diff --git a/controllers/kustomization_decryptor.go b/controllers/kustomization_decryptor.go index a403bdfc..29b82cf3 100644 --- a/controllers/kustomization_decryptor.go +++ b/controllers/kustomization_decryptor.go @@ -42,6 +42,7 @@ import ( "sigs.k8s.io/yaml" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + "github.com/fluxcd/kustomize-controller/internal/sops/azkv" intkeyservice "github.com/fluxcd/kustomize-controller/internal/sops/keyservice" ) @@ -50,14 +51,18 @@ const ( DecryptionProviderSOPS = "sops" // DecryptionVaultTokenFileName is the name of the file containing the Vault token DecryptionVaultTokenFileName = "sops.vault-token" + // DecryptionAzureAuthFile is the Azure authentication file + DecryptionAzureAuthFile = "sops.azure-kv" ) type KustomizeDecryptor struct { client.Client - kustomization kustomizev1.Kustomization - homeDir string - ageIdentities []string - vaultToken string + + kustomization kustomizev1.Kustomization + homeDir string + ageIdentities []string + vaultToken string + azureAADConfig *azkv.AADConfig } func NewDecryptor(kubeClient client.Client, @@ -155,6 +160,14 @@ func (kd *KustomizeDecryptor) ImportKeys(ctx context.Context) error { var ageIdentities []string var vaultToken string for name, value := range secret.Data { + if name == DecryptionAzureAuthFile { + azureConf := azkv.AADConfig{} + if err = azkv.LoadAADConfigFromBytes(value, &azureConf); err != nil { + return err + } + kd.azureAADConfig = &azureConf + continue + } switch filepath.Ext(name) { case ".asc": keyPath, err := securejoin.SecureJoin(tmpDir, name) @@ -272,7 +285,7 @@ func (kd KustomizeDecryptor) DataWithFormat(data []byte, inputFormat, outputForm metadataKey, err := tree.Metadata.GetDataKeyWithKeyServices( []keyservice.KeyServiceClient{ - intkeyservice.NewLocalClient(intkeyservice.NewServer(false, kd.homeDir, kd.vaultToken, kd.ageIdentities)), + intkeyservice.NewLocalClient(intkeyservice.NewServer(false, kd.homeDir, kd.vaultToken, kd.ageIdentities, kd.azureAADConfig)), }, ) if err != nil { diff --git a/docs/spec/v1beta2/kustomization.md b/docs/spec/v1beta2/kustomization.md index 3a5c022b..711cb266 100644 --- a/docs/spec/v1beta2/kustomization.md +++ b/docs/spec/v1beta2/kustomization.md @@ -967,147 +967,326 @@ the controller will impersonate the service account on the target cluster. In order to store secrets safely in a public or private Git repository, you can use [Mozilla SOPS](https://github.com/mozilla/sops) -and encrypt your Kubernetes Secrets data with [OpenPGP](https://www.openpgp.org) -and [age](https://age-encryption.org/v1/) keys. +and encrypt your Kubernetes Secrets data with [age](https://age-encryption.org/v1/) +and [OpenPGP](https://www.openpgp.org) keys, or using provider +implementations like Azure Key Vault, GCP KMS or Hashicorp Vault. -### OpenPGP +> **Note:** You should encrypt only the `data` section of the Kubernetes +> Secret, encrypting the `metadata`, `kind` or `apiVersion` fields is not +> supported. An easy way to do this is by appending +> `--encrypted-regex '^(data|stringData)$'` to your `sops --encrypt` command. -Generate a GPG key **without passphrase** using [gnupg](https://www.gnupg.org/), -then use `sops` to encrypt a Kubernetes secret: +### Decryption Secret reference -```sh -sops --pgp=FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4 \ ---encrypt --encrypted-regex '^(data|stringData)$' --in-place my-secret.yaml -``` - -Commit and push the encrypted file to Git. - -> **Note** that you should encrypt only the `data` section, encrypting the Kubernetes -> secret metadata, kind or apiVersion is not supported by kustomize-controller. - -Create a secret in the `default` namespace with the OpenPGP private key, -the key name must end with `.asc` to be detected as an OpenPGP key: - -```sh -gpg --export-secret-keys --armor FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4 | -kubectl -n default create secret generic sops-gpg \ ---from-file=sops.asc=/dev/stdin -``` - -Configure decryption by referring the private key secret: +To configure what keys must be used for decryption, a `.decryption.secretRef` +can be specified with a reference to a Secret in the same namespace as the +Kustomization. ```yaml +--- apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: - name: my-secrets + name: sops-encrypted namespace: default spec: interval: 5m path: "./" sourceRef: kind: GitRepository - name: my-secrets + name: repository-with-secrets decryption: provider: sops secretRef: - name: sops-pgp + name: sops-keys ``` -### Age +The Secret's `.data` section is expected to contain entries with decryption +keys (for age and OpenPGP), or credentials (for any of the supported provider +implementations). The controller identifies the type of the entry by the suffix +of the key (e.g. `.agekey`), or a fixed key (e.g. `sops.vault-token`). -Generate an age key with [age](https://age-encryption.org) using `age-keygen`, -then use `sops` to encrypt a Kubernetes secret: +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary age private key + identity.agekey: + # Examplary Hashicorp Vault token + sops.vault-token: +``` -```console -$ age-keygen -o age.agekey -Public key: age1helqcqsh9464r8chnwc2fzj8uv7vr5ntnsft0tn45v2xtz0hpfwq98cmsg -$ sops --age=age1helqcqsh9464r8chnwc2fzj8uv7vr5ntnsft0tn45v2xtz0hpfwq98cmsg \ ---encrypt --encrypted-regex '^(data|stringData)$' --in-place my-secret.yaml +#### age Secret entry + +To specify an age private key in a Kubernetes Secret, suffix the key of the +`.data` entry with `.agekey`. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary age private key + identity.agekey: +``` + +#### OpenPGP Secret entry + +To specify an OpenPGP (passwordless) keyring in armor format in a Kubernetes +Secret, suffix the key of the `.data` entry with `.asc`. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary OpenPGP keyring + identity.asc: ``` -Commit and push the encrypted file to Git. +#### Azure Key Vault Secret entry -> **Note** that you should encrypt only the `data` section, encrypting the Kubernetes -> secret metadata, kind or apiVersion is not supported by kustomize-controller. +To specify credentials for Azure Key Vault in a Secret, append a `.data` entry +with a fixed `sops.azure-kv` key. The value can contain a variety of JSON or +YAML formats depending on the authentication method you want to utilize. -Create a secret in the `default` namespace with the age private key, -the key name must end with `.agekey` to be detected as an age key: +##### Service Principal with Secret -```sh -cat age.agekey | -kubectl -n default create secret generic sops-age \ ---from-file=age.agekey=/dev/stdin +To configure a Service Principal with Secret credentials to access the Azure +Key Vault, a JSON or YAML object with `tenantId`, `clientId` and `clientSecret` +fields must be configured as the `sops.azure-kv` value. It +optionally supports `authorityHost` to configure an authority host other than +the Azure Public Cloud endpoint. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Service Principal with Secret + sops.azure-kv: | + tenantId: some-tenant-id + clientId: some-client-id + clientSecret: some-client-secret ``` -Configure decryption by referring the private key secret: +##### Service Principal with Certificate + +To configure a Service Principal with Certificate credentials to access the +Azure Key Vault, a JSON or YAML object with `tenantId`, `clientId` and +`clientCertificate` fields must be configured as the `sops.azure-kv` value. +It optionally supports `clientCertificateSendChain` and `authorityHost` to +control the sending of the certificate chain, or to specify an authority host +other than the Azure Public Cloud endpoint. ```yaml -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 -kind: Kustomization +--- +apiVersion: v1 +kind: Secret metadata: - name: my-secrets + name: sops-keys namespace: default -spec: - interval: 5m - path: "./" - sourceRef: - kind: GitRepository - name: my-secrets - decryption: - provider: sops - secretRef: - name: sops-age +stringData: + # Exemplary Azure Service Principal with Certificate + sops.azure-kv: | + tenantId: some-tenant-id + clientId: some-client-id + clientCertificate: ``` -### HashiCorp Vault +##### `az` generated Service Principal -Export the `VAULT_ADDR` and `VAULT_TOKEN` environment variables to your shell, -then use `sops` to encrypt a Kubernetes Secret (see [HashiCorp Vault](https://www.vaultproject.io/docs/secrets/transit) -for more details on enabling the transit backend and [sops](https://github.com/mozilla/sops#encrypting-using-hashicorp-vault)). +To configure a Service Principal [generated using +`az`](https://docs.microsoft.com/en-us/azure/aks/kubernetes-service-principal?tabs=azure-cli#manually-create-a-service-principal), +the output of the command can be directly used as a `sops.azure-kv` value. -Then use `sops` to encrypt a Kubernetes Secret: +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Service Principal generated with `az` + sops.azure-kv: | + { + "appId": "559513bd-0c19-4c1a-87cd-851a26afd5fc", + "displayName": "myAKSClusterServicePrincipal", + "name": "http://myAKSClusterServicePrincipal", + "password": "e763725a-5eee-40e8-a466-dc88d980f415", + "tenant": "72f988bf-86f1-41af-91ab-2d7cd011db48" + } +``` -```console -$ export VAULT_ADDR=https://vault.example.com:8200 -$ export VAULT_TOKEN=my-token -$ sops --hc-vault-transit $VAULT_ADDR/v1/sops/keys/my-encryption-key --encrypt \ ---encrypted-regex '^(data|stringData)$' --in-place my-secret.yaml +##### Managed Identity with Client ID + +To configure a Managed Identity making use of a Client ID, a JSON or YAML +object with a `clientId` must be configured as the `sops.azure-kv` value. It +optionally supports `authorityHost` to configure an authority host other than +the Azure Public Cloud endpoint. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Managed Identity with Client ID + sops.azure-kv: | + clientId: some-client-id ``` -Commit and push the encrypted file to Git. +#### Hashicorp Vault Secret entry -> **Note** that you should encrypt only the `data` section, encrypting the Kubernetes -> secret metadata, kind or apiVersion is not supported by kustomize-controller. +To specify credentials for Hashicorp Vault in a Kubernetes Secret, append a +`.data` entry with a fixed `sops.vault-token` key and the token as value. -Create a secret in the `default` namespace with the vault token, -the key name must be `sops.vault-token` to be detected as a vault token: +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary Hashicorp Vault Secret token + sops.vault-token: +``` + +### Controller global decryption + +Other than [authentication using a Secret reference](#decryption-secret-reference), +it is possible to specify global decryption settings on the +kustomize-controller Pod. When the controller fails to find credentials on the +Kustomization object itself, it will fall back to these defaults. + +#### AWS + +While making use of the [IAM OIDC provider](https://eksctl.io/usage/iamserviceaccounts/) +on your EKS cluster, you can create an IAM Role and Service Account with access +to AWS KMS (using at least `kms:Decrypt` and `kms:DescribeKey`). Once these are +created, you can annotate the kustomize-controller Service Account with the +Role ARN, granting the controller permissions to decrypt the Secrets. ```sh -echo $VAULT_TOKEN | -kubectl -n default create secret generic sops-hcvault \ ---from-file=sops.vault-token=/dev/stdin +kubectl -n flux-system annotate serviceaccount kustomize-controller \ + --field-manager=flux-client-side-apply \ + eks.amazonaws.com/role-arn='arn:aws:iam:::role/' ``` -Configure decryption by referring the private key secret: +In addition to this, the +[general SOPS documentation around KMS AWS applies](https://github.com/mozilla/sops#27kms-aws-profiles), +allowing you to specify e.g. a `SOPS_KMS_ARN` environment variable. + +#### Azure Key Vault + +While making use of [AAD Pod Identity](https://github.com/Azure/aad-pod-identity), +you can bind a Managed Identity to Flux's kustomize-controller. Once the +`AzureIdentity` and `AzureIdentityBinding` for this are created, you can patch +the controller's Deployment with the `aadpodidbinding` label set to the +selector of the binding, and the `AZURE_AUTH_METHOD` environment variable set +to `msi`. ```yaml -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 -kind: Kustomization +--- +apiVersion: apps/v1 +kind: Deployment metadata: - name: my-secrets - namespace: default + name: kustomize-controller + namespace: flux-system spec: - interval: 5m - path: "./" - sourceRef: - kind: GitRepository - name: my-secrets - decryption: - provider: sops - secretRef: - name: sops-hcvault + template: + metadata: + labels: + aadpodidbinding: sops-akv-decryptor # match the AzureIdentityBinding selector + spec: + containers: + - name: manager + env: + - name: AZURE_AUTH_METHOD + value: msi +``` + +In addition to this, the [default SOPS Azure Key Vault flow is +followed](https://github.com/mozilla/sops#encrypting-using-azure-key-vault), +allowing you to specify a variety of other environment variables. + +#### GCP KMS + +While making use of Google Cloud Platform, the [`GOOGLE_APPLICATION_CREDENTIALS` +environment variable](https://cloud.google.com/docs/authentication/production) +is automatically taken into account. +[Granting permissions](https://cloud.google.com/kms/docs/reference/permissions-and-roles) +to the Service Account attached to this will therefore be sufficient to decrypt +data. When running outside GCP, it is possible to manually patch the +kustomize-controller Deployment with a valid set of (mounted) credentials. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + spec: + containers: + - name: manager + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/gcp/credentials.json + volumeMounts: + - name: gcp-credentials + mountPath: /var/gcp/ + readOnly: true + volumes: + - name: gcp-credentials + secret: + secretName: mysecret + items: + - key: credentials + path: credentials.json ``` + +#### Hashicorp Vault + +To configure a global default for Hashicorp Vault, patch the controller's +Deployment with a `VAULT_TOKEN` environment variable. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + spec: + containers: + - name: manager + env: + - name: VAULT_TOKEN + value: +``` + ### Kustomize secretGenerator SOPS encrypted data can be stored as a base64 encoded Secret, diff --git a/go.mod b/go.mod index 9468406b..6a373bc0 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,12 @@ replace github.com/fluxcd/kustomize-controller/api => ./api require ( filippo.io/age v1.0.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.1 + github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.3.0 github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 github.com/cyphar/filepath-securejoin v0.2.2 + github.com/dimchansky/utfbom v1.1.1 github.com/drone/envsubst v1.0.3-0.20200804185402-58bc65f69603 github.com/fluxcd/kustomize-controller/api v0.21.1 github.com/fluxcd/pkg/apis/acl v0.0.3 @@ -40,17 +44,20 @@ require ( require ( cloud.google.com/go v0.99.0 // indirect github.com/Azure/azure-sdk-for-go v31.2.0+incompatible // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.21 // indirect + github.com/Azure/go-autorest/autorest v0.11.19 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.14 // indirect - github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect - github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect + github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect + github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect github.com/Microsoft/go-winio v0.4.14 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect @@ -58,31 +65,30 @@ require ( github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/armon/go-metrics v0.3.10 // indirect github.com/armon/go-radix v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.37.19 // indirect + github.com/aws/aws-sdk-go v1.37.18 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect - github.com/containerd/continuity v0.2.1 // indirect + github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dimchansky/utfbom v1.1.1 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/color v1.13.0 // indirect - github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect + github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/go-errors/errors v1.4.1 // indirect + github.com/go-errors/errors v1.0.1 // indirect github.com/go-logr/logr v1.2.2 // indirect github.com/go-logr/zapr v1.2.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect - github.com/go-test/deep v1.0.8 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.1+incompatible // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -107,10 +113,10 @@ require ( github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.2 // indirect - github.com/hashicorp/go-version v1.3.0 // indirect + github.com/hashicorp/go-version v1.2.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcl v1.0.1-vault-3 // indirect - github.com/hashicorp/vault/sdk v0.3.1-0.20211209192327-a0822e64eae0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/vault/sdk v0.3.0 // indirect github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect github.com/imdario/mergo v0.3.12 // indirect @@ -118,6 +124,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.2.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.6 // indirect @@ -126,7 +133,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.0 // indirect + github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect @@ -137,10 +144,11 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/oklog/run v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/runc v0.1.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.1 // indirect @@ -159,7 +167,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect @@ -172,7 +180,7 @@ require ( google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/urfave/cli.v1 v1.20.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect @@ -186,10 +194,10 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect ) -// pin kustomize to v4.5.2 +// pin kustomize to v4.4.1 replace ( - sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.11.2 - sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.13.3 + sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.10.1 + sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.13.0 ) // Fix CVE-2021-30465 diff --git a/go.sum b/go.sum index 913bed35..0791c23d 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -58,6 +57,21 @@ filippo.io/edwards25519 v1.0.0-alpha.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCO filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/Azure/azure-sdk-for-go v31.2.0+incompatible h1:kZFnTLmdQYNGfakatSivKHUfUnDZhqNdchHD4oIhp5k= github.com/Azure/azure-sdk-for-go v31.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.20.0/go.mod h1:ZPW/Z0kLCTdDZaDbYTetxc9Cxl/2lNqxYHYNOF2bti0= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.0/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 h1:qoVeMsc9/fh/yhxVaA0obYjVH/oI/ihrOoMwsLS9KSA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.0/go.mod h1:TmXReXZ9yPp5D5TBRMTAtyz+UyOl15Py4hL5E5p6igQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.1 h1:RxemzI2cHD0A8WyMqHu/UnDjfpGES/cmjtPbQoktWqs= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.1/go.mod h1:+nVKciyKD2J9TyVcEQ82Bo9b+3F92PiQfHrIE/zqLqM= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.1/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.1 h1:sLZ/Y+P/5RRtsXWylBjB5lkgixYfm0MQPiwrSX//JSo= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.1/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.3.0 h1:FVbZiAs9cncAB9eIUwDrfBA2PfJIMeTcdMxy6W2nRMo= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.3.0/go.mod h1:Klp8aJcaCELXQHa/Cg0rFFIFlE0EjOUAzt9x1cB00TY= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1 h1:lirjIOHv5RrmDbZXw9lUz/fY68uU05qR4uIef58WMvQ= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1/go.mod h1:j1J9XXIo/eXD7YSrr73sYZTEY/AQ0+/Q6Aa96z1e2j8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= @@ -66,20 +80,17 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.21 h1:w77zY/9RnUAWcIQyDC0Fc89mCvwftR8F+zsR/OH6enk= -github.com/Azure/go-autorest/autorest v0.11.21/go.mod h1:Do/yuMSW/13ayUkcVREpsMHGG+MvV81uzSCFgYPj4tM= +github.com/Azure/go-autorest/autorest v0.11.19 h1:7/IqD2fEYVha1EPeaiytVKhzmPV223pfkRIQUGOK2IE= +github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.14 h1:G8hexQdV5D4khOXrWG2YuLCFKhWYmWD8bHYaXN5ophk= github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 h1:YgO/vSnJEc76NLw2ecIXvXa8bDWiqf1pOJzARAoZsYU= github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 h1:TzPg6B6fTZ0G1zBf3T54aI7p3cAT6u//TOXGPmFMOXg= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= @@ -90,20 +101,19 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 h1:WVsrXCnHlDDX8ls+tootqRE87/hL9S/g4ewig9RsD/c= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -142,9 +152,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.37.18 h1:SRdWLg+DqMFWX8HB3UvXyAoZpw9IDIUYnSTwgzOYbqg= github.com/aws/aws-sdk-go v1.37.18/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.37.19 h1:/xKHoSsYfH9qe16pJAHIjqTVpMM2DRSsEt8Ok1bzYiw= -github.com/aws/aws-sdk-go v1.37.19/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -196,9 +205,8 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.2.1 h1:/EeEo2EtN3umhbbgCveyjifoMYg0pS+nMMEemaYw634= -github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -225,6 +233,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -284,9 +294,8 @@ github.com/fluxcd/pkg/untar v0.1.0/go.mod h1:aGswNyzB1mlz/T/kpOS58mITBMxMKc9tlJB github.com/fluxcd/source-controller/api v0.21.2 h1:J0S5NN4V8FPLrkSMXIUoUvj1X/RuTpVJSjIRF414wmc= github.com/fluxcd/source-controller/api v0.21.2/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= -github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= @@ -300,9 +309,8 @@ github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSy github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-errors/errors v1.4.1 h1:IvVlgbzSsaUNudsw5dcXSzF3EWyXTi5XrAdngnuhRyg= -github.com/go-errors/errors v1.4.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -333,9 +341,8 @@ github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -343,6 +350,10 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -518,17 +529,15 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= -github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-vault-3 h1:V95v5KSTu6DB5huDSKiq4uAfILEuNigK/+qPET6H/Mg= -github.com/hashicorp/hcl v1.0.1-vault-3/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= @@ -543,9 +552,8 @@ github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoI github.com/hashicorp/vault/api v1.3.0 h1:uDy39PLSvy6gtKyjOCRPizy2QdFiIYSWBR2pxCEzYL8= github.com/hashicorp/vault/api v1.3.0/go.mod h1:EabNQLI0VWbWoGlA+oBLC8PXmR9D60aUVgQGvangFWQ= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/vault/sdk v0.3.0 h1:kR3dpxNkhh/wr6ycaJYqp6AFT/i2xaftbfnwZduTKEY= github.com/hashicorp/vault/sdk v0.3.0/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= -github.com/hashicorp/vault/sdk v0.3.1-0.20211209192327-a0822e64eae0 h1:bFbj+/yH2Qs3GBbyR48Yde0nYA19FEn1A0jS5a0Jjbo= -github.com/hashicorp/vault/sdk v0.3.1-0.20211209192327-a0822e64eae0/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= @@ -599,6 +607,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= @@ -641,9 +651,8 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= -github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -668,8 +677,10 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -724,6 +735,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -840,7 +853,6 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -923,12 +935,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1003,6 +1016,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1017,9 +1031,11 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= @@ -1086,7 +1102,6 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1143,6 +1158,7 @@ golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1424,9 +1440,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= @@ -1511,12 +1526,12 @@ sigs.k8s.io/controller-runtime v0.11.1/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eM sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/kustomize/api v0.11.2 h1:6YvCJHFDwsLwAX7zNHBxMZi3k7dGIXI8G9l0saYQI0E= -sigs.k8s.io/kustomize/api v0.11.2/go.mod h1:GZuhith5YcqxIDe0GnRJNx5xxPTjlwaLTt/e+ChUtJA= +sigs.k8s.io/kustomize/api v0.10.1 h1:KgU7hfYoscuqag84kxtzKdEC3mKMb99DPI3a0eaV1d0= +sigs.k8s.io/kustomize/api v0.10.1/go.mod h1:2FigT1QN6xKdcnGS2Ppp1uIWrtWN28Ms8A3OZUZhwr8= sigs.k8s.io/kustomize/cmd/config v0.10.2/go.mod h1:K2aW7nXJ0AaT+VA/eO0/dzFLxmpFcTzudmAgDwPY1HQ= sigs.k8s.io/kustomize/kustomize/v4 v4.4.1/go.mod h1:qOKJMMz2mBP+vcS7vK+mNz4HBLjaQSWRY22EF6Tb7Io= -sigs.k8s.io/kustomize/kyaml v0.13.3 h1:tNNQIC+8cc+aXFTVg+RtQAOsjwUdYBZRAgYOVI3RBc4= -sigs.k8s.io/kustomize/kyaml v0.13.3/go.mod h1:/ya3Gk4diiQzlE4mBh7wykyLRFZNvqlbh+JnwQ9Vhrc= +sigs.k8s.io/kustomize/kyaml v0.13.0 h1:9c+ETyNfSrVhxvphs+K2dzT3dh5oVPPEqPOE/cUpScY= +sigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= diff --git a/internal/sops/azkv/keysource.go b/internal/sops/azkv/keysource.go new file mode 100644 index 00000000..edddb946 --- /dev/null +++ b/internal/sops/azkv/keysource.go @@ -0,0 +1,218 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +package azkv + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "io/ioutil" + "time" + "unicode/utf16" + + "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/keyvault/azkeys/crypto" + "github.com/dimchansky/utfbom" + "sigs.k8s.io/yaml" +) + +// MasterKey is an Azure Key Vault key used to encrypt and decrypt SOPS' data key. +// The underlying authentication token can be configured using AADConfig. +type MasterKey struct { + VaultURL string + Name string + Version string + + EncryptedKey string + CreationDate time.Time + + token azcore.TokenCredential +} + +// LoadAADConfigFromBytes attempts to load the given bytes into the given AADConfig. +// By first decoding it if UTF-16, and then unmarshalling it into the given struct. +// It returns an error for any failure. +func LoadAADConfigFromBytes(b []byte, s *AADConfig) error { + b, err := decode(b) + if err != nil { + return fmt.Errorf("failed to decode Azure authentication file bytes: %w", err) + } + if err = yaml.Unmarshal(b, s); err != nil { + err = fmt.Errorf("failed to unmarshal Azure authentication file: %w", err) + } + return err +} + +// AADConfig contains the selection of fields from an Azure authentication file +// required for Active Directory authentication. +type AADConfig struct { + AZConfig + TenantID string `json:"tenantId,omitempty"` + ClientID string `json:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty"` + ClientCertificate string `json:"clientCertificate,omitempty"` + ClientCertificatePassword string `json:"clientCertificatePassword,omitempty"` + ClientCertificateSendChain bool `json:"clientCertificateSendChain,omitempty"` + AuthorityHost string `json:"authorityHost,omitempty"` +} + +// AZConfig contains the Service Principal fields as generated by `az`. +// Ref: https://docs.microsoft.com/en-us/azure/aks/kubernetes-service-principal?tabs=azure-cli#manually-create-a-service-principal +type AZConfig struct { + AppID string `json:"appId,omitempty"` + Tenant string `json:"tenant,omitempty"` + Password string `json:"password,omitempty"` +} + +// SetToken attempts to configure the token on the MasterKey using the +// AADConfig values. It detects credentials in the following order: +// +// - azidentity.ClientSecretCredential when `tenantId`, `clientId` and +// `clientSecret` fields are found. +// - azidentity.ClientCertificateCredential when `tenantId`, +// `clientCertificate` (and optionally `clientCertificatePassword`) fields +// are found. +// - azidentity.ClientSecretCredential when AZConfig fields are found. +// - azidentity.ManagedIdentityCredential for a User ID, when a `clientId` +// field but no `tenantId` is found. +// +// If no set of credentials is found or the azcore.TokenCredential can not be +// created, an error is returned. +func (s *AADConfig) SetToken(key *MasterKey) error { + if s == nil || key == nil { + return nil + } + + var err error + if s.TenantID != "" && s.ClientID != "" { + if s.ClientSecret != "" { + key.token, err = azidentity.NewClientSecretCredential(s.TenantID, s.ClientID, s.ClientSecret, &azidentity.ClientSecretCredentialOptions{ + AuthorityHost: s.GetAuthorityHost(), + }) + return err + } + if s.ClientCertificate != "" { + certs, pk, err := azidentity.ParseCertificates([]byte(s.ClientCertificate), []byte(s.ClientCertificatePassword)) + key.token, err = azidentity.NewClientCertificateCredential(s.TenantID, s.ClientID, certs, pk, &azidentity.ClientCertificateCredentialOptions{ + SendCertificateChain: s.ClientCertificateSendChain, + AuthorityHost: s.GetAuthorityHost(), + }) + return err + } + } + if s.Tenant != "" && s.AppID != "" && s.Password != "" { + key.token, err = azidentity.NewClientSecretCredential(s.Tenant, s.AppID, s.Password, &azidentity.ClientSecretCredentialOptions{ + AuthorityHost: s.GetAuthorityHost(), + }) + return err + } + if s.ClientID != "" { + key.token, err = azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ + ID: azidentity.ClientID(s.ClientID), + }) + return err + } + + return fmt.Errorf("invalid data: requires a '%s' field, a combination of '%s', '%s' and '%s', or '%s', '%s' and '%s'", + "clientId", "tenantId", "clientId", "clientSecret", "tenantId", "clientId", "clientCertificate") +} + +// GetAuthorityHost returns the AuthorityHost, or the Azure Public Cloud +// default. +func (s *AADConfig) GetAuthorityHost() azidentity.AuthorityHost { + if s.AuthorityHost != "" { + return azidentity.AuthorityHost(s.AuthorityHost) + } + return azidentity.AzurePublicCloud +} + +// EncryptedDataKey returns the encrypted data key this master key holds. +func (key *MasterKey) EncryptedDataKey() []byte { + return []byte(key.EncryptedKey) +} + +// SetEncryptedDataKey sets the encrypted data key for this master key. +func (key *MasterKey) SetEncryptedDataKey(enc []byte) { + key.EncryptedKey = string(enc) +} + +// Encrypt takes a SOPS data key, encrypts it with Key Vault and stores the result in the EncryptedKey field. +func (key *MasterKey) Encrypt(dataKey []byte) error { + c, err := crypto.NewClient(key.ToString(), key.token, nil) + if err != nil { + return fmt.Errorf("failed to construct client to encrypt data: %w", err) + } + resp, err := c.Encrypt(context.Background(), crypto.AlgorithmRSAOAEP256, dataKey, nil) + if err != nil { + return fmt.Errorf("failed to encrypt data: %w", err) + } + key.EncryptedKey = string(resp.Result) + return nil +} + +// EncryptIfNeeded encrypts the provided SOPS' data key and encrypts it if it hasn't been encrypted yet. +func (key *MasterKey) EncryptIfNeeded(dataKey []byte) error { + if key.EncryptedKey == "" { + return key.Encrypt(dataKey) + } + return nil +} + +// Decrypt decrypts the EncryptedKey field with Azure Key Vault and returns the result. +func (key *MasterKey) Decrypt() ([]byte, error) { + c, err := crypto.NewClient(key.ToString(), key.token, nil) + if err != nil { + return nil, fmt.Errorf("failed to construct client to decrypt data: %w", err) + } + resp, err := c.Decrypt(context.Background(), crypto.AlgorithmRSAOAEP256, []byte(key.EncryptedKey), nil) + if err != nil { + return nil, fmt.Errorf("failed to decrypt data: %w", err) + } + return resp.Result, nil +} + +// NeedsRotation returns whether the data key needs to be rotated or not. +func (key *MasterKey) NeedsRotation() bool { + return time.Since(key.CreationDate) > (time.Hour * 24 * 30 * 6) +} + +// ToString converts the key to a string representation. +func (key *MasterKey) ToString() string { + return fmt.Sprintf("%s/keys/%s/%s", key.VaultURL, key.Name, key.Version) +} + +// ToMap converts the MasterKey to a map for serialization purposes. +func (key MasterKey) ToMap() map[string]interface{} { + out := make(map[string]interface{}) + out["vaultUrl"] = key.VaultURL + out["key"] = key.Name + out["version"] = key.Version + out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339) + out["enc"] = key.EncryptedKey + return out +} + +func decode(b []byte) ([]byte, error) { + reader, enc := utfbom.Skip(bytes.NewReader(b)) + switch enc { + case utfbom.UTF16LittleEndian: + u16 := make([]uint16, (len(b)/2)-1) + err := binary.Read(reader, binary.LittleEndian, &u16) + if err != nil { + return nil, err + } + return []byte(string(utf16.Decode(u16))), nil + case utfbom.UTF16BigEndian: + u16 := make([]uint16, (len(b)/2)-1) + err := binary.Read(reader, binary.BigEndian, &u16) + if err != nil { + return nil, err + } + return []byte(string(utf16.Decode(u16))), nil + } + return ioutil.ReadAll(reader) +} diff --git a/internal/sops/azkv/keysource_test.go b/internal/sops/azkv/keysource_test.go new file mode 100644 index 00000000..1601f768 --- /dev/null +++ b/internal/sops/azkv/keysource_test.go @@ -0,0 +1,227 @@ +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package azkv + +import ( + "bytes" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "math/big" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + . "github.com/onsi/gomega" +) + +func TestLoadAADConfigFromBytes(t *testing.T) { + tests := []struct { + name string + b []byte + want AADConfig + wantErr bool + }{ + { + name: "Service Principal with Secret", + b: []byte(`tenantId: "some-tenant-id" +clientId: "some-client-id" +clientSecret: "some-client-secret"`), + want: AADConfig{ + TenantID: "some-tenant-id", + ClientID: "some-client-id", + ClientSecret: "some-client-secret", + }, + }, + { + name: "Service Principal with Certificate", + b: []byte(`tenantId: "some-tenant-id" +clientId: "some-client-id" +clientCertificate: "some-client-certificate"`), + want: AADConfig{ + TenantID: "some-tenant-id", + ClientID: "some-client-id", + ClientCertificate: "some-client-certificate", + }, + }, + { + name: "Managed Identity with Client ID", + b: []byte(`clientId: "some-client-id"`), + want: AADConfig{ + ClientID: "some-client-id", + }, + }, + { + name: "Service Principal with Secret from az CLI", + b: []byte(`{"appId": "some-app-id", "tenant": "some-tenant", "password": "some-password"}`), + want: AADConfig{ + AZConfig: AZConfig{ + AppID: "some-app-id", + Tenant: "some-tenant", + Password: "some-password", + }, + }, + }, + { + name: "Authority host", + b: []byte(`{"authorityHost": "https://example.com"}`), + want: AADConfig{ + AuthorityHost: "https://example.com", + }, + }, + { + name: "invalid", + b: []byte("some string"), + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + + got := AADConfig{} + err := LoadAADConfigFromBytes(tt.b, &got) + if tt.wantErr { + g.Expect(err).To(HaveOccurred()) + g.Expect(got).To(Equal(tt.want)) + return + } + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(got).To(Equal(tt.want)) + }) + } +} + +func TestAADConfig_SetToken(t *testing.T) { + tlsMock := validTls(t) + + tests := []struct { + name string + config AADConfig + want azcore.TokenCredential + wantErr bool + }{ + { + name: "Service Principal with Secret", + config: AADConfig{ + TenantID: "some-tenant-id", + ClientID: "some-client-id", + ClientSecret: "some-client-secret", + }, + want: &azidentity.ClientSecretCredential{}, + }, + { + name: "Service Principal with Certificate", + config: AADConfig{ + TenantID: "some-tenant-id", + ClientID: "some-client-id", + ClientCertificate: string(tlsMock), + }, + want: &azidentity.ClientCertificateCredential{}, + }, + { + name: "Service Principal with az CLI format", + config: AADConfig{ + AZConfig: AZConfig{ + AppID: "some-app-id", + Tenant: "some-tenant", + Password: "some-password", + }, + }, + want: &azidentity.ClientSecretCredential{}, + }, + { + name: "Managed Identity with Client ID", + config: AADConfig{ + ClientID: "some-client-id", + }, + want: &azidentity.ManagedIdentityCredential{}, + }, + { + name: "empty config", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + + key := MasterKey{} + got := tt.config.SetToken(&key) + + if tt.wantErr { + g.Expect(got).To(HaveOccurred()) + g.Expect(key.token).To(BeNil()) + return + } + + g.Expect(got).ToNot(HaveOccurred()) + g.Expect(key.token).ToNot(BeNil()) + g.Expect(key.token).To(BeAssignableToTypeOf(tt.want)) + }) + } +} + +func TestAADConfig_SetToken_Nil(t *testing.T) { + g := NewWithT(t) + + var c *AADConfig + g.Expect(c.SetToken(&MasterKey{})).To(Succeed()) + g.Expect((&AADConfig{}).SetToken(nil)).To(Succeed()) +} + +func TestAADConfig_GetAuthorityHost(t *testing.T) { + g := NewWithT(t) + + g.Expect((&AADConfig{}).GetAuthorityHost()).To(Equal(azidentity.AzurePublicCloud)) + g.Expect((&AADConfig{AuthorityHost: "https://example.com"}).GetAuthorityHost()).To(Equal(azidentity.AuthorityHost("https://example.com"))) +} + +func validTls(t *testing.T) []byte { + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal("Private key cannot be created.", err.Error()) + } + + out := bytes.NewBuffer(nil) + + var privateKey = &pem.Block{ + Type: "PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), + } + if err = pem.Encode(out, privateKey); err != nil { + t.Fatal("Private key cannot be PEM encoded.", err.Error()) + } + + certTemplate := x509.Certificate{ + SerialNumber: big.NewInt(1337), + } + cert, err := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, &key.PublicKey, key) + if err != nil { + t.Fatal("Certificate cannot be created.", err.Error()) + } + var certificate = &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert, + } + if err = pem.Encode(out, certificate); err != nil { + t.Fatal("Certificate cannot be PEM encoded.", err.Error()) + } + + return out.Bytes() +} diff --git a/internal/sops/keyservice/server.go b/internal/sops/keyservice/server.go index 3007c7cd..bb6df590 100644 --- a/internal/sops/keyservice/server.go +++ b/internal/sops/keyservice/server.go @@ -13,6 +13,7 @@ import ( "google.golang.org/grpc/status" "github.com/fluxcd/kustomize-controller/internal/sops/age" + "github.com/fluxcd/kustomize-controller/internal/sops/azkv" "github.com/fluxcd/kustomize-controller/internal/sops/hcvault" "github.com/fluxcd/kustomize-controller/internal/sops/pgp" ) @@ -37,17 +38,22 @@ type Server struct { // VaultToken configures the Vault token used by the server. VaultToken string + // AzureAADConfig configures the Azure Active Directory settings used + // by the server. + AzureAADConfig *azkv.AADConfig + // DefaultServer is the server used for any other request than a PGP // or age encryption/decryption. DefaultServer keyservice.KeyServiceServer } -func NewServer(prompt bool, homeDir, vaultToken string, agePrivateKeys []string) keyservice.KeyServiceServer { +func NewServer(prompt bool, homeDir, vaultToken string, agePrivateKeys []string, azureCfg *azkv.AADConfig) keyservice.KeyServiceServer { server := &Server{ Prompt: prompt, HomeDir: homeDir, AgePrivateKeys: agePrivateKeys, VaultToken: vaultToken, + AzureAADConfig: azureCfg, DefaultServer: &keyservice.Server{ Prompt: prompt, }, @@ -100,7 +106,36 @@ func (ks *Server) decryptWithVault(key *keyservice.VaultKey, ciphertext []byte) } vaultKey.EncryptedKey = string(ciphertext) plaintext, err := vaultKey.Decrypt() - return []byte(plaintext), err + return plaintext, err +} + +func (ks *Server) encryptWithAzureKeyvault(key *keyservice.AzureKeyVaultKey, plaintext []byte) ([]byte, error) { + azureKey := azkv.MasterKey{ + VaultURL: key.VaultUrl, + Name: key.Name, + Version: key.Version, + } + if err := ks.AzureAADConfig.SetToken(&azureKey); err != nil { + return nil, fmt.Errorf("failed to set token for Azure encryption request: %w", err) + } + if err := azureKey.Encrypt(plaintext); err != nil { + return nil, err + } + return []byte(azureKey.EncryptedKey), nil +} + +func (ks *Server) decryptWithAzureKeyvault(key *keyservice.AzureKeyVaultKey, ciphertext []byte) ([]byte, error) { + azureKey := azkv.MasterKey{ + VaultURL: key.VaultUrl, + Name: key.Name, + Version: key.Version, + } + if err := ks.AzureAADConfig.SetToken(&azureKey); err != nil { + return nil, fmt.Errorf("failed to set token for Azure decryption request: %w", err) + } + azureKey.EncryptedKey = string(ciphertext) + plaintext, err := azureKey.Decrypt() + return plaintext, err } // Encrypt takes an encrypt request and encrypts the provided plaintext with the provided key, @@ -126,6 +161,19 @@ func (ks Server) Encrypt(ctx context.Context, response = &keyservice.EncryptResponse{ Ciphertext: ciphertext, } + case *keyservice.Key_AzureKeyvaultKey: + // Fallback to default server if no custom settings are configured + // to ensure backwards compatibility with global configurations + if ks.AzureAADConfig == nil { + return ks.Encrypt(ctx, req) + } + ciphertext, err := ks.encryptWithAzureKeyvault(k.AzureKeyvaultKey, req.Plaintext) + if err != nil { + return nil, err + } + response = &keyservice.EncryptResponse{ + Ciphertext: ciphertext, + } default: return ks.DefaultServer.Encrypt(ctx, req) } @@ -200,6 +248,19 @@ func (ks Server) Decrypt(ctx context.Context, response = &keyservice.DecryptResponse{ Plaintext: plaintext, } + case *keyservice.Key_AzureKeyvaultKey: + // Fallback to default server if no custom settings are configured + // to ensure backwards compatibility with global configurations + if ks.AzureAADConfig == nil { + return ks.Decrypt(ctx, req) + } + plaintext, err := ks.decryptWithAzureKeyvault(k.AzureKeyvaultKey, req.Ciphertext) + if err != nil { + return nil, err + } + response = &keyservice.DecryptResponse{ + Plaintext: plaintext, + } default: return ks.DefaultServer.Decrypt(ctx, req) } diff --git a/main.go b/main.go index 0eafd6de..c1a11ac1 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( flag "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth/azure" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" "sigs.k8s.io/cli-utils/pkg/kstatus/polling" ctrl "sigs.k8s.io/controller-runtime"