Skip to content

Commit

Permalink
feat(azure): Support Azure Workload Identity argoproj-labs#421
Browse files Browse the repository at this point in the history
  • Loading branch information
YvesZelros committed Aug 31, 2023
1 parent 77b07b1 commit 1511ca2
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 1,808 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
argocd-vault-plugin
RELEASE_CHANGELOG.md
bin
.DS_Store
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
BINARY=argocd-vault-plugin
export GOOS=linux
export GOARCH=amd64

default: build

Expand Down
Binary file added argocd-vault-plugin
Binary file not shown.
30 changes: 19 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ require (
cloud.google.com/go/secretmanager v1.9.0
github.com/1Password/connect-sdk-go v1.4.0
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.0.0
github.com/IBM/go-sdk-core/v5 v5.10.2
github.com/IBM/secrets-manager-go-sdk v1.2.0
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
Expand All @@ -27,7 +26,7 @@ require (
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/errors v0.20.2 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/golang-jwt/jwt/v4 v4.4.1 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.0
github.com/hashicorp/go-hclog v1.2.2
Expand All @@ -44,8 +43,8 @@ require (
github.com/yandex-cloud/go-sdk v0.0.0-20220511115426-9feb5f1ee87f
go.mongodb.org/mongo-driver v1.10.0 // indirect
go.mozilla.org/sops/v3 v3.7.2
golang.org/x/net v0.7.0
golang.org/x/sys v0.5.0 // indirect
golang.org/x/net v0.14.0
golang.org/x/sys v0.11.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f
google.golang.org/grpc v1.53.0
k8s.io/apimachinery v0.24.1
Expand Down Expand Up @@ -100,7 +99,6 @@ require (
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect
github.com/digitalocean/godo v1.7.5 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/dnaeon/go-vcr v1.2.0 // indirect
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 // indirect
github.com/emicklei/go-restful v2.16.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
Expand Down Expand Up @@ -232,7 +230,7 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.1 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/subosito/gotenv v1.3.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go v3.0.171+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
Expand All @@ -246,11 +244,11 @@ require (
go.mozilla.org/gopgagent v0.0.0-20170926210634-4d7ea76ff71a // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/term v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
google.golang.org/api v0.103.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand All @@ -272,5 +270,15 @@ require (

require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 // indirect
github.com/Azure/go-autorest/autorest v0.11.24 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
)
1,500 changes: 33 additions & 1,467 deletions go.sum

Large diffs are not rendered by default.

70 changes: 34 additions & 36 deletions pkg/backends/azurekeyvault.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ package backends
import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets"
"github.com/argoproj-labs/argocd-vault-plugin/pkg/utils"
"path"
"strings"
"time"
)

// AzureKeyVault is a struct for working with an Azure Key Vault backend
type AzureKeyVault struct {
Client keyvault.BaseClient
Credential *azidentity.DefaultAzureCredential
}

// NewAzureKeyVaultBackend initializes a new Azure Key Vault backend
func NewAzureKeyVaultBackend(client keyvault.BaseClient) *AzureKeyVault {
func NewAzureKeyVaultBackend(credential *azidentity.DefaultAzureCredential) *AzureKeyVault {
return &AzureKeyVault{
Client: client,
Credential: credential,
}
}

Expand All @@ -35,53 +35,46 @@ func (a *AzureKeyVault) GetSecrets(kvpath string, version string, _ map[string]s
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

data := make(map[string]interface{})
client, err := azsecrets.NewClient(kvpath, a.Credential, nil)

utils.VerboseToStdErr("Azure Key Vault listing secrets in vault %v", kvpath)
secretList, err := a.Client.GetSecretsComplete(ctx, kvpath, nil)
if err != nil {
return nil, err
}

utils.VerboseToStdErr("Azure Key Vault list secrets response %v", secretList)
// Gather all secrets in Key Vault

for ; secretList.NotDone(); secretList.NextWithContext(ctx) {
secret := path.Base(*secretList.Value().ID)
if version == "" {
utils.VerboseToStdErr("Azure Key Vault getting secret %s from vault %s", secret, kvpath)
secretResp, err := a.Client.GetSecret(ctx, kvpath, secret, "")
if err != nil {
return nil, err
}
data := make(map[string]interface{})

utils.VerboseToStdErr("Azure Key Vault get unversioned secret response %v", secretResp)
data[secret] = *secretResp.Value
continue
pager := client.NewListSecretPropertiesPager(nil)
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
return nil, err
}
// In Azure Key Vault the versions of a secret is first shown after running GetSecretVersions. So we need
// to loop through the versions for each secret in order to find the secret that has the specific version.
secretVersions, _ := a.Client.GetSecretVersionsComplete(ctx, kvpath, secret, nil)
for ; secretVersions.NotDone(); secretVersions.NextWithContext(ctx) {
secretVersion := secretVersions.Value()
for _, secretVersion := range page.Value {
// Azure Key Vault has ability to enable/disable a secret, so lets honour that
if !*secretVersion.Attributes.Enabled {
continue
}
// Secret version matched given version
if strings.Contains(*secretVersion.ID, version) {
utils.VerboseToStdErr("Azure Key Vault getting secret %s from vault %s at version %s", secret, kvpath, version)
secretResp, err := a.Client.GetSecret(ctx, kvpath, secret, version)
name := secretVersion.ID.Name()
// Secret version matched given version ?
if version == "" || strings.Contains(secretVersion.ID.Version(), version) {
utils.VerboseToStdErr("Azure Key Vault getting secret %s from vault %s at version %s", name, kvpath, version)
secret, err := client.GetSecret(ctx, secretVersion.ID.Name(), version, nil)
if err != nil {
return nil, err
}

utils.VerboseToStdErr("Azure Key Vault get versioned secret response %v", secretResp)
data[secret] = *secretResp.Value
utils.VerboseToStdErr("Azure Key Vault get unversioned secret response %v", secret)
data[name] = *secret.Value
} else {
utils.VerboseToStdErr("Azure Key Vault getting secret %s from vault %s at version %s", name, kvpath, version)
secret, err := client.GetSecret(ctx, secretVersion.ID.Name(), version, nil)
if err != nil {
continue // Ignore secret that not match the requested version
}
utils.VerboseToStdErr("Azure Key Vault get versioned secret response %v", secret)
data[name] = *secret.Value
}
}
}

return data, nil
}

Expand All @@ -95,7 +88,12 @@ func (a *AzureKeyVault) GetIndividualSecret(kvpath, secret, version string, anno
utils.VerboseToStdErr("Azure Key Vault getting secret %s from vault %s at version %s", secret, kvpath, version)

kvpath = fmt.Sprintf("https://%s.vault.azure.net", kvpath)
data, err := a.Client.GetSecret(ctx, kvpath, secret, version)
client, err := azsecrets.NewClient(kvpath, a.Credential, nil)
if err != nil {
return nil, err
}

data, err := client.GetSecret(ctx, secret, version, nil)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 1511ca2

Please sign in to comment.