Skip to content

Commit b33f0b1

Browse files
committed
migrate from adal to azidentity
adal is is out of support since March 31, 2023. This PR migrates from adal to azidentity for azure key vault Signed-off-by: sp98 <[email protected]>
1 parent 5f4b25c commit b33f0b1

File tree

5 files changed

+179
-60
lines changed

5 files changed

+179
-60
lines changed

azure/azure_kv.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import (
66
"errors"
77
"time"
88

9-
"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
10-
"github.com/Azure/go-autorest/autorest/to"
9+
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
1110
"github.com/libopenstorage/secrets"
1211
"github.com/portworx/sched-ops/task"
1312
)
@@ -21,6 +20,10 @@ const (
2120
AzureClientID = "AZURE_CLIENT_ID"
2221
// AzureClientSecret of service principal account
2322
AzureClientSecret = "AZURE_CLIENT_SECRET"
23+
// AzureClientCertPath is path of the client certificate
24+
AzureClientCertPath = "AZURE_CLIENT_CERT_PATH"
25+
// AzureClientCertPassword is the password of the private key
26+
AzureClientCertPassword = "AZURE_CIENT_CERT_PASSWORD"
2427
// AzureEnviornment to connect
2528
AzureEnviornment = "AZURE_ENVIRONMENT"
2629
// AzureVaultURI of azure key vault
@@ -37,6 +40,7 @@ var (
3740
ErrAzureTenantIDNotSet = errors.New("AZURE_TENANT_ID not set.")
3841
ErrAzureClientIDNotSet = errors.New("AZURE_CLIENT_ID not set.")
3942
ErrAzureSecretIDNotSet = errors.New("AZURE_SECRET_ID not set.")
43+
ErrAzureAuthMedhodNotSet = errors.New("AZURE_SECRET_ID or AZURE_CLIENT_CERT_PATH not set")
4044
ErrAzureVaultURLNotSet = errors.New("AZURE_VAULT_URL not set.")
4145
ErrAzureEnvironmentNotset = errors.New("AZURE_ENVIRONMENT not set.")
4246
ErrAzureConfigMissing = errors.New("AzureConfig is not provided")
@@ -45,7 +49,7 @@ var (
4549
)
4650

4751
type azureSecrets struct {
48-
kv keyvault.BaseClient
52+
kv azsecrets.Client
4953
baseURL string
5054
}
5155

@@ -62,9 +66,9 @@ func New(
6266
return nil, ErrAzureClientIDNotSet
6367
}
6468
secretID := getAzureKVParams(secretConfig, AzureClientSecret)
65-
if secretID == "" {
66-
return nil, ErrAzureSecretIDNotSet
67-
}
69+
clientCertPath := getAzureKVParams(secretConfig, AzureClientCertPath)
70+
clientCertPassword := getAzureKVParams(secretConfig, AzureClientCertPassword)
71+
6872
envName := getAzureKVParams(secretConfig, AzureEnviornment)
6973
if envName == "" {
7074
// we set back to default AzurePublicCloud
@@ -75,13 +79,24 @@ func New(
7579
return nil, ErrAzureVaultURLNotSet
7680
}
7781

78-
client, err := getAzureVaultClient(clientID, secretID, tenantID, envName)
79-
if err != nil {
80-
return nil, err
82+
var client *azsecrets.Client
83+
var err error
84+
if secretID != "" {
85+
client, err = getAzureVaultClient(clientID, secretID, tenantID, vaultURL)
86+
if err != nil {
87+
return nil, err
88+
}
89+
} else if clientCertPath != "" {
90+
client, err = getAzureVaultClientWithCert(clientID, tenantID, vaultURL, clientCertPath, clientCertPassword)
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,7 +113,8 @@ 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 {
103119
return nil, true, err
104120
}
@@ -109,7 +125,7 @@ func (az *azureSecrets) GetSecret(
109125
return nil, secrets.NoVersion, err
110126
}
111127

112-
secretResp, ok := resp.(keyvault.SecretBundle)
128+
secretResp, ok := resp.(azsecrets.SecretBundle)
113129
if !ok || secretResp.Value == nil {
114130
return nil, secrets.NoVersion, ErrInvalidSecretResp
115131
}
@@ -133,7 +149,7 @@ func (az *azureSecrets) PutSecret(
133149
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
134150
defer cancel()
135151

136-
var secretResp keyvault.SecretBundle
152+
var secretResp azsecrets.SecretBundle
137153
if secretName == "" {
138154
return secrets.NoVersion, secrets.ErrEmptySecretId
139155
}
@@ -146,10 +162,10 @@ func (az *azureSecrets) PutSecret(
146162
return secrets.NoVersion, err
147163
}
148164

165+
valueStr := string(value)
149166
t := func() (interface{}, bool, error) {
150-
secretResp, err = az.kv.SetSecret(ctx, az.baseURL, secretName, keyvault.SecretSetParameters{
151-
Value: to.StringPtr(string(value)),
152-
})
167+
params := azsecrets.SetSecretParameters{Value: &valueStr}
168+
az.kv.SetSecret(ctx, secretName, params, nil)
153169
if err != nil {
154170
return nil, true, err
155171
}
@@ -169,7 +185,7 @@ func (az *azureSecrets) DeleteSecret(
169185
if secretName == "" {
170186
return secrets.ErrEmptySecretId
171187
}
172-
_, err := az.kv.DeleteSecret(ctx, az.baseURL, secretName)
188+
_, err := az.kv.DeleteSecret(ctx, secretName, nil)
173189

174190
return err
175191
}

azure/azure_kv_helper.go

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
package azure
22

33
import (
4-
"net/url"
4+
"fmt"
55
"os"
6-
"strings"
76

8-
"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
9-
"github.com/Azure/go-autorest/autorest"
10-
"github.com/Azure/go-autorest/autorest/adal"
11-
"github.com/Azure/go-autorest/autorest/azure"
7+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
8+
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
129
)
1310

1411
func getAzureKVParams(secretConfig map[string]interface{}, name string) string {
@@ -19,29 +16,46 @@ func getAzureKVParams(secretConfig map[string]interface{}, name string) string {
1916
}
2017
}
2118

22-
func getAzureVaultClient(clientID, secretID, tenantID, envName string) (keyvault.BaseClient, error) {
23-
var environment *azure.Environment
24-
alternateEndpoint, _ := url.Parse(
25-
"https://login.windows.net/" + tenantID + "/oauth2/token")
19+
func getAzureVaultClient(clientID, secretID, tenantID, vaultURL string) (*azsecrets.Client, error) {
20+
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secretID, nil)
21+
if err != nil {
22+
return nil, fmt.Errorf("failed to get client secret credentials. %v", err)
23+
}
24+
client, err := azsecrets.NewClient(vaultURL, cred, nil)
25+
if err != nil {
26+
return nil, fmt.Errorf("failed to get client to access azure kv secrets. %v", err)
27+
}
28+
29+
return client, nil
30+
}
31+
32+
func getAzureVaultClientWithCert(clientID, tenantID, vaultURL, certPath, certPassword string) (*azsecrets.Client, error) {
33+
certData, err := os.ReadFile(certPath)
34+
if err != nil {
35+
return nil, fmt.Errorf("failed read certificate from path %q. %v", certPath, err)
36+
}
2637

27-
keyClient := keyvault.New()
28-
env, err := azure.EnvironmentFromName(envName)
38+
var passphrase []byte
39+
if certPassword == "" {
40+
passphrase = nil
41+
} else {
42+
passphrase = []byte(certPassword)
43+
}
44+
45+
certs, key, err := azidentity.ParseCertificates(certData, passphrase)
2946
if err != nil {
30-
return keyClient, err
47+
return nil, fmt.Errorf("failed load certificate and private key. %v", err)
3148
}
32-
environment = &env
33-
oauthconfig, err := adal.NewOAuthConfig(
34-
environment.ActiveDirectoryEndpoint, tenantID)
49+
50+
cred, err := azidentity.NewClientCertificateCredential(tenantID, clientID, certs, key, nil)
3551
if err != nil {
36-
return keyClient, err
52+
return nil, fmt.Errorf("failed to construct client certificate credentials. %v", err)
3753
}
38-
oauthconfig.AuthorizeEndpoint = *alternateEndpoint
3954

40-
token, err := adal.NewServicePrincipalToken(
41-
*oauthconfig, clientID, secretID, strings.TrimSuffix(environment.KeyVaultEndpoint, "/"))
55+
client, err := azsecrets.NewClient(vaultURL, cred, nil)
4256
if err != nil {
43-
return keyClient, err
57+
return nil, fmt.Errorf("failed to get client to access azure kv secrets. %v", err)
4458
}
45-
keyClient.Authorizer = autorest.NewBearerAuthorizer(token)
46-
return keyClient, nil
59+
60+
return client, nil
4761
}

azure/azure_kv_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,24 @@ func TestNew(t *testing.T) {
1111
os.Unsetenv("AZURE_TENANT_ID")
1212
os.Unsetenv("AZURE_CLIENT_ID")
1313
os.Unsetenv("AZURE_CLIENT_SECRET")
14+
os.Unsetenv("AZURE_CLIENT_CERT_PATH")
1415
os.Unsetenv("AZURE_ENVIRONMENT")
1516
os.Unsetenv("AZURE_VAULT_URL")
1617

1718
// nil secret config
1819
_, err := New(nil)
19-
assert.Equal(t, err, ErrAzureTenantIDNotSet)
20+
assert.Equal(t, ErrAzureTenantIDNotSet, err)
2021
os.Setenv("AZURE_TENANT_ID", "invalid_tenant_id")
2122

2223
_, err = New(nil)
23-
assert.Equal(t, err, ErrAzureClientIDNotSet)
24+
assert.Equal(t, ErrAzureClientIDNotSet, err)
2425
os.Setenv("AZURE_CLIENT_ID", "invalid-client-id")
2526

2627
_, err = New(nil)
27-
assert.Equal(t, err, ErrAzureSecretIDNotSet)
28-
os.Setenv("AZURE_CLIENT_SECRET", "invalid-secret-id")
29-
30-
_, err = New(nil)
31-
assert.Equal(t, err, ErrAzureVaultURLNotSet)
28+
assert.Equal(t, ErrAzureVaultURLNotSet, err)
3229
os.Setenv("AZURE_VAULT_URL", "invalid-vault-url")
3330

3431
_, err = New(nil)
35-
assert.NoError(t, err, "Unepxected error on New")
32+
assert.Equal(t, ErrAzureAuthMedhodNotSet, err)
33+
os.Setenv("AZURE_CLIENT_SECRET", "invalid-secret-id")
3634
}

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@ require (
1818
github.com/portworx/kvdb v0.0.0-20200929023115-b312c7519467
1919
github.com/portworx/sched-ops v1.20.4-rc1
2020
github.com/sirupsen/logrus v1.9.0
21-
github.com/stretchr/testify v1.8.0
21+
github.com/stretchr/testify v1.8.4
2222
google.golang.org/api v0.83.0
2323
k8s.io/client-go v12.0.0+incompatible
2424
)
2525

2626
require (
27+
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1
28+
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0
29+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0
2730
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
2831
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
2932
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
3033
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3134
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
3235
github.com/go-openapi/jsonreference v0.20.0 // indirect
3336
github.com/go-test/deep v1.0.8 // indirect
34-
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
35-
github.com/google/uuid v1.3.0 // indirect
3637
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
3738
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
3839
github.com/imdario/mergo v0.3.13 // indirect

0 commit comments

Comments
 (0)