@@ -4,10 +4,12 @@ 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)
@@ -21,6 +23,10 @@ const (
2123 AzureClientID = "AZURE_CLIENT_ID"
2224 // AzureClientSecret of service principal account
2325 AzureClientSecret = "AZURE_CLIENT_SECRET"
26+ // AzureClientCertPath is path of the client certificate
27+ AzureClientCertPath = "AZURE_CLIENT_CERT_PATH"
28+ // AzureClientCertPassword is the password of the private key
29+ AzureClientCertPassword = "AZURE_CIENT_CERT_PASSWORD"
2430 // AzureEnviornment to connect
2531 AzureEnviornment = "AZURE_ENVIRONMENT"
2632 // AzureVaultURI of azure key vault
3743 ErrAzureTenantIDNotSet = errors .New ("AZURE_TENANT_ID not set." )
3844 ErrAzureClientIDNotSet = errors .New ("AZURE_CLIENT_ID not set." )
3945 ErrAzureSecretIDNotSet = errors .New ("AZURE_SECRET_ID not set." )
46+ ErrAzureAuthMedhodNotSet = errors .New ("AZURE_SECRET_ID or AZURE_CLIENT_CERT_PATH not set" )
4047 ErrAzureVaultURLNotSet = errors .New ("AZURE_VAULT_URL not set." )
4148 ErrAzureEnvironmentNotset = errors .New ("AZURE_ENVIRONMENT not set." )
4249 ErrAzureConfigMissing = errors .New ("AzureConfig is not provided" )
4552)
4653
4754type azureSecrets struct {
48- kv keyvault. BaseClient
55+ kv azsecrets. Client
4956 baseURL string
5057}
5158
@@ -62,26 +69,34 @@ func New(
6269 return nil , ErrAzureClientIDNotSet
6370 }
6471 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- }
72+ clientCertPath := getAzureKVParams (secretConfig , AzureClientCertPath )
73+ clientCertPassword := getAzureKVParams (secretConfig , AzureClientCertPassword )
74+
7375 vaultURL := getAzureKVParams (secretConfig , AzureVaultURL )
7476 if vaultURL == "" {
7577 return nil , ErrAzureVaultURLNotSet
7678 }
7779
78- client , err := getAzureVaultClient (clientID , secretID , tenantID , envName )
79- if err != nil {
80- return nil , err
80+ clientOpts := getAzureClientOptions (secretConfig )
81+
82+ var client * azsecrets.Client
83+ var err error
84+ if secretID != "" {
85+ client , err = getAzureVaultClient (clientID , secretID , tenantID , vaultURL , clientOpts )
86+ if err != nil {
87+ return nil , err
88+ }
89+ } else if clientCertPath != "" {
90+ client , err = getAzureVaultClientWithCert (clientID , tenantID , vaultURL , clientCertPath , clientCertPassword , clientOpts )
91+ if err != nil {
92+ return nil , err
93+ }
94+ } else {
95+ return nil , ErrAzureAuthMedhodNotSet
8196 }
8297
8398 return & azureSecrets {
84- kv : client ,
99+ kv : * client ,
85100 baseURL : vaultURL ,
86101 }, nil
87102}
@@ -98,8 +113,13 @@ func (az *azureSecrets) GetSecret(
98113 }
99114
100115 t := func () (interface {}, bool , error ) {
101- secretResp , err := az .kv .GetSecret (ctx , az .baseURL , secretID , "" )
116+ // passing empty version to always get the latest version of the secret.
117+ secretResp , err := az .kv .GetSecret (ctx , secretID , "" , nil )
102118 if err != nil {
119+ // don't retry if Secret is not present
120+ if strings .Contains (err .Error (), "SecretNotFound" ) {
121+ return nil , false , secrets .ErrSecretNotFound
122+ }
103123 return nil , true , err
104124 }
105125 return secretResp , false , nil
@@ -109,7 +129,7 @@ func (az *azureSecrets) GetSecret(
109129 return nil , secrets .NoVersion , err
110130 }
111131
112- secretResp , ok := resp .(keyvault. SecretBundle )
132+ secretResp , ok := resp .(azsecrets. GetSecretResponse )
113133 if ! ok || secretResp .Value == nil {
114134 return nil , secrets .NoVersion , ErrInvalidSecretResp
115135 }
@@ -133,7 +153,7 @@ func (az *azureSecrets) PutSecret(
133153 ctx , cancel := context .WithTimeout (context .Background (), defaultTimeout )
134154 defer cancel ()
135155
136- var secretResp keyvault .SecretBundle
156+ var secretResp azsecrets .SecretBundle
137157 if secretName == "" {
138158 return secrets .NoVersion , secrets .ErrEmptySecretId
139159 }
@@ -146,10 +166,10 @@ func (az *azureSecrets) PutSecret(
146166 return secrets .NoVersion , err
147167 }
148168
169+ valueStr := string (value )
149170 t := func () (interface {}, bool , error ) {
150- secretResp , err = az .kv .SetSecret (ctx , az .baseURL , secretName , keyvault.SecretSetParameters {
151- Value : to .StringPtr (string (value )),
152- })
171+ params := azsecrets.SetSecretParameters {Value : & valueStr }
172+ az .kv .SetSecret (ctx , secretName , params , nil )
153173 if err != nil {
154174 return nil , true , err
155175 }
@@ -169,7 +189,7 @@ func (az *azureSecrets) DeleteSecret(
169189 if secretName == "" {
170190 return secrets .ErrEmptySecretId
171191 }
172- _ , err := az .kv .DeleteSecret (ctx , az . baseURL , secretName )
192+ _ , err := az .kv .DeleteSecret (ctx , secretName , nil )
173193
174194 return err
175195}
@@ -213,3 +233,17 @@ func init() {
213233 panic (err .Error ())
214234 }
215235}
236+
237+ func getAzureClientOptions (secretConfig map [string ]interface {}) azcore.ClientOptions {
238+ opts := azcore.ClientOptions {}
239+ cloudEnv := getAzureKVParams (secretConfig , AzureEnviornment )
240+ if strings .EqualFold (cloudEnv , "AzureUSGovernment" ) {
241+ opts .Cloud = cloud .AzureGovernment
242+ } else if strings .EqualFold (cloudEnv , "AzureChinaCloud" ) {
243+ opts .Cloud = cloud .AzureChina
244+ } else {
245+ opts .Cloud = cloud .AzurePublic
246+ }
247+ return opts
248+
249+ }
0 commit comments