From 1f8fabe4cc06762e7dbe18f87da4e817cd6ef9d3 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Wed, 20 Mar 2024 16:33:29 +0000 Subject: [PATCH 1/7] fix: rename keyvault inline iwth other az services --- README.md | 2 + go.mod | 143 ++++++------- go.sum | 196 ++++++++++++++++-- pkg/generator/azappconf.go | 74 +++++++ pkg/generator/azappconf_test.go | 14 ++ pkg/generator/azhelpers.go | 36 ++++ pkg/generator/{keyvault.go => azkeyvault.go} | 0 .../{keyvault_test.go => azkeyvault_test.go} | 0 pkg/generator/aztablestorage.go | 35 +--- pkg/generator/generator.go | 8 +- pkg/generator/strategy.go | 2 + 11 files changed, 387 insertions(+), 123 deletions(-) create mode 100644 pkg/generator/azappconf.go create mode 100644 pkg/generator/azappconf_test.go create mode 100644 pkg/generator/azhelpers.go rename pkg/generator/{keyvault.go => azkeyvault.go} (100%) rename pkg/generator/{keyvault_test.go => azkeyvault_test.go} (100%) diff --git a/README.md b/README.md index 086ccc2..1678413 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ Currently supported variable and secrets implementations: - [Azure TableStorage](https://azure.microsoft.com/en-gb/products/storage/tables/) - Implementation Indicator: `AZTABLESTORE` - see [Special consideration for AZTABLESTORE](#special-consideration-for-aztablestore) around how to structure the token in this case. +- [Azure AppConfig](https://azure.microsoft.com/en-gb/products/app-configuration/) + - Implementation Indicator: `AZAPPCONF` - [GCP Secrets](https://cloud.google.com/secret-manager) - Implementation Indicator: `GCPSECRETS` - [Hashicorp Vault](https://developer.hashicorp.com/vault/docs/secrets/kv) diff --git a/go.mod b/go.mod index 3a885a3..8b0e5dd 100644 --- a/go.mod +++ b/go.mod @@ -3,94 +3,95 @@ module github.com/dnitsch/configmanager go 1.21 require ( - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v0.13.0 - github.com/aws/aws-sdk-go-v2 v1.18.0 - github.com/aws/aws-sdk-go-v2/config v1.18.25 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.8 - github.com/aws/aws-sdk-go-v2/service/ssm v1.36.4 - github.com/go-test/deep v1.1.0 - github.com/rs/zerolog v1.29.1 - github.com/spf13/cobra v1.7.0 + cloud.google.com/go/secretmanager v1.12.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 + github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.1.0 + github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0 + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 + github.com/aws/aws-sdk-go-v2 v1.26.0 + github.com/aws/aws-sdk-go-v2/config v1.27.8 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4 + github.com/aws/aws-sdk-go-v2/service/ssm v1.49.4 + github.com/googleapis/gax-go/v2 v2.12.3 + github.com/hashicorp/vault/api v1.12.2 + github.com/hashicorp/vault/api/auth/aws v0.6.0 + github.com/rs/zerolog v1.32.0 + github.com/spyzhov/ajson v0.9.1 + gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go/compute v1.19.3 // indirect + cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // 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/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.44.267 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect - github.com/cenkalti/backoff/v3 v3.2.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/aws/aws-sdk-go v1.49.22 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.8 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 // indirect + github.com/aws/smithy-go v1.20.1 // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-test/deep v1.1.0 + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/s2a-go v0.1.3 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v0.16.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.2 // indirect + github.com/hashicorp/go-retryablehttp v0.6.6 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/awsutil v0.2.1 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect + github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/api v0.123.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect -) - -require ( - cloud.google.com/go/secretmanager v1.10.1 - github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.0.2 - github.com/aws/aws-sdk-go-v2/credentials v1.13.24 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect - github.com/aws/smithy-go v1.13.5 // indirect - github.com/googleapis/gax-go/v2 v2.9.0 - github.com/hashicorp/vault/api v1.9.1 - github.com/hashicorp/vault/api/auth/aws v0.4.0 - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spyzhov/ajson v0.8.0 - golang.org/x/sys v0.10.0 // indirect - gopkg.in/yaml.v3 v3.0.1 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/api v0.169.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/go.sum b/go.sum index 909743b..b98ad46 100644 --- a/go.sum +++ b/go.sum @@ -4,28 +4,50 @@ cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds= cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/iam v1.0.1 h1:lyeCAU6jpnVNrE9zGQkTl3WgNgK/X+uWwaw0kynZJMU= cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/secretmanager v1.10.1 h1:9QwQ3oMurvmPEmM80spGe2SFGDa+RRgkLIdTm3gMWO8= cloud.google.com/go/secretmanager v1.10.1/go.mod h1:pxG0NLpcK6OMy54kfZgQmsKTPxJem708X1es7xv8n60= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +cloud.google.com/go/secretmanager v1.12.0 h1:e5pIo/QEgiFiHPVJPxM5jbtUr4O/u5h2zLHYtkFQr24= +cloud.google.com/go/secretmanager v1.12.0/go.mod h1:Y1Gne3Ag+fZ2TDTiJc8ZJCMFbi7k1rYT4Rw30GXfvlk= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= +github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.1.0 h1:AdaGDU3FgoUC2tsd3vsd9JblRrpFLUsS38yh1eLYfwM= +github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.1.0/go.mod h1:6tpINME7dnF7bLlb8Ubj6FtM9CFZrCn7aT02pcYrklM= github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.0.2 h1:iXFUCl7NK2DPVKfixcYDPGj3uLV7yf5eolBsoWD8Sc4= github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.0.2/go.mod h1:E1WPwLx0wZyus7NBHjhrHE1QgWwKJPE81fnUbT+FxqI= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0 h1:aJG+Jxd9/rrLwf8R1Ko0RlOBTJASs/lGQJ8b9AdlKTc= +github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0/go.mod h1:41ONblJrPxDcnVr+voS+3xXWy/KnZLh+7zY5s6woAlQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v0.13.0 h1:XY0plaTx8oeipK+XogAck2Qzv39KdnJNBwrxC4A0GL4= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v0.13.0/go.mod h1:tj2JhpZY+NjcQcZ207YHkfwYuivmTrcj5ZNpQxpT3Qk= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 h1:h4Zxgmi9oyZL2l8jeg1iRTqPloHktywWcu0nlJmo1tA= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0/go.mod h1:LgLGXawqSreJz135Elog0ywTJDsm0Hz2k+N+6ZK35u8= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -33,35 +55,68 @@ github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve github.com/aws/aws-sdk-go v1.34.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.44.267 h1:Asrp6EMqqRxZvjK0NjzkWcrOk15RnWtupuUrUuZMabk= github.com/aws/aws-sdk-go v1.44.267/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.49.22 h1:r01+cQJ3cORQI1PJxG8af0jzrZpUOL9L+/3kU2x1geU= +github.com/aws/aws-sdk-go v1.49.22/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY= github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA= +github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I= github.com/aws/aws-sdk-go-v2/config v1.18.25 h1:JuYyZcnMPBiFqn87L2cRppo+rNwgah6YwD3VuyvaW6Q= github.com/aws/aws-sdk-go-v2/config v1.18.25/go.mod h1:dZnYpD5wTW/dQF0rRNLVypB396zWCcPiBIvdvSWHEg4= +github.com/aws/aws-sdk-go-v2/config v1.27.8 h1:0r8epOsiJ7YJz65MGcb8i91ehFp4kvvFe2qkq5oYeRI= +github.com/aws/aws-sdk-go-v2/config v1.27.8/go.mod h1:XsmYKxYNuIhLsFddpNds+j9H5XKzjWDdg/SZngiwFio= github.com/aws/aws-sdk-go-v2/credentials v1.13.24 h1:PjiYyls3QdCrzqUN35jMWtUK1vqVZ+zLfdOa/UPFDp0= github.com/aws/aws-sdk-go-v2/credentials v1.13.24/go.mod h1:jYPYi99wUOPIFi0rhiOvXeSEReVOzBqFNOX5bXYoG2o= +github.com/aws/aws-sdk-go-v2/credentials v1.17.8 h1:WUdNLXbyNbU07V/WFrSOBXqZTDgmmMNMgUFzpYOKJhw= +github.com/aws/aws-sdk-go-v2/credentials v1.17.8/go.mod h1:iPZzLpaBIfhyvVS/XGD3JvR1GP3YdHTqpySKDlqkfs8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 h1:jJPgroehGvjrde3XufFIJUZVK5A2L9a3KwSFgKy9n8w= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3/go.mod h1:4Q0UFP0YJf0NrsEuEYHpM9fTSEVnD16Z3uyEF7J9JGM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4 h1:S+L2QSKhUuShih3aq9P/mkzDBiOO5tTyVg+vXREfsfg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 h1:kG5eQilShqmJbv11XL1VpyDbaEJzWxd4zRiCG30GSn4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 h1:vFQlirhuM8lLlpI7imKOMsjdQLuN9CPi+k44F/OFVsk= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 h1:gGLG7yKaXG02/jBlg210R7VgQIotiQntNhsCFejawx8= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 h1:0iKliEXAcCa2qVtRs7Ot5hItA2MsufrphbRFlz1Owxo= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHMmcB4Dckjpkapoy47W6C9QBv/zoUP+Hn8Kc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.8 h1:eB91eEYUlh8+O2dXr189W8GJJd+/T8N/c5HocH2KzVo= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.8/go.mod h1:3ARttS6G6U3auEdKfaN4GlnfS9UxYE9nqub1+0YGycA= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4 h1:5GYToReUFSGP6/zqvG3fv8qNqeetyfsSiPHduHShjAc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4/go.mod h1:slgOMs1CQu8UVgwoFqEvCi71L4HVoZgM0r8MtcNP6Mc= github.com/aws/aws-sdk-go-v2/service/ssm v1.36.4 h1:3AjvCuRS8OnNVRC/UBagp1Jo2feR94+VAIKO4lz8gOQ= github.com/aws/aws-sdk-go-v2/service/ssm v1.36.4/go.mod h1:p6MaesK9061w6NTiFmZpUzEkKUY5blKlwD2zYyErxKA= +github.com/aws/aws-sdk-go-v2/service/ssm v1.49.4 h1:2f1Gkbe9O15DntphmbdEInn6MGIZ3x2bbv8b0p/4awQ= +github.com/aws/aws-sdk-go-v2/service/ssm v1.49.4/go.mod h1:BlIdE/k0lwn8xyn8piK02oYjqKsxulo6yPV3BuIWuMI= github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 h1:UBQjaMTCKwyUYwiVnUt6toEJwGXsLBI6al083tpjJzY= github.com/aws/aws-sdk-go-v2/service/sso v1.12.10/go.mod h1:ouy2P4z6sJN70fR3ka3wD3Ro3KezSxU6eKGQI2+2fjI= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3/go.mod h1:5HFu51Elk+4oRBZVxmHrSds5jFXmFj8C3w7DVF2gnrs= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 h1:PkHIIJs8qvq0e5QybnZoG1K/9QTrLr9OsqCIo59jOBA= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10/go.mod h1:AFvkxc8xfBe8XA+5St5XIHHrQQtkxqrRincx4hmMHOk= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 h1:uLq0BKatTmDzWa/Nu4WO0M1AaQDaPpwTKAeByEc6WFM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3/go.mod h1:b+qdhjnxj8GSR6t5YfphOffeoQSQ1KmpoVVuBn+PWxs= github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 h1:2DQLAKDteoEDI8zpCzqBMaZlJuoE9iTYD0gFmXVax9E= github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 h1:J/PpTf/hllOjx8Xu9DMflff3FajfLxqM5+tepvVXmxg= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5/go.mod h1:0ih0Z83YDH/QeQ6Ori2yGE2XvWYv/Xm+cZc01LC6oK0= github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= +github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= @@ -92,14 +147,28 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -134,13 +203,21 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.9.0 h1:ie5/2yPjucjZW6fEGjLhS5+PhEg6owWMrFB5d7TFFhw= github.com/googleapis/gax-go/v2 v2.9.0/go.mod h1:qf/E3rjAvrwLsAnQW+IClIu+z03yUf4KOoO82NfZ+QY= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -149,20 +226,24 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= github.com/hashicorp/go-secure-stdlib/awsutil v0.2.1 h1:i4J4rojlVbS4wD+/FNcj6Auost9grl6F0Ft5alB8N9Y= github.com/hashicorp/go-secure-stdlib/awsutil v0.2.1/go.mod h1:oKHSQs4ivIfZ3fbXGQOop1XuDfdSb8RIsWTGaAanSfg= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= @@ -171,6 +252,7 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -179,8 +261,13 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hashicorp/vault/api v1.9.0/go.mod h1:lloELQP4EyhjnCQhF8agKvWIVTmxbpEJj70b98959sM= github.com/hashicorp/vault/api v1.9.1 h1:LtY/I16+5jVGU8rufyyAkwopgq/HpUnxFBg+QLOAV38= github.com/hashicorp/vault/api v1.9.1/go.mod h1:78kktNcQYbBGSrOjQfHjXN32OhhxXnbYl3zxpd2uPUs= +github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck= +github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE= +github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE= github.com/hashicorp/vault/api/auth/aws v0.4.0 h1:2Myo+XU3X5gQTtr3S+WGXcrLUa6iO4w97VzFFaaBOm8= github.com/hashicorp/vault/api/auth/aws v0.4.0/go.mod h1:CGm5PAXEREuYpszyA2ERQPFBSIUD+QTqXfKvdI2Gw/Q= +github.com/hashicorp/vault/api/auth/aws v0.6.0 h1:L4mBSAW44EjgX4OJ3w6aDXQeehuGE9OMY9ldNbKgGXM= +github.com/hashicorp/vault/api/auth/aws v0.6.0/go.mod h1:m4ye0+jgUsLtE+UBszQFgz+0fRiE4qF7MDWgI+mDxbg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= @@ -213,6 +300,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -222,6 +311,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -233,8 +324,11 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -245,11 +339,14 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spyzhov/ajson v0.8.0 h1:sFXyMbi4Y/BKjrsfkUZHSjA2JM1184enheSjjoT/zCc= github.com/spyzhov/ajson v0.8.0/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= +github.com/spyzhov/ajson v0.9.1 h1:izsDkOC9yznlpA2BxJcrkr8Q5Gyjf43yeSc2Wz0g/aU= +github.com/spyzhov/ajson v0.9.1/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -261,19 +358,36 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -290,19 +404,29 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -326,13 +450,25 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -341,11 +477,16 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -353,21 +494,32 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.123.0 h1:yHVU//vA+qkOhm4reEC9LtzHVUCN/IqqNRl1iQ9xE20= google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 h1:9IZDv+/GcI6u+a4jRFRLxQs0RUCfavGfoOgEW6jpkI0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -378,6 +530,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -391,6 +545,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/pkg/generator/azappconf.go b/pkg/generator/azappconf.go new file mode 100644 index 0000000..a073c4c --- /dev/null +++ b/pkg/generator/azappconf.go @@ -0,0 +1,74 @@ +/** + * Azure App Config implementation +**/ +package generator + +import ( + "context" + "fmt" + + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" + "github.com/dnitsch/configmanager/pkg/log" +) + +// appConfApi +// uses this package https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig +type appConfApi interface { + GetSetting(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) +} + +type AzAppConf struct { + svc appConfApi + ctx context.Context + token string + config TokenConfigVars +} + +// NewAzTableStore +func NewAzAppConf(ctx context.Context, token string, conf GenVarsConfig) (*AzAppConf, error) { + + ct := conf.ParseTokenVars(token) + + backingStore := &AzAppConf{ + ctx: ctx, + config: ct, + } + + srvInit := azServiceFromToken(stripPrefix(ct.Token, AzAppConfigPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.azconfig.io", 1) + backingStore.token = srvInit.token + + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + log.Error(err) + return nil, err + } + + c, err := azappconfig.NewClient(srvInit.serviceUri, cred, nil) + if err != nil { + log.Error(err) + return nil, fmt.Errorf("%v\n%w", err, ErrClientInitialization) + } + + backingStore.svc = c + return backingStore, nil + +} + +// setTokenVal sets the token +func (implmt *AzAppConf) setTokenVal(token string) {} + +// tokenVal in AZ table storage if an Entity contains the `value` property +// we attempt to extract it and return. +// +// From this point then normal rules of configmanager apply, +// including keySeperator and lookup. +func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { + log.Info("Concrete implementation AzAppConf") + log.Infof("AzAppConf Token: %s", imp.token) + + _, cancel := context.WithCancel(imp.ctx) + defer cancel() + + return "", nil +} diff --git a/pkg/generator/azappconf_test.go b/pkg/generator/azappconf_test.go new file mode 100644 index 0000000..adb663e --- /dev/null +++ b/pkg/generator/azappconf_test.go @@ -0,0 +1,14 @@ +package generator + +import ( + "context" + "testing" +) + +func Test_AzAppConf_succeeds(t *testing.T) { + c, _ := NewAzAppConf(context.TODO(), "AZAPPCONF://configmanager-app-config/queue_name", *(NewConfig().WithTokenSeparator("://"))) + if c == nil { + t.Errorf("got %v, wanted: %v", c, AzAppConf{}) + } + // got, err := c.tokenVal() +} diff --git a/pkg/generator/azhelpers.go b/pkg/generator/azhelpers.go new file mode 100644 index 0000000..f7c92b1 --- /dev/null +++ b/pkg/generator/azhelpers.go @@ -0,0 +1,36 @@ +package generator + +import ( + "fmt" + "strings" +) + +/* +Generic Azure Service Init Helpers +*/ +// azServiceHelper returns a service URI and the stripped token +type azServiceHelper struct { + serviceUri string + token string +} + +// azServiceFromToken for azure the first part of the token __must__ always be the +// identifier of the service e.g. the account name for tableStore or the Vault name for KVSecret or +// AppConfig instance +// take parameter specifies the number of elements to take from the start only +// +// e.g. a value of 2 for take will take first 2 elements from the slices +// +// For AppConfig or KeyVault we ONLY need the AppConfig instance or KeyVault instance name +func azServiceFromToken(token string, formatUri string, take int) azServiceHelper { + // ensure preceding slash is trimmed + stringToken := strings.Split(strings.TrimPrefix(token, "/"), "/") + splitToken := []any{} + // recast []string slice to an []any + for _, st := range stringToken { + splitToken = append(splitToken, st) + } + + uri := fmt.Sprintf(formatUri, splitToken[0:take]...) + return azServiceHelper{serviceUri: uri, token: strings.Join(stringToken[take:], "/")} +} diff --git a/pkg/generator/keyvault.go b/pkg/generator/azkeyvault.go similarity index 100% rename from pkg/generator/keyvault.go rename to pkg/generator/azkeyvault.go diff --git a/pkg/generator/keyvault_test.go b/pkg/generator/azkeyvault_test.go similarity index 100% rename from pkg/generator/keyvault_test.go rename to pkg/generator/azkeyvault_test.go diff --git a/pkg/generator/aztablestorage.go b/pkg/generator/aztablestorage.go index 5dfdae9..14256fc 100644 --- a/pkg/generator/aztablestorage.go +++ b/pkg/generator/aztablestorage.go @@ -35,13 +35,13 @@ func NewAzTableStore(ctx context.Context, token string, conf GenVarsConfig) (*Az ct := conf.ParseTokenVars(token) - tstore := &AzTableStore{ + backingStore := &AzTableStore{ ctx: ctx, config: ct, } srvInit := azServiceFromToken(stripPrefix(ct.Token, AzTableStorePrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.table.core.windows.net/%s", 2) - tstore.token = srvInit.token + backingStore.token = srvInit.token cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { @@ -55,8 +55,8 @@ func NewAzTableStore(ctx context.Context, token string, conf GenVarsConfig) (*Az return nil, fmt.Errorf("%v\n%w", err, ErrClientInitialization) } - tstore.svc = c - return tstore, nil + backingStore.svc = c + return backingStore, nil } @@ -110,30 +110,3 @@ func azTableStoreTokenSplitter(token string) (partitionKey, rowKey string, err e return } -/* -// Generic Azure Service Init Helpers -*/ - -// azServiceHelper returns a service URI and the stripped token -type azServiceHelper struct { - serviceUri string - token string -} - -// azServiceFromToken for azure the first part of the token __must__ always be the -// identifier of the service e.g. the account name for tableStore or the KV name for KVSecret -// take parameter specifies the number of elements to take from the start only -// -// e.g. a value of 2 for take will take first 2 elements from the slices -func azServiceFromToken(token string, formatUri string, take int) azServiceHelper { - // ensure preceding slash is trimmed - stringToken := strings.Split(strings.TrimPrefix(token, "/"), "/") - splitToken := []any{} - // recast []string slice to an []any - for _, st := range stringToken { - splitToken = append(splitToken, st) - } - - uri := fmt.Sprintf(formatUri, splitToken[0:take]...) - return azServiceHelper{serviceUri: uri, token: strings.Join(stringToken[take:], "/")} -} diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 558040e..13f7d01 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -24,6 +24,8 @@ const ( AzKeyVaultSecretsPrefix ImplementationPrefix = "AZKVSECRET" // Azure Key Vault Secrets prefix AzTableStorePrefix ImplementationPrefix = "AZTABLESTORE" + // Azure App Config prefix + AzAppConfigPrefix ImplementationPrefix = "AZAPPCONF" // Hashicorp Vault prefix HashicorpVaultPrefix ImplementationPrefix = "VAULT" // GcpSecrets @@ -42,7 +44,11 @@ var ( // default varPrefix used by the replacer function // any token must beging with one of these else // it will be skipped as not a replaceable token - VarPrefix = map[ImplementationPrefix]bool{SecretMgrPrefix: true, ParamStorePrefix: true, AzKeyVaultSecretsPrefix: true, GcpSecretsPrefix: true, HashicorpVaultPrefix: true, AzTableStorePrefix: true} + VarPrefix = map[ImplementationPrefix]bool{ + SecretMgrPrefix: true, ParamStorePrefix: true, AzKeyVaultSecretsPrefix: true, + GcpSecretsPrefix: true, HashicorpVaultPrefix: true, AzTableStorePrefix: true, + AzAppConfigPrefix: true, + } ) // Generatoriface describes the exported methods diff --git a/pkg/generator/strategy.go b/pkg/generator/strategy.go index 67dba45..24f4fee 100644 --- a/pkg/generator/strategy.go +++ b/pkg/generator/strategy.go @@ -73,6 +73,8 @@ func (rs *retrieveStrategy) SelectImplementation(ctx context.Context, prefix Imp return NewVaultStore(ctx, in, config) case AzTableStorePrefix: return NewAzTableStore(ctx, in, config) + case AzAppConfigPrefix: + return NewAzAppConf(ctx, in, config) default: return nil, fmt.Errorf("implementation not found for input string: %s", in) } From ff7472096f77e596cd2d452bff8454f030d3eb66 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Wed, 20 Mar 2024 17:16:03 +0000 Subject: [PATCH 2/7] fix: add errors to central place in package --- pkg/generator/defaultstrategy.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/generator/defaultstrategy.go b/pkg/generator/defaultstrategy.go index 0931940..fc471e0 100644 --- a/pkg/generator/defaultstrategy.go +++ b/pkg/generator/defaultstrategy.go @@ -1,12 +1,20 @@ package generator -import "fmt" +import ( + "errors" + "fmt" +) type DefaultStrategy struct { } const implementationNetworkErr string = "implementation %s error: %v for token: %s" +var ( + ErrEmptyResponse = errors.New("value retrieved but empty for token") + ErrServiceCallFailed = errors.New("failed to complete the service call") +) + func NewDefatultStrategy() *DefaultStrategy { return &DefaultStrategy{} } From de3ad1a1c7d79ef57baf406f37c562c098f74363 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Wed, 20 Mar 2024 17:17:34 +0000 Subject: [PATCH 3/7] fix: clean up --- go.mod | 6 ++++++ go.sum | 3 +++ pkg/generator/azappconf.go | 11 ++++++++++- pkg/generator/azkeyvault.go | 12 ++++++------ pkg/generator/generator.go | 2 ++ pkg/generator/strategy_test.go | 9 ++++++--- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 8b0e5dd..3feea91 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,11 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) + require ( cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect @@ -74,6 +79,7 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/spf13/cobra v1.8.0 go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect diff --git a/go.sum b/go.sum index b98ad46..c524ce5 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,7 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -335,6 +336,8 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spyzhov/ajson v0.8.0 h1:sFXyMbi4Y/BKjrsfkUZHSjA2JM1184enheSjjoT/zCc= diff --git a/pkg/generator/azappconf.go b/pkg/generator/azappconf.go index a073c4c..2168ddd 100644 --- a/pkg/generator/azappconf.go +++ b/pkg/generator/azappconf.go @@ -67,8 +67,17 @@ func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { log.Info("Concrete implementation AzAppConf") log.Infof("AzAppConf Token: %s", imp.token) - _, cancel := context.WithCancel(imp.ctx) + ctx, cancel := context.WithCancel(imp.ctx) defer cancel() + s, err := imp.svc.GetSetting(ctx, imp.token, &azappconfig.GetSettingOptions{}) + if err != nil { + log.Errorf(implementationNetworkErr, AzAppConfigPrefix, err, imp.token) + return "", fmt.Errorf("token: %s, error: %v. %w", imp.token, err, ErrServiceCallFailed) + } + if s.Value != nil { + return *s.Value, nil + } + log.Errorf("token: %v, %w", imp.token, ErrEmptyResponse) return "", nil } diff --git a/pkg/generator/azkeyvault.go b/pkg/generator/azkeyvault.go index d436b5c..baa3e1c 100644 --- a/pkg/generator/azkeyvault.go +++ b/pkg/generator/azkeyvault.go @@ -28,13 +28,13 @@ func NewKvScrtStore(ctx context.Context, token string, conf GenVarsConfig) (*KvS ct := conf.ParseTokenVars(token) - kv := &KvScrtStore{ + backingStore := &KvScrtStore{ ctx: ctx, config: ct, } - vc := azServiceFromToken(stripPrefix(ct.Token, AzKeyVaultSecretsPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.vault.azure.net", 1) - kv.token = vc.token + srvInit := azServiceFromToken(stripPrefix(ct.Token, AzKeyVaultSecretsPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.vault.azure.net", 1) + backingStore.token = srvInit.token cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { @@ -42,14 +42,14 @@ func NewKvScrtStore(ctx context.Context, token string, conf GenVarsConfig) (*KvS return nil, err } - c, err := azsecrets.NewClient(vc.serviceUri, cred, nil) + c, err := azsecrets.NewClient(srvInit.serviceUri, cred, nil) if err != nil { log.Error(err) return nil, err } - kv.svc = c - return kv, nil + backingStore.svc = c + return backingStore, nil } diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 13f7d01..3201ad8 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -198,6 +198,8 @@ func (c *GenVars) generate(rawMap map[string]string, rs retrieveIface) error { outCh := make(chan chanResp, initChanLen) wg.Add(initChanLen) + // TODO: initialise the singleton serviceContainer + // pass into each goroutine for token, prefix := range rawMap { // take value from config allocation on a per iteration basis conf := c.Config() diff --git a/pkg/generator/strategy_test.go b/pkg/generator/strategy_test.go index 8c7d278..005d156 100644 --- a/pkg/generator/strategy_test.go +++ b/pkg/generator/strategy_test.go @@ -92,7 +92,8 @@ func TestSelectImpl(t *testing.T) { }{ "success AWSSEcretsMgr": { func() func() { - os.Setenv("AWS_PROFILE", "foo") + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") return func() { os.Clearenv() } @@ -109,7 +110,8 @@ func TestSelectImpl(t *testing.T) { }, "success AWSParamStore": { func() func() { - os.Setenv("AWS_PROFILE", "foo") + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") return func() { os.Clearenv() } @@ -181,7 +183,8 @@ func TestSelectImpl(t *testing.T) { }, "default Error": { func() func() { - os.Setenv("AWS_PROFILE", "foo") + os.Setenv("AWS_ACCESS_KEY", "AAAAAAAAAAAAAAA") + os.Setenv("AWS_SECRET_ACCESS_KEY", "00000000000000000000111111111") return func() { os.Clearenv() } From ab1fd0cf75ed1537fd0505870ab96d8330e2910f Mon Sep 17 00:00:00 2001 From: dnitsch Date: Wed, 20 Mar 2024 19:08:34 +0000 Subject: [PATCH 4/7] fix: genvars config --- pkg/generator/azappconf.go | 7 +++---- pkg/generator/config.go | 8 ++++++-- pkg/generator/gcpsecrets.go | 2 +- pkg/generator/paramstore.go | 2 +- pkg/generator/secretsmanager.go | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pkg/generator/azappconf.go b/pkg/generator/azappconf.go index 2168ddd..173abd6 100644 --- a/pkg/generator/azappconf.go +++ b/pkg/generator/azappconf.go @@ -58,9 +58,8 @@ func NewAzAppConf(ctx context.Context, token string, conf GenVarsConfig) (*AzApp // setTokenVal sets the token func (implmt *AzAppConf) setTokenVal(token string) {} -// tokenVal in AZ table storage if an Entity contains the `value` property -// we attempt to extract it and return. -// +// tokenVal in AZ App Config +// label can be specified // From this point then normal rules of configmanager apply, // including keySeperator and lookup. func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { @@ -70,7 +69,7 @@ func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { ctx, cancel := context.WithCancel(imp.ctx) defer cancel() - s, err := imp.svc.GetSetting(ctx, imp.token, &azappconfig.GetSettingOptions{}) + s, err := imp.svc.GetSetting(ctx, imp.token, &azappconfig.GetSettingOptions{Label: &imp.config.Version}) if err != nil { log.Errorf(implementationNetworkErr, AzAppConfigPrefix, err, imp.token) return "", fmt.Errorf("token: %s, error: %v. %w", imp.token, err, ErrServiceCallFailed) diff --git a/pkg/generator/config.go b/pkg/generator/config.go index 5ac30e4..858cce7 100644 --- a/pkg/generator/config.go +++ b/pkg/generator/config.go @@ -12,7 +12,7 @@ type TokenConfigVars struct { Role string // where supported a version of the secret can be specified // - // e.g. HashiVault or AWS SecretsManager + // e.g. HashiVault or AWS SecretsManager or AzAppConfig Label // Version string } @@ -68,7 +68,10 @@ func (c *GenVarsConfig) KeySeparator() string { return c.keySeparator } -func (c GenVarsConfig) ParseTokenVars(token string) TokenConfigVars { +// ParseTokenVars extracts info from the token "metadata" +// +// All data inside the `[` `]` is considered metadata about the token +func (c *GenVarsConfig) ParseTokenVars(token string) TokenConfigVars { tc := TokenConfigVars{} // strip anything in [] vars := regexp.MustCompile(`\[.*\]`) @@ -79,6 +82,7 @@ func (c GenVarsConfig) ParseTokenVars(token string) TokenConfigVars { if len(role) > 0 { tc.Role = role[1] } + // TODO: create aliases for version (e.g. label) version := regexp.MustCompile(`version:(.*?)(?:,|])`).FindStringSubmatch(rawVars) if len(version) > 0 { tc.Version = version[1] diff --git a/pkg/generator/gcpsecrets.go b/pkg/generator/gcpsecrets.go index 1c6f90a..1557ea1 100644 --- a/pkg/generator/gcpsecrets.go +++ b/pkg/generator/gcpsecrets.go @@ -38,7 +38,7 @@ func NewGcpSecrets(ctx context.Context) (*GcpSecrets, error) { } func (imp *GcpSecrets) setTokenVal(token string) { - ct := (GenVarsConfig{}).ParseTokenVars(token) + ct := (&GenVarsConfig{}).ParseTokenVars(token) imp.config = ct imp.token = ct.Token } diff --git a/pkg/generator/paramstore.go b/pkg/generator/paramstore.go index c6bc7db..441ee77 100644 --- a/pkg/generator/paramstore.go +++ b/pkg/generator/paramstore.go @@ -35,7 +35,7 @@ func NewParamStore(ctx context.Context) (*ParamStore, error) { } func (imp *ParamStore) setTokenVal(token string) { - ct := (GenVarsConfig{}).ParseTokenVars(token) + ct := (&GenVarsConfig{}).ParseTokenVars(token) imp.config = ct imp.token = ct.Token } diff --git a/pkg/generator/secretsmanager.go b/pkg/generator/secretsmanager.go index e696a0e..ec9a305 100644 --- a/pkg/generator/secretsmanager.go +++ b/pkg/generator/secretsmanager.go @@ -36,7 +36,7 @@ func NewSecretsMgr(ctx context.Context) (*SecretsMgr, error) { } func (imp *SecretsMgr) setTokenVal(token string) { - ct := (GenVarsConfig{}).ParseTokenVars(token) + ct := (&GenVarsConfig{}).ParseTokenVars(token) imp.config = ct imp.token = ct.Token } From 22469754d304f5152dc0744abc15fbbad79339bb Mon Sep 17 00:00:00 2001 From: dnitsch Date: Thu, 21 Mar 2024 10:50:58 +0000 Subject: [PATCH 5/7] fix: ParseMetadata use common generic --- configmanager.go | 3 +- go.mod | 32 ++--- go.sum | 30 +++++ pkg/generator/azappconf.go | 31 +++-- pkg/generator/azkeyvault.go | 15 ++- pkg/generator/aztablestorage.go | 15 ++- pkg/generator/config.go | 77 +++++++---- pkg/generator/config_test.go | 211 +++++++++++++++++++------------ pkg/generator/gcpsecrets.go | 14 +- pkg/generator/hashivault.go | 42 +++--- pkg/generator/hashivault_test.go | 14 +- pkg/generator/paramstore.go | 14 +- pkg/generator/secretsmanager.go | 14 +- 13 files changed, 332 insertions(+), 180 deletions(-) diff --git a/configmanager.go b/configmanager.go index a47e247..85e0f14 100644 --- a/configmanager.go +++ b/configmanager.go @@ -7,9 +7,8 @@ import ( "sort" "strings" - yaml "gopkg.in/yaml.v3" - "github.com/dnitsch/configmanager/pkg/generator" + yaml "gopkg.in/yaml.v3" ) const ( diff --git a/go.mod b/go.mod index 3feea91..a7a311c 100644 --- a/go.mod +++ b/go.mod @@ -26,14 +26,14 @@ require ( ) require ( - cloud.google.com/go/compute v1.24.0 // indirect + cloud.google.com/go/compute v1.25.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/iam v1.1.7 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect - github.com/aws/aws-sdk-go v1.49.22 // indirect + github.com/aws/aws-sdk-go v1.51.4 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.8 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect @@ -45,7 +45,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 // indirect github.com/aws/smithy-go v1.20.1 // indirect - github.com/cenkalti/backoff/v3 v3.0.0 // indirect + github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect @@ -54,21 +54,21 @@ require ( github.com/go-test/deep v1.1.0 github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v0.16.2 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.6.6 // indirect + github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -88,16 +88,16 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.22.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/api v0.169.0 // indirect + google.golang.org/api v0.170.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/grpc v1.62.1 // indirect google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/go.sum b/go.sum index c524ce5..cf3d901 100644 --- a/go.sum +++ b/go.sum @@ -2,16 +2,22 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds= cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/iam v1.0.1 h1:lyeCAU6jpnVNrE9zGQkTl3WgNgK/X+uWwaw0kynZJMU= cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= +cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/secretmanager v1.10.1 h1:9QwQ3oMurvmPEmM80spGe2SFGDa+RRgkLIdTm3gMWO8= @@ -57,6 +63,8 @@ github.com/aws/aws-sdk-go v1.44.267 h1:Asrp6EMqqRxZvjK0NjzkWcrOk15RnWtupuUrUuZMa github.com/aws/aws-sdk-go v1.44.267/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.49.22 h1:r01+cQJ3cORQI1PJxG8af0jzrZpUOL9L+/3kU2x1geU= github.com/aws/aws-sdk-go v1.49.22/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.51.4 h1:yOVfGhRJyReBrACK0alLosJl8iXhWkNY1vrePYmhHdw= +github.com/aws/aws-sdk-go v1.51.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY= github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA= @@ -191,6 +199,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -231,6 +241,8 @@ github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3 github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= @@ -238,21 +250,29 @@ github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= +github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= github.com/hashicorp/go-secure-stdlib/awsutil v0.2.1 h1:i4J4rojlVbS4wD+/FNcj6Auost9grl6F0Ft5alB8N9Y= github.com/hashicorp/go-secure-stdlib/awsutil v0.2.1/go.mod h1:oKHSQs4ivIfZ3fbXGQOop1XuDfdSb8RIsWTGaAanSfg= +github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 h1:I8bynUKMh9I7JdwtW9voJ0xmHvBpxQtLjrMFDYmhOxY= +github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0/go.mod h1:oKHSQs4ivIfZ3fbXGQOop1XuDfdSb8RIsWTGaAanSfg= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8/go.mod h1:aiJI+PIApBRQG7FZTEBx5GiiX+HbOHilUdNxUZi4eV0= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= @@ -420,6 +440,8 @@ golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -505,6 +527,8 @@ google.golang.org/api v0.123.0 h1:yHVU//vA+qkOhm4reEC9LtzHVUCN/IqqNRl1iQ9xE20= google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.170.0 h1:zMaruDePM88zxZBG+NG8+reALO2rfLhe/JShitLyT48= +google.golang.org/api v0.170.0/go.mod h1:/xql9M2btF85xac/VAm4PsLMTLVGUOpq4BE9R8jyNy8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -519,10 +543,16 @@ google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 h1:PgNlNSx2Nq2/j4juYzQBG0/Zdr+WP4z5N01Vk4VYBCY= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237/go.mod h1:9sVD8c25Af3p0rGs7S7LLsxWKFiJt/65LdSyqXBkX/Y= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 h1:9IZDv+/GcI6u+a4jRFRLxQs0RUCfavGfoOgEW6jpkI0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/pkg/generator/azappconf.go b/pkg/generator/azappconf.go index 173abd6..4780ac9 100644 --- a/pkg/generator/azappconf.go +++ b/pkg/generator/azappconf.go @@ -6,7 +6,9 @@ package generator import ( "context" "fmt" + "time" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" "github.com/dnitsch/configmanager/pkg/log" @@ -22,20 +24,27 @@ type AzAppConf struct { svc appConfApi ctx context.Context token string - config TokenConfigVars + config *AzAppConfConfig } -// NewAzTableStore -func NewAzAppConf(ctx context.Context, token string, conf GenVarsConfig) (*AzAppConf, error) { - - ct := conf.ParseTokenVars(token) +// AzAppConfConfig is the azure conf service specific config +// and it is parsed from the token metadata +type AzAppConfConfig struct { + Label string `json:"label"` + OnlyIfChanged *azcore.ETag `json:"onlyIfChanged"` + AcceptDateTime *time.Time `json:"acceptedDateTime"` +} +// NewAzAppConf +func NewAzAppConf(ctx context.Context, token string, conf GenVarsConfig) (*AzAppConf, error) { + storeConf := &AzAppConfConfig{} + initialToken := ParseMetadata(token, storeConf) backingStore := &AzAppConf{ ctx: ctx, - config: ct, + config: storeConf, } - srvInit := azServiceFromToken(stripPrefix(ct.Token, AzAppConfigPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.azconfig.io", 1) + srvInit := azServiceFromToken(stripPrefix(initialToken, AzAppConfigPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.azconfig.io", 1) backingStore.token = srvInit.token cred, err := azidentity.NewDefaultAzureCredential(nil) @@ -68,8 +77,14 @@ func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { ctx, cancel := context.WithCancel(imp.ctx) defer cancel() + opts := &azappconfig.GetSettingOptions{} + + // assign any metadatas from the token + if imp.config.Label != "" { + opts.Label = &imp.config.Label + } - s, err := imp.svc.GetSetting(ctx, imp.token, &azappconfig.GetSettingOptions{Label: &imp.config.Version}) + s, err := imp.svc.GetSetting(ctx, imp.token, opts) if err != nil { log.Errorf(implementationNetworkErr, AzAppConfigPrefix, err, imp.token) return "", fmt.Errorf("token: %s, error: %v. %w", imp.token, err, ErrServiceCallFailed) diff --git a/pkg/generator/azkeyvault.go b/pkg/generator/azkeyvault.go index baa3e1c..72b804d 100644 --- a/pkg/generator/azkeyvault.go +++ b/pkg/generator/azkeyvault.go @@ -19,21 +19,28 @@ type KvScrtStore struct { svc kvApi ctx context.Context token string - config TokenConfigVars + config *AzKvConfig +} + +// AzKvConfig takes any metadata from the token +// Version is the only +type AzKvConfig struct { + Version string `json:"version"` } // NewKvScrtStore returns a KvScrtStore // requires `AZURE_SUBSCRIPTION_ID` environment variable to be present to successfully work func NewKvScrtStore(ctx context.Context, token string, conf GenVarsConfig) (*KvScrtStore, error) { - ct := conf.ParseTokenVars(token) + storeConf := &AzKvConfig{} + initialToken := ParseMetadata(token, storeConf) backingStore := &KvScrtStore{ ctx: ctx, - config: ct, + config: storeConf, } - srvInit := azServiceFromToken(stripPrefix(ct.Token, AzKeyVaultSecretsPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.vault.azure.net", 1) + srvInit := azServiceFromToken(stripPrefix(initialToken, AzKeyVaultSecretsPrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.vault.azure.net", 1) backingStore.token = srvInit.token cred, err := azidentity.NewDefaultAzureCredential(nil) diff --git a/pkg/generator/aztablestorage.go b/pkg/generator/aztablestorage.go index 14256fc..4521f35 100644 --- a/pkg/generator/aztablestorage.go +++ b/pkg/generator/aztablestorage.go @@ -27,20 +27,24 @@ type AzTableStore struct { svc tableStoreApi ctx context.Context token string - config TokenConfigVars + config *AzTableStrgConfig +} + +type AzTableStrgConfig struct { + Format string `json:"format"` } // NewAzTableStore func NewAzTableStore(ctx context.Context, token string, conf GenVarsConfig) (*AzTableStore, error) { - ct := conf.ParseTokenVars(token) - + storeConf := &AzTableStrgConfig{} + initialToken := ParseMetadata(token, storeConf) backingStore := &AzTableStore{ ctx: ctx, - config: ct, + config: storeConf, } - srvInit := azServiceFromToken(stripPrefix(ct.Token, AzTableStorePrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.table.core.windows.net/%s", 2) + srvInit := azServiceFromToken(stripPrefix(initialToken, AzTableStorePrefix, conf.TokenSeparator(), conf.KeySeparator()), "https://%s.table.core.windows.net/%s", 2) backingStore.token = srvInit.token cred, err := azidentity.NewDefaultAzureCredential(nil) @@ -109,4 +113,3 @@ func azTableStoreTokenSplitter(token string) (partitionKey, rowKey string, err e // naked return to save having to define another struct return } - diff --git a/pkg/generator/config.go b/pkg/generator/config.go index 858cce7..e75e3ac 100644 --- a/pkg/generator/config.go +++ b/pkg/generator/config.go @@ -1,7 +1,8 @@ package generator import ( - "regexp" + "encoding/json" + "fmt" "strings" ) @@ -68,29 +69,59 @@ func (c *GenVarsConfig) KeySeparator() string { return c.keySeparator } -// ParseTokenVars extracts info from the token "metadata" +// ParseMetadata parses the metadata of each token into the provided pointer. +// All data inside the `[` `]` is considered metadata about the token. // -// All data inside the `[` `]` is considered metadata about the token -func (c *GenVarsConfig) ParseTokenVars(token string) TokenConfigVars { - tc := TokenConfigVars{} - // strip anything in [] - vars := regexp.MustCompile(`\[.*\]`) - rawVars := vars.FindString(token) - // extract [role:,version:] - if rawVars != "" { - role := regexp.MustCompile(`role:(.*?)(?:,|])`).FindStringSubmatch(rawVars) - if len(role) > 0 { - tc.Role = role[1] - } - // TODO: create aliases for version (e.g. label) - version := regexp.MustCompile(`version:(.*?)(?:,|])`).FindStringSubmatch(rawVars) - if len(version) > 0 { - tc.Version = version[1] +// returns the token without the metadata `[` `]` +// +// Further processing down the line will remove other elements of the token. +func ParseMetadata[T comparable](token string, typ T) string { + metadataStr, startIndex, found := extractMetadataStr(token) + if !found { + return token + } + if startIndex > 0 { + token = token[0:startIndex] + } + // crude json like builder from key/val tags + // since we are only ever dealing with a string input + // extracted from the token there is little chance panic would occur here + // WATCH THIS SPACE "¯\_(ツ)_/¯" + metaMap := []string{} + for _, keyVal := range strings.Split(metadataStr, ",") { + mapKeyVal := strings.Split(keyVal, "=") + if len(mapKeyVal) == 2 { + metaMap = append(metaMap, fmt.Sprintf(`"%s":"%s"`, mapKeyVal[0], mapKeyVal[1])) } - tc.Token = strings.ReplaceAll(token, rawVars, "") - // tc.Role = - return tc } - tc.Token = token - return tc + // empty map will be parsed as `{}` still resulting in a valid json + // and successful unmarshalling but default value pointer struct + b := []byte(fmt.Sprintf(`{%s}`, strings.Join(metaMap, ","))) + if err := json.Unmarshal(b, typ); err != nil { + // It would very hard to test this since + // we are forcing the key and value to be strings + // return non-filled pointer + return token + } + return token +} + +const startMetaStr string = `[` +const endMetaStr string = `]` + +// extractMetadataStr returns anything between the start and end +// metadata markers in the token string itself +func extractMetadataStr(str string) (metaString string, startIndex int, found bool) { + + startIndex = strings.Index(str, startMetaStr) + if startIndex == -1 { + return metaString, startIndex, false + } + newS := str[startIndex+len(startMetaStr):] + e := strings.Index(newS, endMetaStr) + if e == -1 { + return metaString, -1, false + } + metaString = newS[:e] + return metaString, startIndex, true } diff --git a/pkg/generator/config_test.go b/pkg/generator/config_test.go index 735c302..00be886 100644 --- a/pkg/generator/config_test.go +++ b/pkg/generator/config_test.go @@ -1,85 +1,134 @@ package generator_test -import ( - "testing" +// func TestParseTokens(t *testing.T) { +// ttests := map[string]struct { +// config generator.GenVarsConfig +// rawToken string +// expect generator.TokenConfigVars +// }{ +// "role, version specified": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[role:arn:aws:iam::1111111:role/i-orchestration,version:1082313]`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123|d88`, +// Role: `arn:aws:iam::1111111:role/i-orchestration`, +// Version: `1082313`, +// }, +// }, +// "version, role specified": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[version:1082313,role:arn:aws:iam::1111111:role/i-orchestration]`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123|d88`, +// Role: `arn:aws:iam::1111111:role/i-orchestration`, +// Version: `1082313`, +// }, +// }, +// "version only specified": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[version:1082313]`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123|d88`, +// Role: ``, +// Version: `1082313`, +// }, +// }, +// "role only specified": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[role:arn:aws:iam::1111111:role/i-orchestration]`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123|d88`, +// Role: `arn:aws:iam::1111111:role/i-orchestration`, +// Version: ``, +// }, +// }, +// "no additional config specified": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123|d88`, +// Role: ``, +// Version: ``, +// }, +// }, +// "additional config specified but empty": { +// *generator.NewConfig(), +// `FOO://basjh/dskjuds/123[]`, +// generator.TokenConfigVars{ +// Token: `FOO://basjh/dskjuds/123`, +// Role: ``, +// Version: ``, +// }, +// }, +// } +// for name, tt := range ttests { +// t.Run(name, func(t *testing.T) { +// got := tt.config.ParseTokenVars(tt.rawToken) +// if got.Role != tt.expect.Role { +// t.Errorf(testutils.TestPhraseWithContext, "role incorrect", got.Role, tt.expect.Role) +// } +// if got.Version != tt.expect.Version { +// t.Errorf(testutils.TestPhraseWithContext, "version incorrect", got.Version, tt.expect.Version) +// } +// if got.Token != tt.expect.Token { +// t.Errorf(testutils.TestPhraseWithContext, "token incorrect", got.Token, tt.expect.Token) +// } +// }) +// } +// } - "github.com/dnitsch/configmanager/internal/testutils" - "github.com/dnitsch/configmanager/pkg/generator" -) +// func Test_MarshalMetadata_with_label_struct_succeeds(t *testing.T) { +// type labelMeta struct { +// Label string `json:"label"` +// } -func TestParseTokens(t *testing.T) { - ttests := map[string]struct { - config generator.GenVarsConfig - rawToken string - expect generator.TokenConfigVars - }{ - "role, version specified": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123|d88[role:arn:aws:iam::1111111:role/i-orchestration,version:1082313]`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123|d88`, - Role: `arn:aws:iam::1111111:role/i-orchestration`, - Version: `1082313`, - }, - }, - "version, role specified": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123|d88[version:1082313,role:arn:aws:iam::1111111:role/i-orchestration]`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123|d88`, - Role: `arn:aws:iam::1111111:role/i-orchestration`, - Version: `1082313`, - }, - }, - "version only specified": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123|d88[version:1082313]`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123|d88`, - Role: ``, - Version: `1082313`, - }, - }, - "role only specified": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123|d88[role:arn:aws:iam::1111111:role/i-orchestration]`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123|d88`, - Role: `arn:aws:iam::1111111:role/i-orchestration`, - Version: ``, - }, - }, - "no additional config specified": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123|d88`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123|d88`, - Role: ``, - Version: ``, - }, - }, - "additional config specified but empty": { - *generator.NewConfig(), - `FOO://basjh/dskjuds/123[]`, - generator.TokenConfigVars{ - Token: `FOO://basjh/dskjuds/123`, - Role: ``, - Version: ``, - }, - }, - } - for name, tt := range ttests { - t.Run(name, func(t *testing.T) { - got := tt.config.ParseTokenVars(tt.rawToken) - if got.Role != tt.expect.Role { - t.Errorf(testutils.TestPhraseWithContext, "role incorrect", got.Role, tt.expect.Role) - } - if got.Version != tt.expect.Version { - t.Errorf(testutils.TestPhraseWithContext, "version incorrect", got.Version, tt.expect.Version) - } - if got.Token != tt.expect.Token { - t.Errorf(testutils.TestPhraseWithContext, "token incorrect", got.Token, tt.expect.Token) - } - }) - } -} +// ttests := map[string]struct { +// config *generator.GenVarsConfig +// rawToken string +// wantVal any +// }{ +// "when provider expects label on token and label exists": { +// generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[label=dev]`, +// "dev", +// }, +// "when provider expects label on token and label does not exist": { +// generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88[someother=dev]`, +// "", +// }, +// "no metadata found": { +// generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88`, +// "", +// }, +// "no metadata found incorrect marker placement": { +// generator.NewConfig(), +// `FOO://basjh/dskjuds/123|d88]asdas=bar[`, +// "", +// }, +// } +// for name, tt := range ttests { +// t.Run(name, func(t *testing.T) { +// inputTyp := &labelMeta{} +// got := tt.config.ParseMetadata(tt.rawToken, inputTyp) +// if got == nil { +// t.Errorf("got , wanted: %v\n", inputTyp) +// } + +// gotTyp := got.(*labelMeta) + +// if gotTyp.Label != tt.wantVal { +// t.Errorf("got %v, wanted: %v\n", gotTyp, inputTyp) +// } +// }) +// } +// } + +// func Test_MarshalMetadata_with_label_struct_fails_with_nil_pointer(t *testing.T) { +// got := generator.NewConfig().ParseMetadata(`FOO://basjh/dskjuds/123|d88`, nil) +// if got != nil { +// t.Errorf("got %v, wanted:\n", got) +// } + +// } diff --git a/pkg/generator/gcpsecrets.go b/pkg/generator/gcpsecrets.go index 1557ea1..ddd71f2 100644 --- a/pkg/generator/gcpsecrets.go +++ b/pkg/generator/gcpsecrets.go @@ -17,11 +17,15 @@ type gcpSecretsApi interface { type GcpSecrets struct { svc gcpSecretsApi ctx context.Context - config TokenConfigVars + config *GcpSecretsConfig close func() error token string } +type GcpSecretsConfig struct { + Version string `json:"version"` +} + func NewGcpSecrets(ctx context.Context) (*GcpSecrets, error) { c, err := gcpsecrets.NewClient(ctx) @@ -38,9 +42,11 @@ func NewGcpSecrets(ctx context.Context) (*GcpSecrets, error) { } func (imp *GcpSecrets) setTokenVal(token string) { - ct := (&GenVarsConfig{}).ParseTokenVars(token) - imp.config = ct - imp.token = ct.Token + storeConf := &GcpSecretsConfig{} + initialToken := ParseMetadata(token, storeConf) + + imp.config = storeConf + imp.token = initialToken } func (imp *GcpSecrets) tokenVal(v *retrieveStrategy) (string, error) { diff --git a/pkg/generator/hashivault.go b/pkg/generator/hashivault.go index 814d617..4900cdf 100644 --- a/pkg/generator/hashivault.go +++ b/pkg/generator/hashivault.go @@ -28,33 +28,33 @@ type hashiVaultApi interface { type VaultStore struct { svc hashiVaultApi ctx context.Context - config TokenConfigVars + config *VaultConfig token string } -func NewVaultStore(ctx context.Context, token string, conf GenVarsConfig) (*VaultStore, error) { - var client *vault.Client - - tc := conf.ParseTokenVars(token) +type VaultConfig struct { + Version string `json:"version"` + Role string `json:"iam_role"` +} +func NewVaultStore(ctx context.Context, token string, conf GenVarsConfig) (*VaultStore, error) { + storeConf := &VaultConfig{} + initialToken := ParseMetadata(token, storeConf) imp := &VaultStore{ ctx: ctx, - config: tc, + config: storeConf, } config := vault.DefaultConfig() - - vt := splitToken(stripPrefix(tc.Token, HashicorpVaultPrefix, conf.TokenSeparator(), conf.KeySeparator())) - + vt := splitToken(stripPrefix(initialToken, HashicorpVaultPrefix, conf.TokenSeparator(), conf.KeySeparator())) imp.token = vt.token - client, err := vault.NewClient(config) if err != nil { return nil, fmt.Errorf("unable to initialize Vault client: %v", err) } if strings.HasPrefix(os.Getenv("VAULT_TOKEN"), "aws_iam") { - awsclient, err := newVaultStoreWithAWSAuthIAM(client, tc.Role) + awsclient, err := newVaultStoreWithAWSAuthIAM(client, storeConf.Role) if err != nil { return nil, err } @@ -74,13 +74,13 @@ func newVaultStoreWithAWSAuthIAM(client *vault.Client, role string) (*vault.Clie auth.WithRole(role), ) if err != nil { - return nil, fmt.Errorf("unable to initialize AWS auth method: %w", err) + return nil, fmt.Errorf("unable to initialize AWS auth method: %s. %w", err, ErrClientInitialization) } authInfo, err := client.Auth().Login(context.Background(), awsAuth) if err != nil { - return nil, fmt.Errorf("unable to login to AWS auth method: %w", err) + return nil, fmt.Errorf("unable to login to AWS auth method: %s. %w", err, ErrClientInitialization) } if authInfo == nil { return nil, fmt.Errorf("no auth info was returned after login") @@ -89,14 +89,14 @@ func newVaultStoreWithAWSAuthIAM(client *vault.Client, role string) (*vault.Clie return client, nil } -// setToken already happens in Vault constructor -// no need to re-set it here -func (imp *VaultStore) setTokenVal(token string) { - // this happens inside the New func call - // due to the way the client needs to be - // initialised with a mountpath - // and mountpath is part of the token so it is set then -} +// setTokenVal +// imp.token is already set in the Vault constructor +// +// This happens inside the New func call +// due to the way the client needs to be +// initialised with a mountpath +// and mountpath is part of the token so it is set then +func (imp *VaultStore) setTokenVal(token string) {} // getTokenValue implements the underlying techonology // token retrieval and returns a stringified version diff --git a/pkg/generator/hashivault_test.go b/pkg/generator/hashivault_test.go index 731248e..9734131 100644 --- a/pkg/generator/hashivault_test.go +++ b/pkg/generator/hashivault_test.go @@ -200,7 +200,7 @@ func TestVaultScenarios(t *testing.T) { } }, }, - "version provided correctly": {"VAULT://secret___/some/other/foo2[version:1]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, `{"foo2":"dsfsdf3454456"}`, func(t *testing.T) hashiVaultApi { + "version provided correctly": {"VAULT://secret___/some/other/foo2[version=1]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, `{"foo2":"dsfsdf3454456"}`, func(t *testing.T) hashiVaultApi { mv := mockVaultApi{} mv.gv = func(ctx context.Context, secretPath string, version int) (*vault.KVSecret, error) { t.Helper() @@ -220,7 +220,7 @@ func TestVaultScenarios(t *testing.T) { } }, }, - "version provided but unable to parse": {"VAULT://secret___/some/other/foo2[version:1a]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, "unable to parse version into an integer: strconv.Atoi: parsing \"1a\": invalid syntax", func(t *testing.T) hashiVaultApi { + "version provided but unable to parse": {"VAULT://secret___/some/other/foo2[version=1a]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, "unable to parse version into an integer: strconv.Atoi: parsing \"1a\": invalid syntax", func(t *testing.T) hashiVaultApi { mv := mockVaultApi{} mv.gv = func(ctx context.Context, secretPath string, version int) (*vault.KVSecret, error) { t.Helper() @@ -326,13 +326,13 @@ func TestAwsIamAuth(t *testing.T) { }, }, "aws_iam auth incorrectly formatted request": { - "VAULT://secret___/some/other/foo2[version:1,role:not_a_role]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, + "VAULT://secret___/some/other/foo2[version=1,iam_role=not_a_role]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, `unable to login to AWS auth method: unable to log in to auth method: unable to log in with AWS auth: Error making API request. URL: PUT %s/v1/auth/aws/login Code: 400. Raw Message: -incorrect values supplied`, +incorrect values supplied. failed to initialize the client`, func(t *testing.T) hashiVaultApi { mv := mockVaultApi{} mv.g = func(ctx context.Context, secretPath string) (*vault.KVSecret, error) { @@ -367,7 +367,7 @@ incorrect values supplied`, }, }, "aws_iam auth success": { - "VAULT://secret___/some/other/foo2[role:arn:aws:iam::1111111:role/i-orchestration]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, + "VAULT://secret___/some/other/foo2[iam_role=arn:aws:iam::1111111:role/i-orchestration]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, `{"foo2":"dsfsdf3454456"}`, func(t *testing.T) hashiVaultApi { mv := mockVaultApi{} @@ -404,8 +404,8 @@ incorrect values supplied`, }, }, "aws_iam auth no token returned": { - "VAULT://secret___/some/other/foo2[role:arn:aws:iam::1111111:role/i-orchestration]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, - `unable to login to AWS auth method: response did not return ClientToken, client token not set`, + "VAULT://secret___/some/other/foo2[iam_role=arn:aws:iam::1111111:role/i-orchestration]", GenVarsConfig{tokenSeparator: "://", keySeparator: "|"}, + `unable to login to AWS auth method: response did not return ClientToken, client token not set. failed to initialize the client`, func(t *testing.T) hashiVaultApi { mv := mockVaultApi{} mv.g = func(ctx context.Context, secretPath string) (*vault.KVSecret, error) { diff --git a/pkg/generator/paramstore.go b/pkg/generator/paramstore.go index 441ee77..ce070e3 100644 --- a/pkg/generator/paramstore.go +++ b/pkg/generator/paramstore.go @@ -16,10 +16,14 @@ type paramStoreApi interface { type ParamStore struct { svc paramStoreApi ctx context.Context - config TokenConfigVars + config *ParamStrConfig token string } +type ParamStrConfig struct { + // reserved for potential future use +} + func NewParamStore(ctx context.Context) (*ParamStore, error) { cfg, err := config.LoadDefaultConfig(ctx) if err != nil { @@ -35,9 +39,11 @@ func NewParamStore(ctx context.Context) (*ParamStore, error) { } func (imp *ParamStore) setTokenVal(token string) { - ct := (&GenVarsConfig{}).ParseTokenVars(token) - imp.config = ct - imp.token = ct.Token + storeConf := &ParamStrConfig{} + initialToken := ParseMetadata(token, storeConf) + + imp.config = storeConf + imp.token = initialToken } func (imp *ParamStore) tokenVal(v *retrieveStrategy) (string, error) { diff --git a/pkg/generator/secretsmanager.go b/pkg/generator/secretsmanager.go index ec9a305..87cb1f8 100644 --- a/pkg/generator/secretsmanager.go +++ b/pkg/generator/secretsmanager.go @@ -16,10 +16,14 @@ type secretsMgrApi interface { type SecretsMgr struct { svc secretsMgrApi ctx context.Context - config TokenConfigVars + config *SecretsMgrConfig token string } +type SecretsMgrConfig struct { + Version string `json:"version"` +} + func NewSecretsMgr(ctx context.Context) (*SecretsMgr, error) { cfg, err := config.LoadDefaultConfig(ctx) if err != nil { @@ -36,9 +40,11 @@ func NewSecretsMgr(ctx context.Context) (*SecretsMgr, error) { } func (imp *SecretsMgr) setTokenVal(token string) { - ct := (&GenVarsConfig{}).ParseTokenVars(token) - imp.config = ct - imp.token = ct.Token + storeConf := &SecretsMgrConfig{} + initialToken := ParseMetadata(token, storeConf) + + imp.config = storeConf + imp.token = initialToken } func (imp *SecretsMgr) tokenVal(v *retrieveStrategy) (string, error) { From 8cc320884457c5b266706a5ed6b428120a2c33f1 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Thu, 21 Mar 2024 13:30:56 +0000 Subject: [PATCH 6/7] fix: az app conf unit tests +semver: feature +semver: feat --- pkg/generator/azappconf.go | 8 +- pkg/generator/azappconf_test.go | 168 ++++++++++++++++++++++++++- pkg/generator/aztablestorage_test.go | 1 + 3 files changed, 170 insertions(+), 7 deletions(-) diff --git a/pkg/generator/azappconf.go b/pkg/generator/azappconf.go index 4780ac9..273d37c 100644 --- a/pkg/generator/azappconf.go +++ b/pkg/generator/azappconf.go @@ -31,7 +31,7 @@ type AzAppConf struct { // and it is parsed from the token metadata type AzAppConfConfig struct { Label string `json:"label"` - OnlyIfChanged *azcore.ETag `json:"onlyIfChanged"` + Etag *azcore.ETag `json:"etag"` AcceptDateTime *time.Time `json:"acceptedDateTime"` } @@ -84,10 +84,14 @@ func (imp *AzAppConf) tokenVal(v *retrieveStrategy) (string, error) { opts.Label = &imp.config.Label } + if imp.config.Etag != nil { + opts.OnlyIfChanged = imp.config.Etag + } + s, err := imp.svc.GetSetting(ctx, imp.token, opts) if err != nil { log.Errorf(implementationNetworkErr, AzAppConfigPrefix, err, imp.token) - return "", fmt.Errorf("token: %s, error: %v. %w", imp.token, err, ErrServiceCallFailed) + return "", fmt.Errorf("token: %s, error: %v. %w", imp.token, err, ErrRetrieveFailed) } if s.Value != nil { return *s.Value, nil diff --git a/pkg/generator/azappconf_test.go b/pkg/generator/azappconf_test.go index adb663e..6174fae 100644 --- a/pkg/generator/azappconf_test.go +++ b/pkg/generator/azappconf_test.go @@ -2,13 +2,171 @@ package generator import ( "context" + "errors" + "fmt" "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig" + "github.com/dnitsch/configmanager/internal/testutils" ) -func Test_AzAppConf_succeeds(t *testing.T) { - c, _ := NewAzAppConf(context.TODO(), "AZAPPCONF://configmanager-app-config/queue_name", *(NewConfig().WithTokenSeparator("://"))) - if c == nil { - t.Errorf("got %v, wanted: %v", c, AzAppConf{}) +func azAppConfCommonChecker(t *testing.T, key string, expectedKey string, expectLabel string, opts *azappconfig.GetSettingOptions) { + t.Helper() + if key != expectedKey { + t.Errorf(testutils.TestPhrase, key, expectedKey) + } + + if expectLabel != "" { + if opts == nil { + t.Errorf(testutils.TestPhrase, nil, expectLabel) + } + if *opts.Label != expectLabel { + t.Errorf(testutils.TestPhrase, opts.Label, expectLabel) + } + } +} + +type mockAzAppConfApi func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) + +func (m mockAzAppConfApi) GetSetting(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + return m(ctx, key, options) +} + +func Test_AzAppConf_Success(t *testing.T) { + tests := map[string]struct { + token string + expect string + mockClient func(t *testing.T) appConfApi + config *GenVarsConfig + }{ + "successVal": { + "AZAPPCONF#/test-app-config-instance/table//token/1", + tsuccessParam, + func(t *testing.T) appConfApi { + return mockAzAppConfApi(func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + azAppConfCommonChecker(t, key, "table//token/1", "", options) + resp := azappconfig.GetSettingResponse{} + resp.Value = &tsuccessParam + return resp, nil + }) + }, + NewConfig().WithKeySeparator("|").WithTokenSeparator("#"), + }, + "successVal with :// token Separator": { + "AZAPPCONF:///test-app-config-instance/conf_key[label=dev]", + tsuccessParam, + func(t *testing.T) appConfApi { + return mockAzAppConfApi(func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + azAppConfCommonChecker(t, key, "conf_key", "dev", options) + resp := azappconfig.GetSettingResponse{} + resp.Value = &tsuccessParam + return resp, nil + }) + }, + NewConfig().WithKeySeparator("|").WithTokenSeparator("://"), + }, + "successVal with :// token Separator and etag specified": { + "AZAPPCONF:///test-app-config-instance/conf_key[label=dev,etag=sometifdsssdsfdi_string01209222]", + tsuccessParam, + func(t *testing.T) appConfApi { + return mockAzAppConfApi(func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + azAppConfCommonChecker(t, key, "conf_key", "dev", options) + if !options.OnlyIfChanged.Equals("sometifdsssdsfdi_string01209222") { + t.Errorf(testutils.TestPhraseWithContext, "Etag not correctly set", options.OnlyIfChanged, "sometifdsssdsfdi_string01209222") + } + resp := azappconfig.GetSettingResponse{} + resp.Value = &tsuccessParam + return resp, nil + }) + }, + NewConfig().WithKeySeparator("|").WithTokenSeparator("://"), + }, + "successVal with keyseparator but no val returned": { + "AZAPPCONF#/test-app-config-instance/try_to_find|key_separator.lookup", + "", + func(t *testing.T) appConfApi { + return mockAzAppConfApi(func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + azAppConfCommonChecker(t, key, "try_to_find", "", options) + resp := azappconfig.GetSettingResponse{} + resp.Value = nil + return resp, nil + }) + }, + NewConfig().WithKeySeparator("|").WithTokenSeparator("#"), + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + impl, err := NewAzAppConf(context.TODO(), tt.token, *tt.config) + if err != nil { + t.Errorf("failed to init AZAPPCONF") + } + + impl.svc = tt.mockClient(t) + rs := newRetrieveStrategy(NewDefatultStrategy(), *tt.config) + rs.setImplementation(impl) + got, err := rs.getTokenValue() + if err != nil { + if err.Error() != tt.expect { + t.Errorf(testutils.TestPhrase, err.Error(), tt.expect) + } + return + } + + if got != tt.expect { + t.Errorf(testutils.TestPhrase, got, tt.expect) + } + }) + } +} + +func Test_AzAppConf_Error(t *testing.T) { + + tests := map[string]struct { + token string + expect error + mockClient func(t *testing.T) appConfApi + config *GenVarsConfig + }{ + "errored on service method call": { + "AZAPPCONF#/test-app-config-instance/table/token/ok", + ErrRetrieveFailed, + func(t *testing.T) appConfApi { + return mockAzAppConfApi(func(ctx context.Context, key string, options *azappconfig.GetSettingOptions) (azappconfig.GetSettingResponse, error) { + t.Helper() + resp := azappconfig.GetSettingResponse{} + return resp, fmt.Errorf("network error") + }) + }, + NewConfig().WithKeySeparator("|").WithTokenSeparator("#"), + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + impl, err := NewAzAppConf(context.TODO(), tt.token, *tt.config) + if err != nil { + t.Fatal("failed to init AZAPPCONF") + } + impl.svc = tt.mockClient(t) + rs := newRetrieveStrategy(NewDefatultStrategy(), *tt.config) + rs.setImplementation(impl) + if _, err := rs.getTokenValue(); !errors.Is(err, tt.expect) { + t.Errorf(testutils.TestPhrase, err.Error(), tt.expect) + } + }) + } +} + +func Test_fail_AzAppConf_Client_init(t *testing.T) { + // this is basically a wrap around test for the url.Parse method in the stdlib + // as that is what the client uses under the hood + _, err := NewAzAppConf(context.TODO(), "/%25%65%6e%301-._~/") + } + if !errors.Is(err, ErrClientInitialization) { + t.Fatalf(testutils.TestPhraseWithContext, "azappconf client init", err.Error(), ErrClientInitialization.Error()) } - // got, err := c.tokenVal() } diff --git a/pkg/generator/aztablestorage_test.go b/pkg/generator/aztablestorage_test.go index cea6222..053e57c 100644 --- a/pkg/generator/aztablestorage_test.go +++ b/pkg/generator/aztablestorage_test.go @@ -12,6 +12,7 @@ import ( ) func azTableStoreCommonChecker(t *testing.T, partitionKey, rowKey, expectedPartitionKey, expectedRowKey string) { + t.Helper() if partitionKey == "" { t.Errorf("expect name to not be nil") } From 76d26b94daeb592cefe54adfd577a352fe76b4a4 Mon Sep 17 00:00:00 2001 From: dnitsch Date: Thu, 21 Mar 2024 14:32:41 +0000 Subject: [PATCH 7/7] fix: update docs --- README.md | 223 ++++++++++-------------------------- docs/adding-provider.md | 41 ++++++- docs/examples.md | 166 +++++++++++++++++++++++++++ pkg/generator/hashivault.go | 1 + 4 files changed, 266 insertions(+), 165 deletions(-) create mode 100644 docs/examples.md diff --git a/README.md b/README.md index 1678413..553a207 100644 --- a/README.md +++ b/README.md @@ -67,109 +67,106 @@ ConfigManager comes packaged as a CLI for all major platforms, to see [download/ For more detailed usage you can run -h with each subcommand and additional info can be found [here](./docs/commands.md) -## __Config Tokens__ +## __Token Config__ -The token is made up of 3 parts: +The token is made up of the following parts: + +_An example token would look like this_ + +#### `AWSSECRETS#/path/to/my/key|lookup.Inside.Object[meta=data]` ### Implementation indicator -e.g. `AWSSECRETS` the strategy identifier to choose at runtime +The `AWSSECRETS` the strategy identifier to choose the correct provider at runtime. Multiple providers can be referenced in a single run via a CLI or with the API. + +This is not overrideable and must be exactly as it is in the provided list of providers. ### __Token Separator__ -e.g. `#` - used for separating the implementation indicator and the look up value. +The `#` symbol from the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) - used for separating the implementation indicator and the look up value. -> The default is currently `#` - it will change to `://` to allow for a more natural reading of the "token". you can achieve this behaviour now by either specifying the `-s` to the CLI or ConfigManager public methods, like below. +> The default is currently `#` - it will change to `://` to allow for a more natural reading of the "token". you can achieve this behaviour now by either specifying the `-s` to the CLI or ConfigManager Go API. ```go -rawStr := `somePAss: AWSPARAMSTR:///int-test/pocketbase/admin-pwd` -cm := configmanager.ConfigManager{} -// use custom token separator -// inline with v2 coming changes cnf := generator.NewConfig().WithTokenSeparator("://") -// replaced will be a string which needs unmarshalling -replaced, err := cm.RetrieveWithInputReplaced(rawStr, *cnf) ``` -Alternatively you can use the helper methods for Yaml or Json tagged structs - see [examples](./examples/examples.go) for more details +### __Provider Secret/Config Path__ -- `/path/to/parameter` the actual path to the secret or parameter in the target system e.g. AWS SecretsManager or ParameterStore (it does assume a path like pattern might throw a runtime error if not found) +The `/path/to/my/key` part from the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) is the actual path to the item in the backing store. -If contents of the `AWSSECRETS#/appxyz/service1-password` are a string then `service1-password` will be the key and converted to UPPERCASE e.g. `SERVICE1_PASSWORD=som3V4lue` +See the different special considerations per provider as it different providers will require different implementations. ### __Key Separator__ -Specifying a key seperator on token items that can be parsed as a K/V map will result in only retrieving the specific key from the map. +__THIS IS OPTIONAL__ + +The `|` symbol from the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) is used to specify the key seperator. + +If an item retrieved from a store is JSON parseable map it can be interrogated for further properties inside. + +### __Look up key__ -e.g. if contents of the `AWSSECRETS#/appxyz/service1-db-config` are parseable into the below object +__THIS IS OPTIONAL__ + +The `lookup.Inside.Object` from the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) is used to perform a lookup inside the retrieved item IF it is parseable into a `map[string]any` structure. + +Given the below response from a backing store ```json { - "host": "db.internal", - "port": 3306, - "pass": "sUp3$ecr3T!", + "lookup": { + "Inside": { + "Object": { + "host": "db.internal", + "port": 3306, + "pass": "sUp3$ecr3T!", + } + } + } } ``` -Then you can access the single values like this `AWSSECRETS#/appxyz/service1-db-config|host` ==> `export SERVICE1_DB_CONFIG__HOST='db.internal'` - -Alternatively if you are `configmanager`-ing a file via the fromstr command and the input is something like this: - -(YAML) +The value returned for the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) would be: -```yaml -app: - name: xyz -db: - host: AWSSECRETS#/appxyz/service1-db-config|host - port: AWSSECRETS#/appxyz/service1-db-config|port - pass: AWSSECRETS#/appxyz/service1-db-config|pass +```json +{ + "host": "db.internal", + "port": 3306, + "pass": "sUp3$ecr3T!", +} ``` -which would result in this +See [examples of working with files](docs/examples.md#working-with-files) for more details. -```yaml -app: - name: xyz -db: - host: db.internal - port: 3306 - pass: sUp3$ecr3T! -``` +### Token Metadata Config -If your config parameter matches the config interface, you can also leave the entire token to point to the `db` key +The `[meta=data]` from the [example token](#awssecretspathtomykeylookupinsideobjectmetadata) - is the optional metadata about the target in the backing provider -```yaml -app: - name: xyz -db: AWSSECRETS#/appxyz/service1-db-config -``` +IT must have this format `[key=value]` - IT IS OPTIONAL -result: +The `key` and `value` would be provider specific. Meaning that different providers support different config, these values _CAN_ be safely omitted configmanager would just use the defaults where applicable or not specify the additional -```yaml -app: - name: xyz -db: { - "host": "db.internal", - "port": 3306, - "pass": "sUp3$ecr3T!", -} -``` +- Hashicorp Vault (VAULT) + - `iam_role` - would be the value of an IAM role ARN to use with AWSClient Authentication. + - `version` - is the version of the secret/configitem to get (should be in an integer format) -### Additional Token Config + e.g. `VAULT://baz/bar/123|d88[role=arn:aws:iam::1111111:role/i-orchestration,version=1082313]` -Suffixed `[]` with `role:` or `version:` specified inside the brackets and comma separated +- Azure AppConfig (AZAPPCONF) + - `label` - the label to use whilst retrieving the item + - `etag` - etag value -order is not important, but the `role:` keyword must be followed by the role string + e.g. `AZAPPCONF://baz/bar/123|d88[label=dev,etag=aaaaa1082313]` -e.g. `VAULT://baz/bar/123|d88[role:arn:aws:iam::1111111:role/i-orchestration,version:1082313]` +- GCP secrets, AWS SEcrets, AZ KeyVault (`GCPSECRETS` , `AWSSECRETS`, `AZKVSECRET`) + they all support the `version` metadata property -Currently only supporting version and role but may be extended in the future. + e.g. `GCPSECRETS://baz/bar/123|d88[version=verUUID0000-1123zss]` -- role is used with `VAULT` `aws_iam` auth type. Specifying it on a token level as opposed to globally will ensure that multiple roles can be used provided that the caller has the ability to assume them. +## Special considerations -- version can be used within all implementations that support versioned config items e.g. `VAULT`, `GCPSECRETS` , `AWSSECRETS`, `AZKVSECRET`. If omitted it will default to the `LATEST`. +This section outlines the special consideration in token construction on a per provider basis ### Special consideration for AZKVSECRET @@ -220,105 +217,9 @@ when using Vault in AWS - you can set the value of the `VAULT_TOKEN=aws_iam` thi The Hashicorp Vault functions in the same exact way as the other implementations. It will retrieve the JSON object and can be looked up within it by using a key separator. -## Go API - -latest api [here](https://pkg.go.dev/github.com/dnitsch/configmanager) - -### Sample Use case - -One of the sample use cases includes implementation in a K8s controller. - -E.g. your Custom CRD stores some values in plain text that should really be secrets/nonpublic config parameters - something like this can be invoked from inside the controller code using the generator pkg API. - -See [examples](./examples/examples.go) for more examples and tests for sample input/usage +## [Go API](https://pkg.go.dev/github.com/dnitsch/configmanager) -```go -package main - -import ( - "context" - "fmt" - - "github.com/dnitsch/configmanager/pkg/generator" - "github.com/dnitsch/configmanager" -) - -func main() { - cm := &configmanager.ConfigManager{} - cnf := generator.NewConfig() - // JSON Marshal K8s CRD into - exampleK8sCrdMarshalled := `apiVersion: crd.foo.custom/v1alpha1 -kind: CustomFooCrd -metadata: - name: foo - namespace: bar -spec: - name: baz - secret_val: AWSSECRETS#/customfoo/secret-val - owner: test_10016@example.com -` - pm, err := cm.RetrieveWithInputReplaced(exampleK8sCrdMarshalled, *cnf) - - if err != nil { - panic(err) - } - fmt.Println(pm) -} -``` - -Above example would ensure that you can safely store config/secret values on a CRD in plain text. - -Or using go1.19+ [generics example](https://github.com/dnitsch/reststrategy/blob/d14ccec2b29bff646678ab9cf1775c0e93308569/controller/controller.go#L353). - -> Beware logging out the CRD after tokens have been replaced. - -Samlpe call to retrieve from inside an app/serverless function to only grab the relevant values from config. - -```go -package main - -import ( - "context" - "fmt" - "log" - "os" - - "github.com/dnitsch/configmanager" - "github.com/dnitsch/configmanager/pkg/generator" -) - -var ( - DB_CONNECTION_STRING string = "someuser:%v@tcp(%s:3306)/someschema" - DB_PASSWORD_SECRET_PATH string = os.Getenv("DB_PASSWORD_TOKEN") - DB_HOST_URL string = os.Getenv("DB_URL_TOKEN") -) - -func main() { - connString, err := credentialString(context.TODO, DB_PASSWORD_SECRET_PATH, DB_HOST_URL) - if err != nil { - log.Fatal(err) - } - -} - -func credentialString(ctx context.Context, pwdToken, hostToken string) (string, error) { - - cnf := generator.NewConfig() - - pm, err := configmanager.Retrieve([]string{pwdToken, hostToken}, *cnf) - - if err != nil { - return "", err - } - if pwd, ok := pm[pwdToken]; ok { - if host, ok := pm[hostToken]; ok { - return fmt.Sprintf(DB_CONNECTION_STRING, pwd, host), nil - } - } - - return "", fmt.Errorf("unable to find value via token") -} -``` +## [Examples](docs/examples.md) ## Help diff --git a/docs/adding-provider.md b/docs/adding-provider.md index 34d02be..9c9be84 100644 --- a/docs/adding-provider.md +++ b/docs/adding-provider.md @@ -1,4 +1,4 @@ -# adding provider +# Adding a provider Add Token Prefix @@ -30,10 +30,43 @@ ensure your implementation satisfy the `genVarsStrategy` interface ```go type genVarsStrategy interface { - getTokenValue(rs *retrieveStrategy) (s string, e error) - setToken(s string) - setValue(s string) + tokenVal(rs *retrieveStrategy) (s string, e error) + setTokenVal(s string) } ``` Even if the native type is K/V return a marshalled version of the JSON as the rest of the flow will decide how to present it back to the final consumer. + +Custom properties inside the GetValue request, you could specify your own Config struct for the provider, e.g. HashiVault implementation + +```go +// VaultConfig holds the parseable metadata struct +type VaultConfig struct { + Version string `json:"version"` + Role string `json:"iam_role"` +} +``` + +You could then use it on the backingStore object + +```go +type VaultStore struct { + svc hashiVaultApi + ctx context.Context + config *VaultConfig + token string +} +``` + +On initialize of the instance or in the setTokenVal method (see GCPSecrets or AWSSecrets/ParamStore examples). + +```go +storeConf := &VaultConfig{} +initialToken := ParseMetadata(token, storeConf) +imp := &VaultStore{ + ctx: ctx, + config: storeConf, +} +``` + +Where the initialToken is the original Token without the metadata in brackets and the `storeConf` pointer will have been filled with any of the parsed metadata and used in the actual provider implementation, see any of the providers for a sample implementation. diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..755bcbf --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,166 @@ +# Examples + + + +## Working with environemt variables + + + +## Working with files + +Then you can access the single values like this `AWSSECRETS#/appxyz/service1-db-config|host` ==> `export SERVICE1_DB_CONFIG__HOST='db.internal'` + +Alternatively if you are `configmanager`-ing a file via the fromstr command and the input is something like this: + +(YAML) + +```yaml +app: + name: xyz +db: + host: AWSSECRETS#/appxyz/service1-db-config|host + port: AWSSECRETS#/appxyz/service1-db-config|port + pass: AWSSECRETS#/appxyz/service1-db-config|pass +``` + +which would result in this + +```yaml +app: + name: xyz +db: + host: db.internal + port: 3306 + pass: sUp3$ecr3T! +``` + +If your config parameter matches the config interface, you can also leave the entire token to point to the `db` key + +```yaml +app: + name: xyz +db: AWSSECRETS#/appxyz/service1-db-config +``` + +result: + +```yaml +app: + name: xyz +db: { + "host": "db.internal", + "port": 3306, + "pass": "sUp3$ecr3T!", +} +``` + +## Go API Examples + +One of the sample use cases includes implementation in a K8s controller. + +E.g. your Custom CRD stores some values in plain text that should really be secrets/nonpublic config parameters - something like this can be invoked from inside the controller code using the generator pkg API. + +See [examples](./examples/examples.go) for more examples and tests for sample input/usage + +```go +package main + +import ( + "context" + "fmt" + + "github.com/dnitsch/configmanager/pkg/generator" + "github.com/dnitsch/configmanager" +) + +func main() { + cm := &configmanager.ConfigManager{} + cnf := generator.NewConfig() + // JSON Marshal K8s CRD into + exampleK8sCrdMarshalled := `apiVersion: crd.foo.custom/v1alpha1 +kind: CustomFooCrd +metadata: + name: foo + namespace: bar +spec: + name: baz + secret_val: AWSSECRETS#/customfoo/secret-val + owner: test_10016@example.com +` + pm, err := cm.RetrieveWithInputReplaced(exampleK8sCrdMarshalled, *cnf) + + if err != nil { + panic(err) + } + fmt.Println(pm) +} +``` + +Above example would ensure that you can safely store config/secret values on a CRD in plain text. + +Or using go1.19+ [generics example](https://github.com/dnitsch/reststrategy/blob/d14ccec2b29bff646678ab9cf1775c0e93308569/controller/controller.go#L353). + +> Beware logging out the CRD after tokens have been replaced. + +Samlpe call to retrieve from inside an app/serverless function to only grab the relevant values from config. + +```go +package main + +import ( + "context" + "fmt" + "log" + "os" + + "github.com/dnitsch/configmanager" + "github.com/dnitsch/configmanager/pkg/generator" +) + +var ( + DB_CONNECTION_STRING string = "someuser:%v@tcp(%s:3306)/someschema" + DB_PASSWORD_SECRET_PATH string = os.Getenv("DB_PASSWORD_TOKEN") + DB_HOST_URL string = os.Getenv("DB_URL_TOKEN") +) + +func main() { + connString, err := credentialString(context.TODO, DB_PASSWORD_SECRET_PATH, DB_HOST_URL) + if err != nil { + log.Fatal(err) + } + +} + +func credentialString(ctx context.Context, pwdToken, hostToken string) (string, error) { + + cnf := generator.NewConfig() + + pm, err := configmanager.Retrieve([]string{pwdToken, hostToken}, *cnf) + + if err != nil { + return "", err + } + if pwd, ok := pm[pwdToken]; ok { + if host, ok := pm[hostToken]; ok { + return fmt.Sprintf(DB_CONNECTION_STRING, pwd, host), nil + } + } + + return "", fmt.Errorf("unable to find value via token") +} +``` \ No newline at end of file diff --git a/pkg/generator/hashivault.go b/pkg/generator/hashivault.go index 4900cdf..006c355 100644 --- a/pkg/generator/hashivault.go +++ b/pkg/generator/hashivault.go @@ -32,6 +32,7 @@ type VaultStore struct { token string } +// VaultConfig holds the parseable metadata struct type VaultConfig struct { Version string `json:"version"` Role string `json:"iam_role"`