@@ -4,23 +4,31 @@ import (
44 "context"
55 "encoding/json"
66 "errors"
7+ "strings"
78 "time"
89
9- "github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
10- "github.com/Azure/go-autorest/autorest/to"
10+ "github.com/Azure/azure-sdk-for-go/sdk/azcore"
11+ "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
12+ "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
1113 "github.com/libopenstorage/secrets"
1214 "github.com/portworx/sched-ops/task"
1315)
1416
1517const (
16- Name = secrets .TypeAzure
17- AzureCloud = "AzurePublicCloud"
18+ Name = secrets .TypeAzure
19+ AzureCloud = "AzurePublicCloud"
20+ AzureGovernment = "AzureUSGovernment"
21+ AzureChina = "AzureChinaCloud"
1822 // AzureTenantID for Azure Active Directory
1923 AzureTenantID = "AZURE_TENANT_ID"
2024 // AzureClientID of service principal account
2125 AzureClientID = "AZURE_CLIENT_ID"
2226 // AzureClientSecret of service principal account
2327 AzureClientSecret = "AZURE_CLIENT_SECRET"
28+ // AzureClientCertPath is path of the client certificate
29+ AzureClientCertPath = "AZURE_CLIENT_CERT_PATH"
30+ // AzureClientCertPassword is the password of the private key
31+ AzureClientCertPassword = "AZURE_CIENT_CERT_PASSWORD"
2432 // AzureEnviornment to connect
2533 AzureEnviornment = "AZURE_ENVIRONMENT"
2634 // AzureVaultURI of azure key vault
3745 ErrAzureTenantIDNotSet = errors .New ("AZURE_TENANT_ID not set." )
3846 ErrAzureClientIDNotSet = errors .New ("AZURE_CLIENT_ID not set." )
3947 ErrAzureSecretIDNotSet = errors .New ("AZURE_SECRET_ID not set." )
48+ ErrAzureAuthMedhodNotSet = errors .New ("AZURE_SECRET_ID or AZURE_CLIENT_CERT_PATH not set" )
4049 ErrAzureVaultURLNotSet = errors .New ("AZURE_VAULT_URL not set." )
4150 ErrAzureEnvironmentNotset = errors .New ("AZURE_ENVIRONMENT not set." )
4251 ErrAzureConfigMissing = errors .New ("AzureConfig is not provided" )
4554)
4655
4756type azureSecrets struct {
48- kv keyvault. BaseClient
57+ kv azsecrets. Client
4958 baseURL string
5059}
5160
@@ -62,26 +71,34 @@ func New(
6271 return nil , ErrAzureClientIDNotSet
6372 }
6473 secretID := getAzureKVParams (secretConfig , AzureClientSecret )
65- if secretID == "" {
66- return nil , ErrAzureSecretIDNotSet
67- }
68- envName := getAzureKVParams (secretConfig , AzureEnviornment )
69- if envName == "" {
70- // we set back to default AzurePublicCloud
71- envName = AzureCloud
72- }
74+ clientCertPath := getAzureKVParams (secretConfig , AzureClientCertPath )
75+ clientCertPassword := getAzureKVParams (secretConfig , AzureClientCertPassword )
76+
7377 vaultURL := getAzureKVParams (secretConfig , AzureVaultURL )
7478 if vaultURL == "" {
7579 return nil , ErrAzureVaultURLNotSet
7680 }
7781
78- client , err := getAzureVaultClient (clientID , secretID , tenantID , envName )
79- if err != nil {
80- return nil , err
82+ clientOpts := getAzureClientOptions (secretConfig )
83+
84+ var client * azsecrets.Client
85+ var err error
86+ if secretID != "" {
87+ client , err = getAzureVaultClient (clientID , secretID , tenantID , vaultURL , clientOpts )
88+ if err != nil {
89+ return nil , err
90+ }
91+ } else if clientCertPath != "" {
92+ client , err = getAzureVaultClientWithCert (clientID , tenantID , vaultURL , clientCertPath , clientCertPassword , clientOpts )
93+ if err != nil {
94+ return nil , err
95+ }
96+ } else {
97+ return nil , ErrAzureAuthMedhodNotSet
8198 }
8299
83100 return & azureSecrets {
84- kv : client ,
101+ kv : * client ,
85102 baseURL : vaultURL ,
86103 }, nil
87104}
@@ -98,8 +115,13 @@ func (az *azureSecrets) GetSecret(
98115 }
99116
100117 t := func () (interface {}, bool , error ) {
101- secretResp , err := az .kv .GetSecret (ctx , az .baseURL , secretID , "" )
118+ // passing empty version to always get the latest version of the secret.
119+ secretResp , err := az .kv .GetSecret (ctx , secretID , "" , nil )
102120 if err != nil {
121+ // don't retry if Secret is not present
122+ if strings .Contains (err .Error (), "SecretNotFound" ) {
123+ return nil , false , secrets .ErrSecretNotFound
124+ }
103125 return nil , true , err
104126 }
105127 return secretResp , false , nil
@@ -109,7 +131,7 @@ func (az *azureSecrets) GetSecret(
109131 return nil , secrets .NoVersion , err
110132 }
111133
112- secretResp , ok := resp .(keyvault. SecretBundle )
134+ secretResp , ok := resp .(azsecrets. GetSecretResponse )
113135 if ! ok || secretResp .Value == nil {
114136 return nil , secrets .NoVersion , ErrInvalidSecretResp
115137 }
@@ -133,7 +155,7 @@ func (az *azureSecrets) PutSecret(
133155 ctx , cancel := context .WithTimeout (context .Background (), defaultTimeout )
134156 defer cancel ()
135157
136- var secretResp keyvault .SecretBundle
158+ var secretResp azsecrets .SecretBundle
137159 if secretName == "" {
138160 return secrets .NoVersion , secrets .ErrEmptySecretId
139161 }
@@ -146,10 +168,10 @@ func (az *azureSecrets) PutSecret(
146168 return secrets .NoVersion , err
147169 }
148170
171+ valueStr := string (value )
149172 t := func () (interface {}, bool , error ) {
150- secretResp , err = az .kv .SetSecret (ctx , az .baseURL , secretName , keyvault.SecretSetParameters {
151- Value : to .StringPtr (string (value )),
152- })
173+ params := azsecrets.SetSecretParameters {Value : & valueStr }
174+ az .kv .SetSecret (ctx , secretName , params , nil )
153175 if err != nil {
154176 return nil , true , err
155177 }
@@ -169,7 +191,7 @@ func (az *azureSecrets) DeleteSecret(
169191 if secretName == "" {
170192 return secrets .ErrEmptySecretId
171193 }
172- _ , err := az .kv .DeleteSecret (ctx , az . baseURL , secretName )
194+ _ , err := az .kv .DeleteSecret (ctx , secretName , nil )
173195
174196 return err
175197}
@@ -213,3 +235,17 @@ func init() {
213235 panic (err .Error ())
214236 }
215237}
238+
239+ func getAzureClientOptions (secretConfig map [string ]interface {}) azcore.ClientOptions {
240+ opts := azcore.ClientOptions {}
241+ cloudEnv := getAzureKVParams (secretConfig , AzureEnviornment )
242+ if strings .EqualFold (cloudEnv , AzureGovernment ) {
243+ opts .Cloud = cloud .AzureGovernment
244+ } else if strings .EqualFold (cloudEnv , AzureChina ) {
245+ opts .Cloud = cloud .AzureChina
246+ } else if cloudEnv == AzureCloud || cloudEnv == "" {
247+ opts .Cloud = cloud .AzurePublic
248+ }
249+ return opts
250+
251+ }
0 commit comments