@@ -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,14 @@ 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 the secret key was not found
122+ responseError , ok := err .(* azcore.ResponseError )
123+ if ok && responseError .StatusCode == 404 {
124+ return nil , false , secrets .ErrSecretNotFound
125+ }
103126 return nil , true , err
104127 }
105128 return secretResp , false , nil
@@ -109,7 +132,7 @@ func (az *azureSecrets) GetSecret(
109132 return nil , secrets .NoVersion , err
110133 }
111134
112- secretResp , ok := resp .(keyvault. SecretBundle )
135+ secretResp , ok := resp .(azsecrets. GetSecretResponse )
113136 if ! ok || secretResp .Value == nil {
114137 return nil , secrets .NoVersion , ErrInvalidSecretResp
115138 }
@@ -133,7 +156,7 @@ func (az *azureSecrets) PutSecret(
133156 ctx , cancel := context .WithTimeout (context .Background (), defaultTimeout )
134157 defer cancel ()
135158
136- var secretResp keyvault .SecretBundle
159+ var secretResp azsecrets .SecretBundle
137160 if secretName == "" {
138161 return secrets .NoVersion , secrets .ErrEmptySecretId
139162 }
@@ -146,10 +169,10 @@ func (az *azureSecrets) PutSecret(
146169 return secrets .NoVersion , err
147170 }
148171
172+ valueStr := string (value )
149173 t := func () (interface {}, bool , error ) {
150- secretResp , err = az .kv .SetSecret (ctx , az .baseURL , secretName , keyvault.SecretSetParameters {
151- Value : to .StringPtr (string (value )),
152- })
174+ params := azsecrets.SetSecretParameters {Value : & valueStr }
175+ az .kv .SetSecret (ctx , secretName , params , nil )
153176 if err != nil {
154177 return nil , true , err
155178 }
@@ -169,7 +192,7 @@ func (az *azureSecrets) DeleteSecret(
169192 if secretName == "" {
170193 return secrets .ErrEmptySecretId
171194 }
172- _ , err := az .kv .DeleteSecret (ctx , az . baseURL , secretName )
195+ _ , err := az .kv .DeleteSecret (ctx , secretName , nil )
173196
174197 return err
175198}
@@ -213,3 +236,17 @@ func init() {
213236 panic (err .Error ())
214237 }
215238}
239+
240+ func getAzureClientOptions (secretConfig map [string ]interface {}) azcore.ClientOptions {
241+ opts := azcore.ClientOptions {}
242+ cloudEnv := getAzureKVParams (secretConfig , AzureEnviornment )
243+ if strings .EqualFold (cloudEnv , AzureGovernment ) {
244+ opts .Cloud = cloud .AzureGovernment
245+ } else if strings .EqualFold (cloudEnv , AzureChina ) {
246+ opts .Cloud = cloud .AzureChina
247+ } else if cloudEnv == AzureCloud || cloudEnv == "" {
248+ opts .Cloud = cloud .AzurePublic
249+ }
250+ return opts
251+
252+ }
0 commit comments