From 92a5a4f90a18eed8f0bc1fadcec487eec32c54f9 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 20 Oct 2021 21:16:07 -0500 Subject: [PATCH 01/70] test --- acceptance/framework/vault/vault_cluster.go | 312 ++++++++++++++++++++ acceptance/go.mod | 3 +- acceptance/go.sum | 208 +++++++++++-- acceptance/tests/vault/main_test.go | 15 + acceptance/tests/vault/vault_test.go | 133 +++++++++ 5 files changed, 650 insertions(+), 21 deletions(-) create mode 100644 acceptance/framework/vault/vault_cluster.go create mode 100644 acceptance/tests/vault/main_test.go create mode 100644 acceptance/tests/vault/vault_test.go diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go new file mode 100644 index 0000000000..e582eabf34 --- /dev/null +++ b/acceptance/framework/vault/vault_cluster.go @@ -0,0 +1,312 @@ +package vault + +import ( + "context" + "encoding/json" + "fmt" + corev1 "k8s.io/api/core/v1" + "strings" + "testing" + "time" + + "github.com/gruntwork-io/terratest/modules/helm" + terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" + terratestLogger "github.com/gruntwork-io/terratest/modules/logger" + "github.com/hashicorp/consul-k8s/acceptance/framework/config" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/sdk/testutil/retry" + "k8s.io/apimachinery/pkg/api/errors" + // https://github.com/hashicorp/vault-examples/tree/main/go + vapi "github.com/hashicorp/vault/api" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +// Cluster represents a consul cluster object +type Cluster interface { + Create(t *testing.T) + Bootstrap(t *testing.T, ctx environment.TestContext) + Destroy(t *testing.T) + SetupVaultClient(t *testing.T) *vapi.Client + VaultClient(t *testing.T) *vapi.Client +} + +const ( + vaultNS = "default" +) + +// VaultCluster +type VaultCluster struct { + ctx environment.TestContext + namespace string + + vaultHelmOptions *helm.Options + vaultReleaseName string + vaultClient *vapi.Client + rootToken string + + kubectlOptions *terratestk8s.KubectlOptions + values map[string]string + + kubernetesClient kubernetes.Interface + kubeConfig string + kubeContext string + + noCleanupOnFailure bool + debugDirectory string + logger terratestLogger.TestLogger +} + +// NewHelmCluster installs Vault into Kubernetes using Helm. +func NewHelmCluster( + t *testing.T, + helmValues map[string]string, + ctx environment.TestContext, + cfg *config.TestConfig, + releaseName string, +) Cluster { + + logger := terratestLogger.New(logger.TestLogger{}) + + kopts := ctx.KubectlOptions(t) + kopts.Namespace = vaultNS + + vaultHelmOpts := &helm.Options{ + SetValues: defaultVaultValues(), + KubectlOptions: kopts, + Logger: logger, + } + + return &VaultCluster{ + ctx: ctx, + vaultHelmOptions: vaultHelmOpts, + kubectlOptions: kopts, + namespace: cfg.KubeNamespace, + values: helmValues, + kubernetesClient: ctx.KubernetesClient(t), + kubeConfig: cfg.Kubeconfig, + kubeContext: cfg.KubeContext, + noCleanupOnFailure: cfg.NoCleanupOnFailure, + debugDirectory: cfg.DebugDirectory, + logger: logger, + vaultReleaseName: releaseName, + } +} + +func (v *VaultCluster) VaultClient(t *testing.T) *vapi.Client { return v.vaultClient } + +// checkForPriorInstallations checks if there is an existing Helm release +// for this Helm chart already installed. If there is, it fails the tests. +func (v *VaultCluster) checkForPriorVaultInstallations(t *testing.T) { + t.Helper() + + var helmListOutput string + // Check if there's an existing cluster and fail if there is one. + // We may need to retry since this is the first command run once the Kube + // cluster is created and sometimes the API server returns errors. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { + var err error + // NOTE: It's okay to pass in `t` to RunHelmCommandAndGetOutputE despite being in a retry + // because we're using RunHelmCommandAndGetOutputE (not RunHelmCommandAndGetOutput) so the `t` won't + // get used to fail the test, just for logging. + helmListOutput, err = helm.RunHelmCommandAndGetOutputE(t, v.vaultHelmOptions, "list", "--output", "json") + require.NoError(r, err) + }) + + var installedReleases []map[string]string + + err := json.Unmarshal([]byte(helmListOutput), &installedReleases) + require.NoError(t, err, "unmarshalling %q", helmListOutput) + + for _, r := range installedReleases { + require.NotContains(t, r["chart"], "vault", fmt.Sprintf("detected an existing installation of Vault %s, release name: %s", r["chart"], r["name"])) + } + /* + // TODO: Copied this from Consul Cluster implementation, is this necessary for vault? + // Wait for all pods in the "default" namespace to exit. A previous + // release may not be listed by Helm but its pods may still be terminating. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { + consulPods, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) + require.NoError(r, err) + if len(consulPods.Items) > 0 { + var podNames []string + for _, p := range consulPods.Items { + podNames = append(podNames, p.Name) + } + r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) + } + }) + */ +} + +// Setup Vault Client returns a Vault Client. +// TODO: We need to support Vault with TLS enabled. +func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { + t.Helper() + + config := vapi.DefaultConfig() + localPort := terratestk8s.GetAvailablePort(t) + remotePort := 8200 // use non-secure by default + + serverPod := fmt.Sprintf("%s-vault-0", v.vaultReleaseName) + tunnel := terratestk8s.NewTunnelWithLogger( + v.vaultHelmOptions.KubectlOptions, + terratestk8s.ResourceTypePod, + serverPod, + localPort, + remotePort, + v.logger) + + // Retry creating the port forward since it can fail occasionally. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { + // NOTE: It's okay to pass in `t` to ForwardPortE despite being in a retry + // because we're using ForwardPortE (not ForwardPort) so the `t` won't + // get used to fail the test, just for logging. + require.NoError(r, tunnel.ForwardPortE(t)) + }) + + t.Cleanup(func() { + tunnel.Close() + }) + + config.Address = fmt.Sprintf("http://127.0.0.1:%d", localPort) + consulClient, err := vapi.NewClient(config) + require.NoError(t, err) + + return consulClient +} + +// Bootstrap runs Init, Unseals the Vault installation +// and then does the setup of Auth Methods and Enables Secrets Engines. +func (v *VaultCluster) Bootstrap(t *testing.T, ctx environment.TestContext) { + + v.vaultClient = v.SetupVaultClient(t) + + // Init the Vault Cluster and store the rootToken. + initResp, err := v.vaultClient.Sys().Init(&vapi.InitRequest{ + // Init the cluster and only request a single Secret to be used for Unsealing. + SecretShares: 1, + SecretThreshold: 1, + StoredShares: 1, + RecoveryShares: 0, + RecoveryThreshold: 0, + }) + if err != nil { + t.Fatal("unable to init Vault cluster", "err", err) + } + // Store the RootToken and set the client to use it so it can Unseal and finish bootstrapping. + v.rootToken = initResp.RootToken + v.vaultClient.SetToken(v.rootToken) + + // Unseal the Vault Cluster using the Unseal Keys from Init(). + sealResp, err := v.vaultClient.Sys().Unseal(initResp.KeysB64[0]) + if err != nil { + t.Fatal("unable to unseal Vault cluster", "err", err) + } + require.Equal(t, false, sealResp.Sealed) + + // Enable the KV-V2 Secrets engine + err = v.vaultClient.Sys().Mount("consul", &vapi.MountInput{ + Type: "kv-v2", + Config: vapi.MountConfigInput{}, + }) + if err != nil { + t.Fatal("unable to mount kv-v2 secrets engine", "err", err) + } + // TODO: Enable the PKI Secrets Engine + + // Enable Kube Auth. + err = v.vaultClient.Sys().EnableAuthWithOptions("kubernetes", &vapi.EnableAuthOptions{ + Type: "kubernetes", + Config: vapi.MountConfigInput{}, + }) + if err != nil { + t.Fatal("unable to enable kube auth", "err", err) + } + // We need to kubectl exec this one on the vault server: + // This is taken from https://learn.hashicorp.com/tutorials/vault/kubernetes-google-cloud-gke?in=vault/kubernetes#configure-kubernetes-authentication + cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", v.rootToken) + + v.logger.Logf(t, "updating vault kube auth config") + // TODO: figure out if this sleep can be done differently. + time.Sleep(time.Second * 30) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) + + // Create an access policy for Secrets Management, so we can create them later + /* + // TODO: Do we need this policy, because we will have to have root token (or some other priv'd) in our client + // TODO: already in order to create policies and roles. + devpolicyRule := `{ "policy": "path "consul/data/*" { capabilities = ["create", "update", "read"] } }` + err = v.vaultClient.Sys().PutPolicy("dev-root-policy", devpolicyRule) + if err != nil { + t.Fatal("unable to create secret mgmt policy", "err", err) + } + */ +} + +// Create installs Vault via Helm. +func (v *VaultCluster) Create(t *testing.T) { + t.Helper() + + // Make sure we delete the cluster if we receive an interrupt signal and + // register cleanup so that we delete the cluster when test finishes. + helpers.Cleanup(t, v.noCleanupOnFailure, func() { + v.Destroy(t) + }) + + // Fail if there are any existing installations of the Helm chart. + v.checkForPriorVaultInstallations(t) + + // step 1: install Vault + helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) + // Wait for the injector pod to become Ready. + helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, fmt.Sprintf("app.kubernetes.io/name=vault-agent-injector")) + // Wait for the Server Pod to be online, it will not be Ready because it has not been Init+Unseal'd yet, this is done + // in the Bootstrap method. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 30}, t, func(r *retry.R) { + pod, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).Get(context.Background(), fmt.Sprintf("%s-vault-0", v.vaultReleaseName), metav1.GetOptions{}) + require.NoError(r, err) + require.Equal(r, pod.Status.Phase, corev1.PodRunning) + }) + +} + +func (v *VaultCluster) Destroy(t *testing.T) { + t.Helper() + + k8s.WritePodsDebugInfoIfFailed(t, v.kubectlOptions, v.debugDirectory, "release="+v.vaultReleaseName) + + // Ignore the error returned by the helm delete here so that we can + // always idempotently clean up resources in the cluster. + _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, false) + // Delete PVCs. + err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.vaultHelmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: fmt.Sprintf("app.kubernetes.io/instance==data-%s-vault-0", v.vaultReleaseName)}) + require.NoError(t, err) + + // Delete any secrets that have v.releaseName in their name. + secrets, err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) + require.NoError(t, err) + for _, secret := range secrets.Items { + if strings.Contains(secret.Name, v.vaultReleaseName) { + err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).Delete(context.Background(), secret.Name, metav1.DeleteOptions{}) + if !errors.IsNotFound(err) { + require.NoError(t, err) + } + } + } +} + +func defaultVaultValues() map[string]string { + values := map[string]string{ + "server.replicas": "1", + "server.bootstrapExpect": "1", + //"ui.enabled": "true", + "injector.enabled": "true", + "global.enabled": "true", + } + return values +} diff --git a/acceptance/go.mod b/acceptance/go.mod index 5e017ccec6..0802e05d35 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -6,7 +6,8 @@ require ( github.com/gruntwork-io/terratest v0.31.2 github.com/hashicorp/consul/api v1.10.1-0.20210915232521-e0a7900f52bf github.com/hashicorp/consul/sdk v0.8.0 - github.com/stretchr/testify v1.5.1 + github.com/hashicorp/vault/api v1.2.0 + github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v2 v2.2.8 k8s.io/api v0.19.3 k8s.io/apimachinery v0.19.3 diff --git a/acceptance/go.sum b/acceptance/go.sum index ab20eec364..38c12fdd82 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -1,3 +1,4 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= 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= @@ -48,38 +49,65 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 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= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= +github.com/armon/go-metrics v0.3.3 h1:a9F4rlj7EWWrbj7BYw8J8+x+ZZkJeqzNyRk8hdPF+ro= +github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +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/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.27.1 h1:MXnqY6SlWySaZAqNnXThOvjRFdiiOuKtC6i7baFdNdU= +github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.30.27 h1:9gPjZWVDSoQrBO2AvqrWObS6KAZByfEJxQoCYo4ZfK0= +github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= @@ -95,6 +123,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -107,6 +136,7 @@ github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -124,7 +154,9 @@ github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy0 github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= @@ -132,18 +164,28 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= +github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 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/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8= +github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -158,9 +200,14 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +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/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -186,14 +233,18 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -215,6 +266,7 @@ github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyyc github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -230,31 +282,57 @@ github.com/hashicorp/consul/api v1.10.1-0.20210915232521-e0a7900f52bf/go.mod h1: github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +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-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= +github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +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-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= +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-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= 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-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +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-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +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/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.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/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/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= @@ -262,6 +340,14 @@ github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE= +github.com/hashicorp/vault/api v1.2.0 h1:ysGFc6XRGbv05NsWPzuO5VTv68Lj8jtwATxRLFOpP9s= +github.com/hashicorp/vault/api v1.2.0/go.mod h1:dAjw0T5shMnrfH7Q/Mst+LrcTKvStZBVs1PICEDpUqY= +github.com/hashicorp/vault/sdk v0.1.14-0.20200519221530-14615acda45f/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10= +github.com/hashicorp/vault/sdk v0.2.1 h1:S4O6Iv/dyKlE9AUTXGa7VOvZmsCvg36toPKgV4f2P4M= +github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/rZwaxjBkgN4U= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -270,14 +356,16 @@ github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -290,12 +378,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -321,14 +411,24 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 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-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -341,6 +441,8 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -352,14 +454,24 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +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/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/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= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -372,13 +484,21 @@ github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prY github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= @@ -389,12 +509,16 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +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= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -402,10 +526,12 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -419,10 +545,13 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= @@ -437,13 +566,17 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -451,6 +584,7 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -468,6 +602,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -480,6 +616,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -496,9 +633,12 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -521,19 +661,23 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -543,11 +687,15 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -557,8 +705,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -575,6 +724,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -582,10 +732,12 @@ golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191205215504-7b8c8591a921/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200113040837-eac381796e91 h1:OOkytthzFBKHY5EfEgLUabprb0LtJVkQtNxAQ02+UE4= golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -615,15 +767,21 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 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= @@ -632,8 +790,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= @@ -644,11 +804,15 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 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/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/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -656,9 +820,13 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/acceptance/tests/vault/main_test.go b/acceptance/tests/vault/main_test.go new file mode 100644 index 0000000000..1d3a5a5842 --- /dev/null +++ b/acceptance/tests/vault/main_test.go @@ -0,0 +1,15 @@ +package vault + +import ( + "os" + "testing" + + testsuite "github.com/hashicorp/consul-k8s/acceptance/framework/suite" +) + +var suite testsuite.Suite + +func TestMain(m *testing.M) { + suite = testsuite.NewSuite(m) + os.Exit(suite.Run()) +} diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go new file mode 100644 index 0000000000..4ee68fbb1f --- /dev/null +++ b/acceptance/tests/vault/vault_test.go @@ -0,0 +1,133 @@ +package vault + +import ( + "testing" + + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul-k8s/acceptance/framework/vault" + "github.com/stretchr/testify/require" +) + +// Installs Vault, bootstraps it with the kube auth method +// and then validates that the KV2 secrets engine is online +// and the Kube Auth Method is enabled. +func TestVault_Bootstrap(t *testing.T) { + cfg := suite.Config() + ctx := suite.Environment().DefaultContext(t) + + vaultReleaseName := helpers.RandomName() + vaultCluster := vault.NewHelmCluster(t, nil, ctx, cfg, vaultReleaseName) + vaultCluster.Create(t) + vaultCluster.Bootstrap(t, ctx) + logger.Log(t, "Finished Bootstrap") + + vaultClient := vaultCluster.VaultClient(t) + + // Write to the KV2 engine succeeds + logger.Log(t, "Creating a KV2 Secret") + params := map[string]interface{}{ + "data": map[string]interface{}{ + "test": "ABCD1234", + }, + } + _, err := vaultClient.Logical().Write("consul/data/secret/test", params) + require.NoError(t, err) + + // Auth Methods exists + authList, err := vaultClient.Sys().ListAuth() + require.NoError(t, err) + logger.Log(t, "Auth List: ", authList) + require.NotNil(t, authList["kubernetes/"]) +} + +/* +// Installs Vault, bootstraps it with secrets, policies, and kube auth method +// then creates a gossip encryption secret and uses this to bootstrap Consul +func TestVaultConsulGossipEncryptionKeyIntegration(t *testing.T) { + cfg := suite.Config() + ctx := suite.Environment().DefaultContext(t) + + vaultReleaseName := helpers.RandomName() + logger.Log(t, "Entering NewHelmCluster") + vaultCluster := vault.NewHelmCluster(t, nil, ctx, cfg, vaultReleaseName) + logger.Log(t, "Entering Create") + vaultCluster.Create(t) + // Vault is now installed in the cluster + + logger.Log(t, "Entering Bootstrap") + vaultCluster.Bootstrap(t, ctx) + logger.Log(t, "Finished Bootstrap") + + vaultClient := vaultCluster.VaultClient(t) + + logger.Log(t, "Creating the policies and secrets") + + var err error + // Create the Vault Policy for the gossip key + logger.Log(t, "Creating the gossip policy") + rules := ` +path "consul/data/secret/gossip" { + capabilities = ["read"] +}` + err = vaultClient.Sys().PutPolicy("consul-gossip", rules) + require.NoError(t, err) + + // create the auth roles for consul-server + consul-client + logger.Log(t, "Creating the gossip auth roles") + params := map[string]interface{}{ + "bound_service_account_names": "consul-consul-client", + "bound_service_account_namespaces": "default", + "policies": "consul-gossip", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-client", params) + require.NoError(t, err) + + params = map[string]interface{}{ + "bound_service_account_names": "consul-consul-server", + "bound_service_account_namespaces": "default", + "policies": "consul-gossip", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-server", params) + require.NoError(t, err) + + // Create the gossip key + logger.Log(t, "Creating the gossip secret") + params = map[string]interface{}{ + "data": map[string]interface{}{ + "gossip": "3R7oLrdpkk2V0Y7yHLizyxXeS2RtaVuy07DkU15Lhws=", + }, + } + _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) + require.NoError(t, err) + + time.Sleep(time.Second * 30) + + consulHelmValues := map[string]string{ + "server.enabled": "true", + "server.replicas": "1", + "global.imageK8S": "kschoche/consul-k8s-hashiconf", + + "connectInject.enabled": "true", + + "secretsBackend.vault.enabled": "true", + "secretsBackend.vault.consulServerRole": "consul-server", + "secretsBackend.vault.consulclientRole": "consul-client", + + "global.tls.enabled": "true", + "global.gossipEncryption.secretName": "consul/data/secret/gossip", + "global.gossipEncryption.secretKey": ".Data.data.gossip", + } + // TODO: consul-release name needs to be integrated into all of the secret names and policies above + consulReleaseName := "consul" //helpers.RandomName() + logger.Log(t, "Installing Consul") + consulCluster := consul.NewHelmCluster(t, consulHelmValues, ctx, cfg, consulReleaseName) + + consulCluster.Create(t) + + time.Sleep(time.Second * 600) + +} +*/ From 8171ec55ef60ca50289ce2cd751cf02afe28f080 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 20 Oct 2021 21:23:21 -0500 Subject: [PATCH 02/70] test --- acceptance/framework/vault/vault_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index e582eabf34..b5731bcb9b 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -264,7 +264,7 @@ func (v *VaultCluster) Create(t *testing.T) { // step 1: install Vault helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) // Wait for the injector pod to become Ready. - helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, fmt.Sprintf("app.kubernetes.io/name=vault-agent-injector")) + helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, "app.kubernetes.io/name=vault-agent-injector") // Wait for the Server Pod to be online, it will not be Ready because it has not been Init+Unseal'd yet, this is done // in the Bootstrap method. retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 30}, t, func(r *retry.R) { From 3ba20ec8ec4480dd1e77d12bcdd0769d4ac7199d Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 20 Oct 2021 22:07:32 -0500 Subject: [PATCH 03/70] change something --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index a592052168..cd6a53cda0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,6 +50,7 @@ commands: wget https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz tar -zxvf helm-v3.7.0-linux-amd64.tar.gz sudo mv linux-amd64/helm /usr/local/bin/helm + /usr/local/bin/helm repo add hashicorp https://helm.releases.hashicorp.com create-kind-clusters: parameters: From 3a0f5a3c4e34a9f9cc60fad7e00a4eafca123d35 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 21 Oct 2021 10:54:48 -0500 Subject: [PATCH 04/70] clean this up --- acceptance/framework/vault/vault_cluster.go | 71 +++++++-------- acceptance/tests/vault/vault_test.go | 99 +-------------------- 2 files changed, 37 insertions(+), 133 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index b5731bcb9b..7f02ee1dbe 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" "strings" "testing" "time" @@ -18,20 +18,31 @@ import ( "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul/sdk/testutil/retry" - "k8s.io/apimachinery/pkg/api/errors" - // https://github.com/hashicorp/vault-examples/tree/main/go vapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) -// Cluster represents a consul cluster object +// Cluster represents a vault cluster object, it is modeled off of the consul_cluster implementation and will +// provide thea ability to rapidly install and bootrstap a vault cluster so that end-to-end testing may be done. type Cluster interface { + // Create will install a vault cluster via helm using the default config defined at the end of this file. Create(t *testing.T) + + // Bootstrap will execute the Init(), Unseal() process and bootstrap the vault cluster by enabling the KV2 secret + // engine and also enabling the Kube Auth Method. Bootstrap(t *testing.T, ctx environment.TestContext) + + // Destroy will do a helm uninstall of the Vault installation and then delete the data PVC used by Vault. Destroy(t *testing.T) + + // SetupVaultClient will setup the port-forwarding to the Vault server so that we can create a vault client connection. + // This is run as part of Bootstrap. SetupVaultClient(t *testing.T) *vapi.Client + + // VaultClient returns the client that was built as part of SetupVaultClient. VaultClient(t *testing.T) *vapi.Client } @@ -97,6 +108,7 @@ func NewHelmCluster( } } +// VaultClient returns the vault client. func (v *VaultCluster) VaultClient(t *testing.T) *vapi.Client { return v.vaultClient } // checkForPriorInstallations checks if there is an existing Helm release @@ -125,22 +137,19 @@ func (v *VaultCluster) checkForPriorVaultInstallations(t *testing.T) { for _, r := range installedReleases { require.NotContains(t, r["chart"], "vault", fmt.Sprintf("detected an existing installation of Vault %s, release name: %s", r["chart"], r["name"])) } - /* - // TODO: Copied this from Consul Cluster implementation, is this necessary for vault? - // Wait for all pods in the "default" namespace to exit. A previous - // release may not be listed by Helm but its pods may still be terminating. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { - consulPods, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) - require.NoError(r, err) - if len(consulPods.Items) > 0 { - var podNames []string - for _, p := range consulPods.Items { - podNames = append(podNames, p.Name) - } - r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) + // Wait for all pods in the "default" namespace to exit. A previous + // release may not be listed by Helm but its pods may still be terminating. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { + vaultPods, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) + require.NoError(r, err) + if len(vaultPods.Items) > 0 { + var podNames []string + for _, p := range vaultPods.Items { + podNames = append(podNames, p.Name) } - }) - */ + r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) + } + }) } // Setup Vault Client returns a Vault Client. @@ -174,10 +183,9 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { }) config.Address = fmt.Sprintf("http://127.0.0.1:%d", localPort) - consulClient, err := vapi.NewClient(config) + vaultClient, err := vapi.NewClient(config) require.NoError(t, err) - - return consulClient + return vaultClient } // Bootstrap runs Init, Unseals the Vault installation @@ -217,7 +225,7 @@ func (v *VaultCluster) Bootstrap(t *testing.T, ctx environment.TestContext) { if err != nil { t.Fatal("unable to mount kv-v2 secrets engine", "err", err) } - // TODO: Enable the PKI Secrets Engine + // TODO: add the PKI Secrets Engine when we have a need for it. // Enable Kube Auth. err = v.vaultClient.Sys().EnableAuthWithOptions("kubernetes", &vapi.EnableAuthOptions{ @@ -232,20 +240,7 @@ func (v *VaultCluster) Bootstrap(t *testing.T, ctx environment.TestContext) { cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", v.rootToken) v.logger.Logf(t, "updating vault kube auth config") - // TODO: figure out if this sleep can be done differently. - time.Sleep(time.Second * 30) k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) - - // Create an access policy for Secrets Management, so we can create them later - /* - // TODO: Do we need this policy, because we will have to have root token (or some other priv'd) in our client - // TODO: already in order to create policies and roles. - devpolicyRule := `{ "policy": "path "consul/data/*" { capabilities = ["create", "update", "read"] } }` - err = v.vaultClient.Sys().PutPolicy("dev-root-policy", devpolicyRule) - if err != nil { - t.Fatal("unable to create secret mgmt policy", "err", err) - } - */ } // Create installs Vault via Helm. @@ -284,10 +279,10 @@ func (v *VaultCluster) Destroy(t *testing.T) { // always idempotently clean up resources in the cluster. _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, false) // Delete PVCs. - err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.vaultHelmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: fmt.Sprintf("app.kubernetes.io/instance==data-%s-vault-0", v.vaultReleaseName)}) + err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.vaultHelmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: fmt.Sprintf("app.kubernetes.io/instance=%s", v.vaultReleaseName)}) require.NoError(t, err) - // Delete any secrets that have v.releaseName in their name. + // Delete any secrets that have v.releaseName in their name, this is only needed to delete the Helm release secret. secrets, err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) for _, secret := range secrets.Items { diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 4ee68fbb1f..a6d7ce4154 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -12,7 +12,7 @@ import ( // Installs Vault, bootstraps it with the kube auth method // and then validates that the KV2 secrets engine is online // and the Kube Auth Method is enabled. -func TestVault_Bootstrap(t *testing.T) { +func TestVault_CreateAndBootstrap(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) @@ -24,110 +24,19 @@ func TestVault_Bootstrap(t *testing.T) { vaultClient := vaultCluster.VaultClient(t) - // Write to the KV2 engine succeeds + // Write to the KV2 engine succeeds. logger.Log(t, "Creating a KV2 Secret") params := map[string]interface{}{ "data": map[string]interface{}{ - "test": "ABCD1234", + "foo": "bar", }, } _, err := vaultClient.Logical().Write("consul/data/secret/test", params) require.NoError(t, err) - // Auth Methods exists + // Validate that the Auth Methods exist. authList, err := vaultClient.Sys().ListAuth() require.NoError(t, err) logger.Log(t, "Auth List: ", authList) require.NotNil(t, authList["kubernetes/"]) } - -/* -// Installs Vault, bootstraps it with secrets, policies, and kube auth method -// then creates a gossip encryption secret and uses this to bootstrap Consul -func TestVaultConsulGossipEncryptionKeyIntegration(t *testing.T) { - cfg := suite.Config() - ctx := suite.Environment().DefaultContext(t) - - vaultReleaseName := helpers.RandomName() - logger.Log(t, "Entering NewHelmCluster") - vaultCluster := vault.NewHelmCluster(t, nil, ctx, cfg, vaultReleaseName) - logger.Log(t, "Entering Create") - vaultCluster.Create(t) - // Vault is now installed in the cluster - - logger.Log(t, "Entering Bootstrap") - vaultCluster.Bootstrap(t, ctx) - logger.Log(t, "Finished Bootstrap") - - vaultClient := vaultCluster.VaultClient(t) - - logger.Log(t, "Creating the policies and secrets") - - var err error - // Create the Vault Policy for the gossip key - logger.Log(t, "Creating the gossip policy") - rules := ` -path "consul/data/secret/gossip" { - capabilities = ["read"] -}` - err = vaultClient.Sys().PutPolicy("consul-gossip", rules) - require.NoError(t, err) - - // create the auth roles for consul-server + consul-client - logger.Log(t, "Creating the gossip auth roles") - params := map[string]interface{}{ - "bound_service_account_names": "consul-consul-client", - "bound_service_account_namespaces": "default", - "policies": "consul-gossip", - "ttl": "24h", - } - _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-client", params) - require.NoError(t, err) - - params = map[string]interface{}{ - "bound_service_account_names": "consul-consul-server", - "bound_service_account_namespaces": "default", - "policies": "consul-gossip", - "ttl": "24h", - } - _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-server", params) - require.NoError(t, err) - - // Create the gossip key - logger.Log(t, "Creating the gossip secret") - params = map[string]interface{}{ - "data": map[string]interface{}{ - "gossip": "3R7oLrdpkk2V0Y7yHLizyxXeS2RtaVuy07DkU15Lhws=", - }, - } - _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) - require.NoError(t, err) - - time.Sleep(time.Second * 30) - - consulHelmValues := map[string]string{ - "server.enabled": "true", - "server.replicas": "1", - "global.imageK8S": "kschoche/consul-k8s-hashiconf", - - "connectInject.enabled": "true", - - "secretsBackend.vault.enabled": "true", - "secretsBackend.vault.consulServerRole": "consul-server", - "secretsBackend.vault.consulclientRole": "consul-client", - - "global.tls.enabled": "true", - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": ".Data.data.gossip", - } - // TODO: consul-release name needs to be integrated into all of the secret names and policies above - consulReleaseName := "consul" //helpers.RandomName() - logger.Log(t, "Installing Consul") - consulCluster := consul.NewHelmCluster(t, consulHelmValues, ctx, cfg, consulReleaseName) - - consulCluster.Create(t) - - time.Sleep(time.Second * 600) - -} -*/ From 08daf431f5ba3fb1b957e4f53eed9c654180fdd3 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 21 Oct 2021 11:50:58 -0500 Subject: [PATCH 05/70] remove interface and make bootstrap part of Create --- acceptance/framework/vault/vault_cluster.go | 39 +++++++++++---------- acceptance/tests/vault/vault_test.go | 9 +++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 7f02ee1dbe..2460edc515 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "k8s.io/apimachinery/pkg/api/errors" "strings" "testing" "time" @@ -21,21 +20,24 @@ import ( vapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) -// Cluster represents a vault cluster object, it is modeled off of the consul_cluster implementation and will -// provide thea ability to rapidly install and bootrstap a vault cluster so that end-to-end testing may be done. -type Cluster interface { - // Create will install a vault cluster via helm using the default config defined at the end of this file. - Create(t *testing.T) +/* + // High level description of the functions implemented for the VaultCluster object: + + // Create will install a vault cluster via helm using the default config defined at the end of this file. It will + // then also call bootstrap() to setup the vault cluster for testing. + Create(t *testing.T, ctx environment.TestContext) - // Bootstrap will execute the Init(), Unseal() process and bootstrap the vault cluster by enabling the KV2 secret + // bootstrap will execute the Init(), Unseal() process and bootstrap the vault cluster by enabling the KV2 secret // engine and also enabling the Kube Auth Method. - Bootstrap(t *testing.T, ctx environment.TestContext) + bootstrap(t *testing.T, ctx environment.TestContext) - // Destroy will do a helm uninstall of the Vault installation and then delete the data PVC used by Vault. + // Destroy will do a helm uninstall of the Vault installation and then delete the data PVC used by Vault and the + // helm secrets. Destroy(t *testing.T) // SetupVaultClient will setup the port-forwarding to the Vault server so that we can create a vault client connection. @@ -44,7 +46,7 @@ type Cluster interface { // VaultClient returns the client that was built as part of SetupVaultClient. VaultClient(t *testing.T) *vapi.Client -} +*/ const ( vaultNS = "default" @@ -72,14 +74,14 @@ type VaultCluster struct { logger terratestLogger.TestLogger } -// NewHelmCluster installs Vault into Kubernetes using Helm. -func NewHelmCluster( +// NewVaultCluster creates a VaultCluster which will be used to install Vault using Helm. +func NewVaultCluster( t *testing.T, helmValues map[string]string, ctx environment.TestContext, cfg *config.TestConfig, releaseName string, -) Cluster { +) *VaultCluster { logger := terratestLogger.New(logger.TestLogger{}) @@ -188,9 +190,9 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { return vaultClient } -// Bootstrap runs Init, Unseals the Vault installation +// bootstrap runs Init, Unseals the Vault installation // and then does the setup of Auth Methods and Enables Secrets Engines. -func (v *VaultCluster) Bootstrap(t *testing.T, ctx environment.TestContext) { +func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { v.vaultClient = v.SetupVaultClient(t) @@ -243,8 +245,8 @@ func (v *VaultCluster) Bootstrap(t *testing.T, ctx environment.TestContext) { k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) } -// Create installs Vault via Helm. -func (v *VaultCluster) Create(t *testing.T) { +// Create installs Vault via Helm and then calls bootstrap to initialize it. +func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { t.Helper() // Make sure we delete the cluster if we receive an interrupt signal and @@ -267,7 +269,8 @@ func (v *VaultCluster) Create(t *testing.T) { require.NoError(r, err) require.Equal(r, pod.Status.Phase, corev1.PodRunning) }) - + // Now call bootstrap() + v.bootstrap(t, ctx) } func (v *VaultCluster) Destroy(t *testing.T) { diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index a6d7ce4154..6d58c7365c 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -12,15 +12,14 @@ import ( // Installs Vault, bootstraps it with the kube auth method // and then validates that the KV2 secrets engine is online // and the Kube Auth Method is enabled. -func TestVault_CreateAndBootstrap(t *testing.T) { +func TestVault_Create(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) vaultReleaseName := helpers.RandomName() - vaultCluster := vault.NewHelmCluster(t, nil, ctx, cfg, vaultReleaseName) - vaultCluster.Create(t) - vaultCluster.Bootstrap(t, ctx) - logger.Log(t, "Finished Bootstrap") + vaultCluster := vault.NewVaultCluster(t, nil, ctx, cfg, vaultReleaseName) + vaultCluster.Create(t, ctx) + logger.Log(t, "Finished Installing and Bootstrapping") vaultClient := vaultCluster.VaultClient(t) From a7ad878b2fa950f364cec6874b218bf0c371ed6a Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Tue, 26 Oct 2021 12:01:04 -0500 Subject: [PATCH 06/70] clean up the framework a bit --- acceptance/framework/consul/consul_cluster.go | 46 +------------- acceptance/framework/helpers/helpers.go | 48 +++++++++++++++ acceptance/framework/vault/vault_cluster.go | 61 +++---------------- 3 files changed, 59 insertions(+), 96 deletions(-) diff --git a/acceptance/framework/consul/consul_cluster.go b/acceptance/framework/consul/consul_cluster.go index b1e8f8d9e2..d99551994f 100644 --- a/acceptance/framework/consul/consul_cluster.go +++ b/acceptance/framework/consul/consul_cluster.go @@ -2,7 +2,6 @@ package consul import ( "context" - "encoding/json" "fmt" "strings" "testing" @@ -115,7 +114,7 @@ func (h *HelmCluster) Create(t *testing.T) { }) // Fail if there are any existing installations of the Helm chart. - h.checkForPriorInstallations(t) + helpers.CheckForPriorInstallations(t, h.kubernetesClient, h.helmOptions, "consul") helm.Install(t, h.helmOptions, config.HelmChartPath, h.releaseName) @@ -281,49 +280,6 @@ func (h *HelmCluster) SetupConsulClient(t *testing.T, secure bool) *api.Client { return consulClient } -// checkForPriorInstallations checks if there is an existing Helm release -// for this Helm chart already installed. If there is, it fails the tests. -func (h *HelmCluster) checkForPriorInstallations(t *testing.T) { - t.Helper() - - var helmListOutput string - // Check if there's an existing cluster and fail if there is one. - // We may need to retry since this is the first command run once the Kube - // cluster is created and sometimes the API server returns errors. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { - var err error - // NOTE: It's okay to pass in `t` to RunHelmCommandAndGetOutputE despite being in a retry - // because we're using RunHelmCommandAndGetOutputE (not RunHelmCommandAndGetOutput) so the `t` won't - // get used to fail the test, just for logging. - helmListOutput, err = helm.RunHelmCommandAndGetOutputE(t, h.helmOptions, "list", "--output", "json") - require.NoError(r, err) - }) - - var installedReleases []map[string]string - - err := json.Unmarshal([]byte(helmListOutput), &installedReleases) - require.NoError(t, err, "unmarshalling %q", helmListOutput) - - for _, r := range installedReleases { - require.NotContains(t, r["chart"], "consul", fmt.Sprintf("detected an existing installation of Consul %s, release name: %s", r["chart"], r["name"])) - } - - // Wait for all pods in the "default" namespace to exit. A previous - // release may not be listed by Helm but its pods may still be terminating. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { - consulPods, err := h.kubernetesClient.CoreV1().Pods(h.helmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) - require.NoError(r, err) - if len(consulPods.Items) > 0 { - var podNames []string - for _, p := range consulPods.Items { - podNames = append(podNames, p.Name) - } - r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) - } - }) - -} - // configurePodSecurityPolicies creates a simple pod security policy, a cluster role to allow access to the PSP, // and a role binding that binds the default service account in the helm installation namespace to the cluster role. // We bind the default service account for tests that are spinning up pods without a service account set so that diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index e4a2c02c91..f1c4494b80 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -2,7 +2,9 @@ package helpers import ( "context" + "encoding/json" "fmt" + "github.com/gruntwork-io/terratest/modules/helm" "os" "os/signal" "strings" @@ -25,6 +27,52 @@ func RandomName() string { return fmt.Sprintf("test-%s", strings.ToLower(random.UniqueId())) } +// CheckForPriorInstallations checks if there is an existing Helm release +// for this Helm chart already installed. If there is, it fails the tests. +func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, options *helm.Options, chartName string) { + t.Helper() + + var helmListOutput string + // Check if there's an existing cluster and fail if there is one. + // We may need to retry since this is the first command run once the Kube + // cluster is created and sometimes the API server returns errors. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { + var err error + // NOTE: It's okay to pass in `t` to RunHelmCommandAndGetOutputE despite being in a retry + // because we're using RunHelmCommandAndGetOutputE (not RunHelmCommandAndGetOutput) so the `t` won't + // get used to fail the test, just for logging. + helmListOutput, err = helm.RunHelmCommandAndGetOutputE(t, options, "list", "--output", "json") + require.NoError(r, err) + }) + + var installedReleases []map[string]string + + err := json.Unmarshal([]byte(helmListOutput), &installedReleases) + require.NoError(t, err, "unmarshalling %q", helmListOutput) + + for _, r := range installedReleases { + require.NotContains(t, r["chart"], chartName, fmt.Sprintf("detected an existing installation of %s %s, release name: %s", chartName, r["chart"], r["name"])) + } + + // Wait for all pods in the "default" namespace to exit. A previous + // release may not be listed by Helm but its pods may still be terminating. + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { + pods, err := client.CoreV1().Pods(options.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) + require.NoError(r, err) + if len(pods.Items) > 0 { + var podNames []string + for _, p := range pods.Items { + if strings.Contains(p.Name, chartName) { + podNames = append(podNames, p.Name) + } + } + if len(podNames) > 0 { + r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) + } + } + }) +} + // WaitForAllPodsToBeReady waits until all pods with the provided podLabelSelector // are in the ready status. It checks every 5 seconds for a total of 20 tries. // If there is at least one container in a pod that isn't ready after that, diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 2460edc515..45dab57dca 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -2,7 +2,6 @@ package vault import ( "context" - "encoding/json" "fmt" "strings" "testing" @@ -113,47 +112,6 @@ func NewVaultCluster( // VaultClient returns the vault client. func (v *VaultCluster) VaultClient(t *testing.T) *vapi.Client { return v.vaultClient } -// checkForPriorInstallations checks if there is an existing Helm release -// for this Helm chart already installed. If there is, it fails the tests. -func (v *VaultCluster) checkForPriorVaultInstallations(t *testing.T) { - t.Helper() - - var helmListOutput string - // Check if there's an existing cluster and fail if there is one. - // We may need to retry since this is the first command run once the Kube - // cluster is created and sometimes the API server returns errors. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { - var err error - // NOTE: It's okay to pass in `t` to RunHelmCommandAndGetOutputE despite being in a retry - // because we're using RunHelmCommandAndGetOutputE (not RunHelmCommandAndGetOutput) so the `t` won't - // get used to fail the test, just for logging. - helmListOutput, err = helm.RunHelmCommandAndGetOutputE(t, v.vaultHelmOptions, "list", "--output", "json") - require.NoError(r, err) - }) - - var installedReleases []map[string]string - - err := json.Unmarshal([]byte(helmListOutput), &installedReleases) - require.NoError(t, err, "unmarshalling %q", helmListOutput) - - for _, r := range installedReleases { - require.NotContains(t, r["chart"], "vault", fmt.Sprintf("detected an existing installation of Vault %s, release name: %s", r["chart"], r["name"])) - } - // Wait for all pods in the "default" namespace to exit. A previous - // release may not be listed by Helm but its pods may still be terminating. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { - vaultPods, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) - require.NoError(r, err) - if len(vaultPods.Items) > 0 { - var podNames []string - for _, p := range vaultPods.Items { - podNames = append(podNames, p.Name) - } - r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) - } - }) -} - // Setup Vault Client returns a Vault Client. // TODO: We need to support Vault with TLS enabled. func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { @@ -256,14 +214,14 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { }) // Fail if there are any existing installations of the Helm chart. - v.checkForPriorVaultInstallations(t) + helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, "vault") - // step 1: install Vault + // Install Vault. helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) - // Wait for the injector pod to become Ready. + // Wait for the injector pod to become Ready, but not the server. helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, "app.kubernetes.io/name=vault-agent-injector") - // Wait for the Server Pod to be online, it will not be Ready because it has not been Init+Unseal'd yet, this is done - // in the Bootstrap method. + // Wait for the server pod to be PodRunning, it will not be Ready because it has not been Init+Unseal'd yet. + // The vault server has health checks bound to unseal status, and Unseal is done as part of bootstrap (below). retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 30}, t, func(r *retry.R) { pod, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).Get(context.Background(), fmt.Sprintf("%s-vault-0", v.vaultReleaseName), metav1.GetOptions{}) require.NoError(r, err) @@ -273,6 +231,7 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { v.bootstrap(t, ctx) } +// Destroy issues an helm delete and deletes the PVC + any helm secrets related to the release that are leftover. func (v *VaultCluster) Destroy(t *testing.T) { t.Helper() @@ -281,11 +240,12 @@ func (v *VaultCluster) Destroy(t *testing.T) { // Ignore the error returned by the helm delete here so that we can // always idempotently clean up resources in the cluster. _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, false) - // Delete PVCs. + + // Delete PVCs, these are the only parts that need to be cleaned up in Vault installs. err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.vaultHelmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: fmt.Sprintf("app.kubernetes.io/instance=%s", v.vaultReleaseName)}) require.NoError(t, err) - // Delete any secrets that have v.releaseName in their name, this is only needed to delete the Helm release secret. + // Delete any secrets that have v.releaseName in their name, this is only needed to delete the Helm release secret if it is still around. secrets, err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) require.NoError(t, err) for _, secret := range secrets.Items { @@ -299,12 +259,11 @@ func (v *VaultCluster) Destroy(t *testing.T) { } func defaultVaultValues() map[string]string { - values := map[string]string{ + return map[string]string{ "server.replicas": "1", "server.bootstrapExpect": "1", //"ui.enabled": "true", "injector.enabled": "true", "global.enabled": "true", } - return values } From d0de8e699826e2044f309b39a54ccb0ace9268ee Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 27 Oct 2021 11:01:02 -0500 Subject: [PATCH 07/70] Apply suggestions from code review Co-authored-by: Iryna Shustava --- acceptance/framework/vault/vault_cluster.go | 9 ++++----- acceptance/tests/vault/vault_test.go | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 45dab57dca..b98619c369 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -31,8 +31,8 @@ import ( // then also call bootstrap() to setup the vault cluster for testing. Create(t *testing.T, ctx environment.TestContext) - // bootstrap will execute the Init(), Unseal() process and bootstrap the vault cluster by enabling the KV2 secret - // engine and also enabling the Kube Auth Method. + // bootstrap will init and unseal the Vault cluster and enable the KV2 secret + // engine and the Kube Auth Method. bootstrap(t *testing.T, ctx environment.TestContext) // Destroy will do a helm uninstall of the Vault installation and then delete the data PVC used by Vault and the @@ -148,8 +148,8 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { return vaultClient } -// bootstrap runs Init, Unseals the Vault installation -// and then does the setup of Auth Methods and Enables Secrets Engines. +// bootstrap initializes and unseals the Vault installation. +// It then sets up Kubernetes auth method and enables secrets engines. func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { v.vaultClient = v.SetupVaultClient(t) @@ -262,7 +262,6 @@ func defaultVaultValues() map[string]string { return map[string]string{ "server.replicas": "1", "server.bootstrapExpect": "1", - //"ui.enabled": "true", "injector.enabled": "true", "global.enabled": "true", } diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 6d58c7365c..7ff23f495e 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -33,7 +33,7 @@ func TestVault_Create(t *testing.T) { _, err := vaultClient.Logical().Write("consul/data/secret/test", params) require.NoError(t, err) - // Validate that the Auth Methods exist. + // Validate that the Auth Method exists. authList, err := vaultClient.Sys().ListAuth() require.NoError(t, err) logger.Log(t, "Auth List: ", authList) From da47c6e2b37a19db0d1f24360b773a6b73934667 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 27 Oct 2021 14:14:35 -0500 Subject: [PATCH 08/70] review comments --- .circleci/config.yml | 1 - acceptance/framework/consul/consul_cluster.go | 2 +- acceptance/framework/helpers/helpers.go | 10 +- acceptance/framework/vault/vault_cluster.go | 111 +++++------------- acceptance/tests/vault/vault_test.go | 2 + 5 files changed, 34 insertions(+), 92 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cd6a53cda0..a592052168 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,7 +50,6 @@ commands: wget https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz tar -zxvf helm-v3.7.0-linux-amd64.tar.gz sudo mv linux-amd64/helm /usr/local/bin/helm - /usr/local/bin/helm repo add hashicorp https://helm.releases.hashicorp.com create-kind-clusters: parameters: diff --git a/acceptance/framework/consul/consul_cluster.go b/acceptance/framework/consul/consul_cluster.go index d99551994f..ada9e7b7d9 100644 --- a/acceptance/framework/consul/consul_cluster.go +++ b/acceptance/framework/consul/consul_cluster.go @@ -114,7 +114,7 @@ func (h *HelmCluster) Create(t *testing.T) { }) // Fail if there are any existing installations of the Helm chart. - helpers.CheckForPriorInstallations(t, h.kubernetesClient, h.helmOptions, "consul") + helpers.CheckForPriorInstallations(t, h.kubernetesClient, h.helmOptions, "consul-helm") helm.Install(t, h.helmOptions, config.HelmChartPath, h.releaseName) diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index f1c4494b80..294e395cb2 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -57,18 +57,14 @@ func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, optio // Wait for all pods in the "default" namespace to exit. A previous // release may not be listed by Helm but its pods may still be terminating. retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { - pods, err := client.CoreV1().Pods(options.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) + pods, err := client.CoreV1().Pods(options.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("chart=%s", chartName)}) require.NoError(r, err) if len(pods.Items) > 0 { var podNames []string for _, p := range pods.Items { - if strings.Contains(p.Name, chartName) { - podNames = append(podNames, p.Name) - } - } - if len(podNames) > 0 { - r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) + podNames = append(podNames, p.Name) } + r.Errorf("pods from previous installation still running: %s", strings.Join(podNames, ", ")) } }) } diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index b98619c369..bad8681b14 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -3,7 +3,10 @@ package vault import ( "context" "fmt" - "strings" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" "time" @@ -12,43 +15,17 @@ import ( terratestLogger "github.com/gruntwork-io/terratest/modules/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/config" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" - "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" - "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul/sdk/testutil/retry" vapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) -/* - // High level description of the functions implemented for the VaultCluster object: - - // Create will install a vault cluster via helm using the default config defined at the end of this file. It will - // then also call bootstrap() to setup the vault cluster for testing. - Create(t *testing.T, ctx environment.TestContext) - - // bootstrap will init and unseal the Vault cluster and enable the KV2 secret - // engine and the Kube Auth Method. - bootstrap(t *testing.T, ctx environment.TestContext) - - // Destroy will do a helm uninstall of the Vault installation and then delete the data PVC used by Vault and the - // helm secrets. - Destroy(t *testing.T) - - // SetupVaultClient will setup the port-forwarding to the Vault server so that we can create a vault client connection. - // This is run as part of Bootstrap. - SetupVaultClient(t *testing.T) *vapi.Client - - // VaultClient returns the client that was built as part of SetupVaultClient. - VaultClient(t *testing.T) *vapi.Client -*/ - const ( - vaultNS = "default" + vaultNS = "default" + vaultChartVersion = "0.17.0" + vaultRootToken = "abcd1234" ) // VaultCluster @@ -58,8 +35,8 @@ type VaultCluster struct { vaultHelmOptions *helm.Options vaultReleaseName string + vaultChartName string vaultClient *vapi.Client - rootToken string kubectlOptions *terratestk8s.KubectlOptions values map[string]string @@ -91,7 +68,11 @@ func NewVaultCluster( SetValues: defaultVaultValues(), KubectlOptions: kopts, Logger: logger, + Version: vaultChartVersion, } + // Add the vault helm repo in case it is missing, and do an update so we can utilise `vaultChartVersion` to install. + helm.AddRepo(t, &helm.Options{}, "hashicorp/vault", "https://helm.releases.hashicorp.com") + helm.RunHelmCommandAndGetOutputE(t, &helm.Options{}, "repo", "update") return &VaultCluster{ ctx: ctx, @@ -106,6 +87,7 @@ func NewVaultCluster( debugDirectory: cfg.DebugDirectory, logger: logger, vaultReleaseName: releaseName, + vaultChartName: fmt.Sprintf("vault-%s", vaultChartVersion), } } @@ -148,37 +130,14 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { return vaultClient } -// bootstrap initializes and unseals the Vault installation. -// It then sets up Kubernetes auth method and enables secrets engines. +// bootstrap sets up Kubernetes auth method and enables secrets engines. func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { v.vaultClient = v.SetupVaultClient(t) + v.vaultClient.SetToken(vaultRootToken) - // Init the Vault Cluster and store the rootToken. - initResp, err := v.vaultClient.Sys().Init(&vapi.InitRequest{ - // Init the cluster and only request a single Secret to be used for Unsealing. - SecretShares: 1, - SecretThreshold: 1, - StoredShares: 1, - RecoveryShares: 0, - RecoveryThreshold: 0, - }) - if err != nil { - t.Fatal("unable to init Vault cluster", "err", err) - } - // Store the RootToken and set the client to use it so it can Unseal and finish bootstrapping. - v.rootToken = initResp.RootToken - v.vaultClient.SetToken(v.rootToken) - - // Unseal the Vault Cluster using the Unseal Keys from Init(). - sealResp, err := v.vaultClient.Sys().Unseal(initResp.KeysB64[0]) - if err != nil { - t.Fatal("unable to unseal Vault cluster", "err", err) - } - require.Equal(t, false, sealResp.Sealed) - - // Enable the KV-V2 Secrets engine - err = v.vaultClient.Sys().Mount("consul", &vapi.MountInput{ + // Enable the KV-V2 Secrets engine. + err := v.vaultClient.Sys().Mount("consul", &vapi.MountInput{ Type: "kv-v2", Config: vapi.MountConfigInput{}, }) @@ -197,7 +156,7 @@ func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { } // We need to kubectl exec this one on the vault server: // This is taken from https://learn.hashicorp.com/tutorials/vault/kubernetes-google-cloud-gke?in=vault/kubernetes#configure-kubernetes-authentication - cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", v.rootToken) + cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", vaultRootToken) v.logger.Logf(t, "updating vault kube auth config") k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) @@ -214,7 +173,7 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { }) // Fail if there are any existing installations of the Helm chart. - helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, "vault") + helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, v.vaultChartName) // Install Vault. helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) @@ -231,38 +190,24 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { v.bootstrap(t, ctx) } -// Destroy issues an helm delete and deletes the PVC + any helm secrets related to the release that are leftover. +// Destroy issues a helm delete and deletes the PVC + any helm secrets related to the release that are leftover. func (v *VaultCluster) Destroy(t *testing.T) { t.Helper() k8s.WritePodsDebugInfoIfFailed(t, v.kubectlOptions, v.debugDirectory, "release="+v.vaultReleaseName) - // Ignore the error returned by the helm delete here so that we can // always idempotently clean up resources in the cluster. - _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, false) - - // Delete PVCs, these are the only parts that need to be cleaned up in Vault installs. - err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.vaultHelmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: fmt.Sprintf("app.kubernetes.io/instance=%s", v.vaultReleaseName)}) - require.NoError(t, err) - - // Delete any secrets that have v.releaseName in their name, this is only needed to delete the Helm release secret if it is still around. - secrets, err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{}) - require.NoError(t, err) - for _, secret := range secrets.Items { - if strings.Contains(secret.Name, v.vaultReleaseName) { - err := v.kubernetesClient.CoreV1().Secrets(v.vaultHelmOptions.KubectlOptions.Namespace).Delete(context.Background(), secret.Name, metav1.DeleteOptions{}) - if !errors.IsNotFound(err) { - require.NoError(t, err) - } - } - } + _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, true) + // We do not need to do any PVC deletion in vault dev mode. } func defaultVaultValues() map[string]string { return map[string]string{ - "server.replicas": "1", - "server.bootstrapExpect": "1", - "injector.enabled": "true", - "global.enabled": "true", + "server.replicas": "1", + "server.dev.enabled": "true", + "server.dev.devRootToken": vaultRootToken, + "server.bootstrapExpect": "1", + "injector.enabled": "true", + "global.enabled": "true", } } diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 7ff23f495e..fac892bf0e 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -2,6 +2,7 @@ package vault import ( "testing" + "time" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -38,4 +39,5 @@ func TestVault_Create(t *testing.T) { require.NoError(t, err) logger.Log(t, "Auth List: ", authList) require.NotNil(t, authList["kubernetes/"]) + time.Sleep(time.Second * 60) } From 400fda62fbd32d0cf8c60f688640a38f48b134ea Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 27 Oct 2021 14:24:35 -0500 Subject: [PATCH 09/70] fix lint --- acceptance/framework/vault/vault_cluster.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index bad8681b14..36644c1abe 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -72,7 +72,9 @@ func NewVaultCluster( } // Add the vault helm repo in case it is missing, and do an update so we can utilise `vaultChartVersion` to install. helm.AddRepo(t, &helm.Options{}, "hashicorp/vault", "https://helm.releases.hashicorp.com") - helm.RunHelmCommandAndGetOutputE(t, &helm.Options{}, "repo", "update") + // Ignoring the error from `helm repo update` as it could fail due to stale cache or unreachable servers and we're + // asserting a chart version on Install which would fail in an obvious way should this not succeed. + _, _ = helm.RunHelmCommandAndGetOutputE(t, &helm.Options{}, "repo", "update") return &VaultCluster{ ctx: ctx, From 80102a5edb7d07f4fd4e165d98a498439cc298bf Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Fri, 12 Nov 2021 13:12:25 -0600 Subject: [PATCH 10/70] Bootstrap gossip encryption with Vault (#811) * Add base bootstrapping logic and acceptance tests for gossip encryption in Vault Co-authored-by: Iryna Shustava --- acceptance/framework/consul/consul_cluster.go | 2 +- acceptance/framework/helpers/helpers.go | 4 +- acceptance/framework/vault/vault_cluster.go | 41 +++---- acceptance/tests/vault/vault_test.go | 109 ++++++++++++++--- charts/consul/templates/_helpers.tpl | 6 + charts/consul/templates/client-daemonset.yaml | 17 +++ .../consul/templates/server-statefulset.yaml | 19 +++ charts/consul/test/unit/client-daemonset.bats | 93 +++++++++++++- .../gossip-encryption-autogenerate-job.bats | 16 +-- .../consul/test/unit/server-statefulset.bats | 115 +++++++++++++++--- charts/consul/values.yaml | 55 ++++++++- 11 files changed, 398 insertions(+), 79 deletions(-) diff --git a/acceptance/framework/consul/consul_cluster.go b/acceptance/framework/consul/consul_cluster.go index 15cd39a28c..90b5dc392b 100644 --- a/acceptance/framework/consul/consul_cluster.go +++ b/acceptance/framework/consul/consul_cluster.go @@ -114,7 +114,7 @@ func (h *HelmCluster) Create(t *testing.T) { }) // Fail if there are any existing installations of the Helm chart. - helpers.CheckForPriorInstallations(t, h.kubernetesClient, h.helmOptions, "consul-helm") + helpers.CheckForPriorInstallations(t, h.kubernetesClient, h.helmOptions, "consul-helm", "chart=consul-helm") helm.Install(t, h.helmOptions, config.HelmChartPath, h.releaseName) diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index 294e395cb2..f173aeea6f 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -29,7 +29,7 @@ func RandomName() string { // CheckForPriorInstallations checks if there is an existing Helm release // for this Helm chart already installed. If there is, it fails the tests. -func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, options *helm.Options, chartName string) { +func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, options *helm.Options, chartName, labelSelector string) { t.Helper() var helmListOutput string @@ -57,7 +57,7 @@ func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, optio // Wait for all pods in the "default" namespace to exit. A previous // release may not be listed by Helm but its pods may still be terminating. retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { - pods, err := client.CoreV1().Pods(options.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("chart=%s", chartName)}) + pods, err := client.CoreV1().Pods(options.KubectlOptions.Namespace).List(context.Background(), metav1.ListOptions{LabelSelector: labelSelector}) require.NoError(r, err) if len(pods.Items) > 0 { var podNames []string diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 36644c1abe..01e3141e1f 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -1,12 +1,7 @@ package vault import ( - "context" "fmt" - "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" - "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" "time" @@ -15,6 +10,8 @@ import ( terratestLogger "github.com/gruntwork-io/terratest/modules/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/config" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul/sdk/testutil/retry" vapi "github.com/hashicorp/vault/api" @@ -23,9 +20,9 @@ import ( ) const ( - vaultNS = "default" - vaultChartVersion = "0.17.0" - vaultRootToken = "abcd1234" + vaultNS = "default" + vaultPodLabel = "app.kubernetes.io/instance=" + vaultRootToken = "abcd1234" ) // VaultCluster @@ -35,7 +32,6 @@ type VaultCluster struct { vaultHelmOptions *helm.Options vaultReleaseName string - vaultChartName string vaultClient *vapi.Client kubectlOptions *terratestk8s.KubectlOptions @@ -68,13 +64,14 @@ func NewVaultCluster( SetValues: defaultVaultValues(), KubectlOptions: kopts, Logger: logger, - Version: vaultChartVersion, } - // Add the vault helm repo in case it is missing, and do an update so we can utilise `vaultChartVersion` to install. - helm.AddRepo(t, &helm.Options{}, "hashicorp/vault", "https://helm.releases.hashicorp.com") + helm.AddRepo(t, vaultHelmOpts, "hashicorp", "https://helm.releases.hashicorp.com") // Ignoring the error from `helm repo update` as it could fail due to stale cache or unreachable servers and we're // asserting a chart version on Install which would fail in an obvious way should this not succeed. - _, _ = helm.RunHelmCommandAndGetOutputE(t, &helm.Options{}, "repo", "update") + _, err := helm.RunHelmCommandAndGetOutputE(t, &helm.Options{}, "repo", "update") + if err != nil { + logger.Logf(t, "Unable to update helm repository, proceeding anyway: %s.", err) + } return &VaultCluster{ ctx: ctx, @@ -89,7 +86,6 @@ func NewVaultCluster( debugDirectory: cfg.DebugDirectory, logger: logger, vaultReleaseName: releaseName, - vaultChartName: fmt.Sprintf("vault-%s", vaultChartVersion), } } @@ -115,7 +111,7 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { v.logger) // Retry creating the port forward since it can fail occasionally. - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 3}, t, func(r *retry.R) { + retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 60}, t, func(r *retry.R) { // NOTE: It's okay to pass in `t` to ForwardPortE despite being in a retry // because we're using ForwardPortE (not ForwardPort) so the `t` won't // get used to fail the test, just for logging. @@ -158,7 +154,7 @@ func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { } // We need to kubectl exec this one on the vault server: // This is taken from https://learn.hashicorp.com/tutorials/vault/kubernetes-google-cloud-gke?in=vault/kubernetes#configure-kubernetes-authentication - cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", vaultRootToken) + cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config disable_iss_validation=\"true\" token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", vaultRootToken) v.logger.Logf(t, "updating vault kube auth config") k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) @@ -175,19 +171,12 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { }) // Fail if there are any existing installations of the Helm chart. - helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, v.vaultChartName) + helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, "", fmt.Sprintf("%s=%s", vaultPodLabel, v.vaultReleaseName)) // Install Vault. helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) - // Wait for the injector pod to become Ready, but not the server. - helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, "app.kubernetes.io/name=vault-agent-injector") - // Wait for the server pod to be PodRunning, it will not be Ready because it has not been Init+Unseal'd yet. - // The vault server has health checks bound to unseal status, and Unseal is done as part of bootstrap (below). - retry.RunWith(&retry.Counter{Wait: 1 * time.Second, Count: 30}, t, func(r *retry.R) { - pod, err := v.kubernetesClient.CoreV1().Pods(v.vaultHelmOptions.KubectlOptions.Namespace).Get(context.Background(), fmt.Sprintf("%s-vault-0", v.vaultReleaseName), metav1.GetOptions{}) - require.NoError(r, err) - require.Equal(r, pod.Status.Phase, corev1.PodRunning) - }) + // Wait for the injector and vault server pods to become Ready. + helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, fmt.Sprintf("%s=%s", vaultPodLabel, v.vaultReleaseName)) // Now call bootstrap() v.bootstrap(t, ctx) } diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index fac892bf0e..67b81f1884 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -1,43 +1,118 @@ package vault import ( - "testing" - "time" - + "crypto/rand" + "encoding/base64" + "fmt" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/vault" "github.com/stretchr/testify/require" + "testing" ) -// Installs Vault, bootstraps it with the kube auth method -// and then validates that the KV2 secrets engine is online -// and the Kube Auth Method is enabled. -func TestVault_Create(t *testing.T) { +// generateGossipSecret generates a random 32 byte secret returned as a base64 encoded string. +func generateGossipSecret() (string, error) { + // This code was copied from Consul's Keygen command: + // https://github.com/hashicorp/consul/blob/d652cc86e3d0322102c2b5e9026c6a60f36c17a5/command/keygen/keygen.go + + key := make([]byte, 32) + n, err := rand.Reader.Read(key) + if err != nil { + return "", fmt.Errorf("error reading random data: %s", err) + } + if n != 32 { + return "", fmt.Errorf("couldn't read enough entropy") + } + + return base64.StdEncoding.EncodeToString(key), nil +} + +// Installs Vault, bootstraps it with secrets, policies, and Kube Auth Method +// then creates a gossip encryption secret and uses this to bootstrap Consul. +func TestVault_BootstrapConsulGossipEncryptionKey(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) + consulReleaseName := helpers.RandomName() vaultReleaseName := helpers.RandomName() + consulClientServiceAccountName := fmt.Sprintf("%s-consul-client", consulReleaseName) + consulServerServiceAccountName := fmt.Sprintf("%s-consul-server", consulReleaseName) + vaultCluster := vault.NewVaultCluster(t, nil, ctx, cfg, vaultReleaseName) vaultCluster.Create(t, ctx) - logger.Log(t, "Finished Installing and Bootstrapping") + // Vault is now installed in the cluster. + // Now fetch the Vault client so we can create the policies and secrets. vaultClient := vaultCluster.VaultClient(t) - // Write to the KV2 engine succeeds. - logger.Log(t, "Creating a KV2 Secret") + // Create the Vault Policy for the gossip key. + logger.Log(t, "Creating the gossip policy") + rules := ` +path "consul/data/secret/gossip" { + capabilities = ["read"] +}` + err := vaultClient.Sys().PutPolicy("consul-gossip", rules) + require.NoError(t, err) + + // Create the Auth Roles for consul-server + consul-client. + logger.Log(t, "Creating the consul-server and consul-client-roles") params := map[string]interface{}{ + "bound_service_account_names": consulClientServiceAccountName, + "bound_service_account_namespaces": "default", + "policies": "consul-gossip", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-client", params) + require.NoError(t, err) + + params = map[string]interface{}{ + "bound_service_account_names": consulServerServiceAccountName, + "bound_service_account_namespaces": "default", + "policies": "consul-gossip", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-server", params) + require.NoError(t, err) + + gossipKey, err := generateGossipSecret() + require.NoError(t, err) + + // Create the gossip secret. + logger.Log(t, "Creating the gossip secret") + params = map[string]interface{}{ "data": map[string]interface{}{ - "foo": "bar", + "gossip": gossipKey, }, } - _, err := vaultClient.Logical().Write("consul/data/secret/test", params) + _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) require.NoError(t, err) - // Validate that the Auth Method exists. - authList, err := vaultClient.Sys().ListAuth() + consulHelmValues := map[string]string{ + "server.enabled": "true", + "server.replicas": "1", + + "connectInject.enabled": "true", + + "global.secretsBackend.vault.enabled": "true", + "global.secretsBackend.vault.consulServerRole": "consul-server", + "global.secretsBackend.vault.consulClientRole": "consul-client", + + "global.acls.manageSystemACLs": "true", + "global.tls.enabled": "true", + "global.gossipEncryption.secretName": "consul/data/secret/gossip", + "global.gossipEncryption.secretKey": "gossip", + } + logger.Log(t, "Installing Consul") + consulCluster := consul.NewHelmCluster(t, consulHelmValues, ctx, cfg, consulReleaseName) + consulCluster.Create(t) + + // Validate that the gossip encryption key is set correctly. + logger.Log(t, "Validating the gossip key has been set correctly.") + consulClient := consulCluster.SetupConsulClient(t, true) + keys, err := consulClient.Operator().KeyringList(nil) require.NoError(t, err) - logger.Log(t, "Auth List: ", authList) - require.NotNil(t, authList["kubernetes/"]) - time.Sleep(time.Second * 60) + // We use keys[0] because KeyringList returns a list of keyrings for each dc, in this case there is only 1 dc. + require.Equal(t, 1, keys[0].PrimaryKeys[gossipKey]) } diff --git a/charts/consul/templates/_helpers.tpl b/charts/consul/templates/_helpers.tpl index 173eb68cc9..07ced2d778 100644 --- a/charts/consul/templates/_helpers.tpl +++ b/charts/consul/templates/_helpers.tpl @@ -15,6 +15,12 @@ as well as the global.name setting. {{- end -}} {{- end -}} +{{- define "consul.vaultGossipTemplate" -}} + | + {{ "{{" }}- with secret "{{ .secretName }}" -{{ "}}" }} + {{ "{{" }}- {{ printf ".Data.data.%s" .secretKey }} -{{ "}}" }} + {{ "{{" }}- end -{{ "}}" }} +{{- end -}} {{/* Sets up the extra-from-values config file passed to consul and then uses sed to do any necessary substitution for HOST_IP/POD_IP/HOSTNAME. Useful for dogstats telemetry. The output file diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index d4e1c05107..af213f9e4e 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -2,6 +2,7 @@ {{- if (and (and .Values.global.tls.enabled .Values.global.tls.httpsOnly) (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics))}}{{ fail "global.metrics.enableAgentMetrics cannot be enabled if TLS (HTTPS only) is enabled" }}{{ end -}} {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (and .Values.global.adminPartitions.enabled $serverEnabled (ne .Values.global.adminPartitions.name "default"))}}{{ fail "global.adminPartitions.name has to be \"default\" in the server cluster" }}{{ end -}} +{{- if (and (not .Values.global.secretsBackend.vault.consulClientRole) .Values.global.secretsBackend.vault.enabled) }}{{ fail "global.secretsBackend.vault.consulClientRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} # DaemonSet to run the Consul clients on every node. apiVersion: apps/v1 kind: DaemonSet @@ -37,6 +38,16 @@ spec: {{- toYaml .Values.client.extraLabels | nindent 8 }} {{- end }} annotations: + {{- if .Values.global.secretsBackend.vault.enabled }} + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulClientRole }}" + {{- if .Values.global.gossipEncryption.secretName }} + {{- with .Values.global.gossipEncryption }} + "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultGossipTemplate" . }} + {{- end }} + {{- end }} + {{- end }} "consul.hashicorp.com/connect-inject": "false" "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/client-config-configmap.yaml") . | sha256sum }} {{- if .Values.client.annotations }} @@ -169,6 +180,7 @@ spec: - name: CONSUL_DISABLE_PERM_MGMT value: "true" {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: GOSSIP_KEY valueFrom: secretKeyRef: @@ -180,6 +192,7 @@ spec: key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} {{- end }} + {{- end }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey .Values.server.enterpriseLicense.enableLicenseAutoload (not .Values.global.acls.manageSystemACLs)) }} - name: CONSUL_LICENSE_PATH value: /consul/license/{{ .Values.server.enterpriseLicense.secretKey }} @@ -202,6 +215,10 @@ spec: - | CONSUL_FULLNAME="{{template "consul.fullname" . }}" + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.gossipEncryption.secretName }} + GOSSIP_KEY=`cat /vault/secrets/gossip.txt` + {{- end }} + {{ template "consul.extraconfig" }} exec /usr/local/bin/docker-entrypoint.sh consul agent \ diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index fe2dcff468..77fa3c68de 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -5,6 +5,9 @@ {{- if .Values.server.disableFsGroupSecurityContext }}{{ fail "server.disableFsGroupSecurityContext has been removed. Please use global.openshift.enabled instead." }}{{ end }} {{- if .Values.server.bootstrapExpect }}{{ if lt (int .Values.server.bootstrapExpect) (int .Values.server.replicas) }}{{ fail "server.bootstrapExpect cannot be less than server.replicas" }}{{ end }}{{ end }} {{- if (and (and .Values.global.tls.enabled .Values.global.tls.httpsOnly) (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics))}}{{ fail "global.metrics.enableAgentMetrics cannot be enabled if TLS (HTTPS only) is enabled" }}{{ end -}} +{{- if (and .Values.global.gossipEncryption.secretName (not .Values.global.gossipEncryption.secretKey)) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and (not .Values.global.gossipEncryption.secretName) .Values.global.gossipEncryption.secretKey) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and .Values.global.secretsBackend.vault.enabled (not .Values.global.secretsBackend.vault.consulServerRole)) }}{{ fail "global.secretsBackend.vault.consulServerRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} # StatefulSet to run the actual Consul server cluster. apiVersion: apps/v1 kind: StatefulSet @@ -46,6 +49,16 @@ spec: {{- toYaml .Values.server.extraLabels | nindent 8 }} {{- end }} annotations: + {{- if .Values.global.secretsBackend.vault.enabled }} + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulServerRole }}" + {{- if .Values.global.gossipEncryption.secretName }} + {{- with .Values.global.gossipEncryption }} + "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultGossipTemplate" . }} + {{- end }} + {{- end }} + {{- end }} "consul.hashicorp.com/connect-inject": "false" "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/server-config-configmap.yaml") . | sha256sum }} {{- if .Values.server.annotations }} @@ -157,6 +170,7 @@ spec: - name: CONSUL_DISABLE_PERM_MGMT value: "true" {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: GOSSIP_KEY valueFrom: secretKeyRef: @@ -168,6 +182,7 @@ spec: key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} {{- end }} + {{- end }} {{- if .Values.global.tls.enabled }} - name: CONSUL_HTTP_ADDR value: https://localhost:8501 @@ -192,6 +207,10 @@ spec: - | CONSUL_FULLNAME="{{template "consul.fullname" . }}" + {{- if .Values.global.secretsBackend.vault.enabled }} + GOSSIP_KEY=`cat /vault/secrets/gossip.txt` + {{- end }} + {{ template "consul.extraconfig" }} exec /usr/local/bin/docker-entrypoint.sh consul agent \ diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index 64a9d0e4c0..f83c802e32 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -602,7 +602,7 @@ load _helpers local actual=$(helm template \ -s templates/client-daemonset.yaml \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY")' | tee /dev/stderr) [ "${actual}" = "" ] } @@ -1516,3 +1516,94 @@ rollingUpdate: [ "${object}" = 1 ] } + +#-------------------------------------------------------------------- +# vault integration + +@test "client/DaemonSet: fail when vault is enabled but the consulClientRole is not provided" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.secretsBackend.vault.consulClientRole must be provided if global.secretsBackend.vault.enabled=true" ]] +} + +@test "client/DaemonSet: vault annotations not set by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/role"] | length > 0 ' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: vault annotations added when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + +@test "client/DaemonSet: vault gossip annotations are set when gossip encryption enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.gossipEncryption.secretName=path/to/secret' \ + --set 'global.gossipEncryption.secretKey=gossip' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-secret-gossip.txt"]' | tee /dev/stderr) + [ "${actual}" = "path/to/secret" ] + local actual="$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-gossip.txt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"path/to/secret\" -}}\n{{- .Data.data.gossip -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] +} + +@test "client/DaemonSet: GOSSIP_KEY env variable is not set and command defines GOSSIP_KEY when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.gossipEncryption.secretName=a/b/c/d' \ + --set 'global.gossipEncryption.secretKey=gossip' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec' | tee /dev/stderr) + + + local actual=$(echo $object | + yq -r '.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY")' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[] | select(.name=="consul") | .command | any(contains("GOSSIP_KEY="))' \ + | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats b/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats index b78b9c231d..4b5938ab91 100644 --- a/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats +++ b/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats @@ -39,24 +39,14 @@ load _helpers [[ "$output" =~ "If global.gossipEncryption.autoGenerate is true, global.gossipEncryption.secretName and global.gossipEncryption.secretKey must not be set." ]] } -@test "gossipEncryptionAutogenerate/Job: fails if global.gossipEncryption.autoGenerate=true and global.gossipEncryption.secretName is set" { +@test "gossipEncryptionAutogenerate/Job: fails if global.gossipEncryption.autoGenerate=true and global.gossipEncryption.secretName+key are set" { cd `chart_dir` run helm template \ -s templates/gossip-encryption-autogenerate-job.yaml \ --set 'global.gossipEncryption.autoGenerate=true' \ --set 'global.gossipEncryption.secretName=name' \ - . - [ "$status" -eq 1 ] - [[ "$output" =~ "If global.gossipEncryption.autoGenerate is true, global.gossipEncryption.secretName and global.gossipEncryption.secretKey must not be set." ]] -} - -@test "gossipEncryptionAutogenerate/Job: fails if global.gossipEncryption.autoGenerate=true and global.gossipEncryption.secretKey is set" { - cd `chart_dir` - run helm template \ - -s templates/gossip-encryption-autogenerate-job.yaml \ - --set 'global.gossipEncryption.autoGenerate=true' \ - --set 'global.gossipEncryption.secretKey=key' \ - . + --set 'global.gossipEncryption.secretKey=name' \ + . [ "$status" -eq 1 ] [[ "$output" =~ "If global.gossipEncryption.autoGenerate is true, global.gossipEncryption.secretName and global.gossipEncryption.secretKey must not be set." ]] } diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index 6418cef313..909fb647b2 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -838,7 +838,7 @@ load _helpers local actual=$(helm template \ -s templates/server-statefulset.yaml \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY")' | tee /dev/stderr) [ "${actual}" = "" ] } @@ -863,25 +863,20 @@ load _helpers [ "${actual}" = "true" ] } - -@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when secretName is missing" { +@test "server/StatefulSet: fail if global.gossipEncyption.gossipEncryption.secretName is set but not global.gossipEncyption.secretKey" { cd `chart_dir` - local actual=$(helm template \ + run helm template \ -s templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] + --set 'global.gossipEncryption.secretName=bar' . + [[ "$output" =~ "gossipEncryption.secretKey and secretName must both be specified." ]] } -@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when secretKey is missing" { +@test "server/StatefulSet: fail if global.gossipEncyption.gossipEncryption.secretKey is set but not global.gossipEncyption.secretName" { cd `chart_dir` - local actual=$(helm template \ + run helm template \ -s templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.secretName=foo' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] + --set 'global.gossipEncryption.secretKey=bar' . + [[ "$output" =~ "gossipEncryption.secretKey and secretName must both be specified." ]] } @test "server/StatefulSet: gossip environment variable present in server StatefulSet when all config is provided" { @@ -1415,3 +1410,95 @@ load _helpers [ "${object}" = 1 ] } + +#-------------------------------------------------------------------- +# vault integration + +@test "server/StatefulSet: fail when vault is enabled but the consulServerRole is not provided" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.secretsBackend.vault.consulServerRole must be provided if global.secretsBackend.vault.enabled=true" ]] +} + +@test "server/StatefulSet: vault annotations not set by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/role"] | length > 0 ' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: vault annotations added when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "test" ] +} + +@test "server/StatefulSet: vault gossip annotations are correct when enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.gossipEncryption.secretName=path/to/secret' \ + --set 'global.gossipEncryption.secretKey=gossip' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-secret-gossip.txt"]' | tee /dev/stderr) + [ "${actual}" = "path/to/secret" ] + local actual=$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-gossip.txt"]' | tee /dev/stderr) + local actual="$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-gossip.txt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"path/to/secret\" -}}\n{{- .Data.data.gossip -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] +} + +@test "server/StatefulSet: vault no GOSSIP_KEY env variable and command defines GOSSIP_KEY" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.gossipEncryption.secretName=a/b/c/d' \ + --set 'global.gossipEncryption.secretKey=gossip' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec' | tee /dev/stderr) + + + local actual=$(echo $object | + yq -r '.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY")' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[] | select(.name=="consul") | .command | any(contains("GOSSIP_KEY="))' \ + | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 44b81cc327..2a04d7416c 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -117,25 +117,70 @@ global: # created by this chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/. enablePodSecurityPolicies: false - # Configures Consul's gossip encryption key, set as a Kubernetes secret + # secretsBackend is used to configure Vault as the secrets backend for the Consul on Kubernetes installation. + # The Vault cluster needs to have the Kubernetes Auth Method, + # KV2 and PKI secrets engines enabled and have necessary secrets, + # policies and roles created prior to installing Consul. + # The Vault cluster should not have Consul as its storage backend. + # Note: When using Vault KV2 secrets engines the "data" field is implicitly required for Vault API calls, + # secretName should be in the form of "vault-kv2-mount-path/data/secret-name". + # secretKey should be in the form of "key". + secretsBackend: + vault: + # Enabling the Vault secrets backend will replace Kubernetes secrets with referenced Vault secrets. + enabled: false + + # The Vault role for the Consul server. + # The role must be connected to the Consul server's service account and + # have a policy with read capabilities for the following secrets: + # - gossip encryption key defined by `global.gossipEncryption.secretName`. + # To discover the service account name of the Consul server, run + # ``` + # helm template -s templates/server-serviceaccount.yaml charts/consul + # ``` + # and check the name of `metadata.name`. + consulServerRole: "" + + # The Vault role for the Consul client. + # The role must be connected to the Consul client's service account and + # have a policy with read capabilities for the following secrets: + # - gossip encryption key defined by `global.gossipEncryption.secretName`. + # To discover the service account name of the Consul server, run + # ``` + # helm template -s templates/client-daemonset.yaml charts/consul + # ``` + # and check the name of `metadata.name`. + consulClientRole: "" + + # Configures Consul's gossip encryption key. # (see `-encrypt` (https://consul.io/docs/agent/options#_encrypt)). # By default, gossip encryption is not enabled. The gossip encryption key may be set automatically or manually. # The recommended method is to automatically generate the key. # To automatically generate and set a gossip encryption key, set autoGenerate to true. # Values for secretName and secretKey should not be set if autoGenerate is true. # To manually generate a gossip encryption key, set secretName and secretKey and use Consul to generate - # a Kubernetes secret referencing these values. + # a key, saving this as a Kubernetes secret or Vault secret path and key. + # If `global.secretsBackend.vault.enabled=true`, be sure to add the "data" field to the secretName as required by + # the Vault KV-2 secrets engine [see example]. # # ``` # $ kubectl create secret generic consul-gossip-encryption-key --from-literal=key=$(consul keygen) # ``` + # + # Vault CLI Example: + # ``` + # $ vault kv put consul/secrets/gossip key=$(consul keygen) + # ``` + # `gossipEncryption.secretName="consul/data/secrets/gossip"` + # `gossipEncryption.secretKey="key"` + gossipEncryption: # Automatically generate a gossip encryption key and save it to a Kubernetes secret. autoGenerate: false - # secretName is the name of the Kubernetes secret that holds the gossip - # encryption key. The secret must be in the same namespace that Consul is installed into. + # secretName is the name of the Kubernetes secret or Vault secret path that holds the gossip + # encryption key. A Kubernetes secret must be in the same namespace that Consul is installed into. secretName: "" - # secretKey is the key within the Kubernetes secret that holds the gossip + # secretKey is the key within the Kubernetes secret or Vault secret key that holds the gossip # encryption key. secretKey: "" From 9c515aaf4397e8f81a66b1137240adc0c9317e4d Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Wed, 24 Nov 2021 13:52:24 -0700 Subject: [PATCH 11/70] Add configuration for the vault Connect CA provider (#872) --- acceptance/framework/helpers/helpers.go | 4 +- .../fixtures/bases/intention/intention.yaml | 10 + .../bases/intention/kustomization.yaml | 2 + acceptance/tests/vault/vault_test.go | 125 +++++++--- .../templates/server-config-configmap.yaml | 30 +++ .../test/unit/server-config-configmap.bats | 227 ++++++++++++++++++ charts/consul/values.yaml | 37 +++ 7 files changed, 406 insertions(+), 29 deletions(-) create mode 100644 acceptance/tests/fixtures/bases/intention/intention.yaml create mode 100644 acceptance/tests/fixtures/bases/intention/kustomization.yaml diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index f173aeea6f..1c40112e7d 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/gruntwork-io/terratest/modules/helm" "os" "os/signal" "strings" @@ -12,6 +11,8 @@ import ( "testing" "time" + "github.com/gruntwork-io/terratest/modules/helm" + terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/gruntwork-io/terratest/modules/random" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -85,6 +86,7 @@ func WaitForAllPodsToBeReady(t *testing.T, client kubernetes.Interface, namespac retry.RunWith(counter, t, func(r *retry.R) { pods, err := client.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{LabelSelector: podLabelSelector}) require.NoError(r, err) + require.NotEmpty(r, pods.Items) var notReadyPods []string for _, pod := range pods.Items { diff --git a/acceptance/tests/fixtures/bases/intention/intention.yaml b/acceptance/tests/fixtures/bases/intention/intention.yaml new file mode 100644 index 0000000000..c7bf26dac2 --- /dev/null +++ b/acceptance/tests/fixtures/bases/intention/intention.yaml @@ -0,0 +1,10 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceIntentions +metadata: + name: client-to-server +spec: + destination: + name: static-server + sources: + - name: static-client + action: allow diff --git a/acceptance/tests/fixtures/bases/intention/kustomization.yaml b/acceptance/tests/fixtures/bases/intention/kustomization.yaml new file mode 100644 index 0000000000..8d15c05511 --- /dev/null +++ b/acceptance/tests/fixtures/bases/intention/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - intention.yaml \ No newline at end of file diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 67b81f1884..94d09f1492 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -4,34 +4,50 @@ import ( "crypto/rand" "encoding/base64" "fmt" + "testing" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/vault" "github.com/stretchr/testify/require" - "testing" ) -// generateGossipSecret generates a random 32 byte secret returned as a base64 encoded string. -func generateGossipSecret() (string, error) { - // This code was copied from Consul's Keygen command: - // https://github.com/hashicorp/consul/blob/d652cc86e3d0322102c2b5e9026c6a60f36c17a5/command/keygen/keygen.go +const ( + gossipPolicy = ` +path "consul/data/secret/gossip" { + capabilities = ["read"] +}` - key := make([]byte, 32) - n, err := rand.Reader.Read(key) - if err != nil { - return "", fmt.Errorf("error reading random data: %s", err) - } - if n != 32 { - return "", fmt.Errorf("couldn't read enough entropy") - } + // connectCAPolicy allows Consul to bootstrap all certificates for the service mesh in Vault. + // Adapted from https://www.consul.io/docs/connect/ca/vault#consul-managed-pki-paths. + connectCAPolicy = ` +path "/sys/mounts" { + capabilities = [ "read" ] +} - return base64.StdEncoding.EncodeToString(key), nil +path "/sys/mounts/connect_root" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} + +path "/sys/mounts/connect_inter" { + capabilities = [ "create", "read", "update", "delete", "list" ] } -// Installs Vault, bootstraps it with secrets, policies, and Kube Auth Method -// then creates a gossip encryption secret and uses this to bootstrap Consul. -func TestVault_BootstrapConsulGossipEncryptionKey(t *testing.T) { +path "/connect_root/*" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} + +path "/connect_inter/*" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} +` +) + +// TestVault installs Vault, bootstraps it with secrets, policies, and Kube Auth Method. +// It then configures Consul to use vault as the backend and checks that it works. +func TestVault(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) @@ -48,16 +64,20 @@ func TestVault_BootstrapConsulGossipEncryptionKey(t *testing.T) { vaultClient := vaultCluster.VaultClient(t) // Create the Vault Policy for the gossip key. - logger.Log(t, "Creating the gossip policy") - rules := ` -path "consul/data/secret/gossip" { - capabilities = ["read"] -}` - err := vaultClient.Sys().PutPolicy("consul-gossip", rules) + logger.Log(t, "Creating policies") + err := vaultClient.Sys().PutPolicy("consul-gossip", gossipPolicy) + require.NoError(t, err) + + err = vaultClient.Sys().PutPolicy("connect-ca", connectCAPolicy) require.NoError(t, err) - // Create the Auth Roles for consul-server + consul-client. - logger.Log(t, "Creating the consul-server and consul-client-roles") + // Create the Auth Roles for consul-server and consul-client. + // Auth roles bind policies to Kubernetes service accounts, which + // then enables the Vault agent init container to call 'vault login' + // with the Kubernetes auth method to obtain a Vault token. + // Please see https://www.vaultproject.io/docs/auth/kubernetes#configuration + // for more details. + logger.Log(t, "Creating the consul-server and consul-client roles") params := map[string]interface{}{ "bound_service_account_names": consulClientServiceAccountName, "bound_service_account_namespaces": "default", @@ -70,7 +90,7 @@ path "consul/data/secret/gossip" { params = map[string]interface{}{ "bound_service_account_names": consulServerServiceAccountName, "bound_service_account_namespaces": "default", - "policies": "consul-gossip", + "policies": "consul-gossip,connect-ca", "ttl": "24h", } _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-server", params) @@ -88,17 +108,23 @@ path "consul/data/secret/gossip" { } _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) require.NoError(t, err) - consulHelmValues := map[string]string{ + "global.image": "docker.mirror.hashicorp.services/hashicorpdev/consul:latest", + "server.enabled": "true", "server.replicas": "1", "connectInject.enabled": "true", + "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", "global.secretsBackend.vault.consulServerRole": "consul-server", "global.secretsBackend.vault.consulClientRole": "consul-client", + "global.secretsBackend.vault.connectCA.address": fmt.Sprintf("http://%s-vault:8200", vaultReleaseName), + "global.secretsBackend.vault.connectCA.rootPKIPath": "connect_root", + "global.secretsBackend.vault.connectCA.intermediatePKIPath": "connect_inter", + "global.acls.manageSystemACLs": "true", "global.tls.enabled": "true", "global.gossipEncryption.secretName": "consul/data/secret/gossip", @@ -113,6 +139,49 @@ path "consul/data/secret/gossip" { consulClient := consulCluster.SetupConsulClient(t, true) keys, err := consulClient.Operator().KeyringList(nil) require.NoError(t, err) - // We use keys[0] because KeyringList returns a list of keyrings for each dc, in this case there is only 1 dc. + // There are two identical keys for LAN and WAN since there is only 1 dc. + require.Len(t, keys, 2) require.Equal(t, 1, keys[0].PrimaryKeys[gossipKey]) + + // Confirm that the Vault Connect CA has been bootstrapped correctly. + caConfig, _, err := consulClient.Connect().CAGetConfig(nil) + require.NoError(t, err) + require.Equal(t, caConfig.Provider, "vault") + + // Deploy two services and check that they can talk to each other. + logger.Log(t, "creating static-server and static-client deployments") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + } else { + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + } + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") + }) + k8s.KubectlApplyK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") + + logger.Log(t, "checking that connection is successful") + if cfg.EnableTransparentProxy { + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), "http://static-server") + } else { + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), "http://localhost:1234") + } +} + +// generateGossipSecret generates a random 32 byte secret returned as a base64 encoded string. +func generateGossipSecret() (string, error) { + // This code was copied from Consul's Keygen command: + // https://github.com/hashicorp/consul/blob/d652cc86e3d0322102c2b5e9026c6a60f36c17a5/command/keygen/keygen.go + + key := make([]byte, 32) + n, err := rand.Reader.Read(key) + if err != nil { + return "", fmt.Errorf("error reading random data: %s", err) + } + if n != 32 { + return "", fmt.Errorf("couldn't read enough entropy") + } + + return base64.StdEncoding.EncodeToString(key), nil } diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 6faf60b4b9..2b8f07dc6b 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -11,6 +11,36 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} data: + {{- $vaultConnectCAEnabled := and .Values.global.secretsBackend.vault.connectCA.address .Values.global.secretsBackend.vault.connectCA.rootPKIPath .Values.global.secretsBackend.vault.connectCA.intermediatePKIPath -}} + {{- if and .Values.global.secretsBackend.vault.enabled $vaultConnectCAEnabled }} + {{- with .Values.global.secretsBackend.vault }} + connect-ca-config.json: | + { + "connect": [ + { + "ca_config": [ + { + "address": "{{ .connectCA.address }}", + "intermediate_pki_path": "{{ .connectCA.intermediatePKIPath }}", + "root_pki_path": "{{ .connectCA.rootPKIPath }}", + "auth_method": { + "type": "kubernetes", + "params": { + "role": "{{.consulServerRole}}" + } + } + } + ], + "ca_provider": "vault" + } + ] + } + {{- if .connectCA.additionalConfig }} + additional-connect-ca-config.json: | +{{ tpl .connectCA.additionalConfig $ | trimAll "\"" | indent 4 }} + {{- end }} + {{- end }} + {{- end }} extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} {{- if .Values.global.acls.manageSystemACLs }} diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 25a08da37c..8245fb215e 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -179,3 +179,230 @@ load _helpers yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault Connect CA + +@test "server/ConfigMap: doesn't add connect CA config by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled but vault address, root and int PKI paths are not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and vault address is set, but root and int PKI paths are not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and root pki path is set, but vault address and int PKI paths are not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and int path is set, but vault address and root PKI paths are not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and root and int paths are set, but vault address is not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and root path and address are set, but int path is not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't add connect CA config when vault is enabled and int path and address are set, but root path is not set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.intPKIPath=int' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.intPKIPath=int' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: adds connect CA config when vault is enabled and connect CA are configured" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"]' | tee /dev/stderr) + [ "${actual}" = '"{\n \"connect\": [\n {\n \"ca_config\": [\n {\n \"address\": \"example.com\",\n \"intermediate_pki_path\": \"int\",\n \"root_pki_path\": \"root\",\n \"auth_method\": {\n \"type\": \"kubernetes\",\n \"params\": {\n \"role\": \"foo\"\n }\n }\n }\n ],\n \"ca_provider\": \"vault\"\n }\n ]\n}\n"' ] + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"]' | tee /dev/stderr) + [ "${actual}" = '"{}\n"' ] +} + +@test "server/ConfigMap: can set additional connect CA config" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.connectCA.additionalConfig="{\"hello\": \"world\"}"' \ + . | tee /dev/stderr | + yq '.data["additional-connect-ca-config.json"]' | tee /dev/stderr) + [ "${actual}" = '"{\"hello\": \"world\"}\n"' ] +} \ No newline at end of file diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 2a04d7416c..480e46bee5 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -152,6 +152,43 @@ global: # and check the name of `metadata.name`. consulClientRole: "" + # Configuration for the Vault Connect CA provider. + # The provider will be configured to use the Vault Kubernetes auth method + # and therefore requires the role provided by `global.secretsBackend.vault.consulServerRole` + # to have permissions to the root and intermediate PKI paths. + # Please see https://www.consul.io/docs/connect/ca/vault#vault-acl-policies + # for information on how to configure the Vault policies. + connectCA: + # The address of the Vault server. + address: "" + + # The path to a PKI secrets engine for the root certificate. + # Please see https://www.consul.io/docs/connect/ca/vault#rootpkipath. + rootPKIPath: "" + + # The path to a PKI secrets engine for the generated intermediate certificate. + # Please see https://www.consul.io/docs/connect/ca/vault#intermediatepkipath. + intermediatePKIPath: "" + + # Additional Connect CA configuration in JSON format. + # Please see https://www.consul.io/docs/connect/ca/vault#common-ca-config-options + # for additional configuration options. + # + # Example: + # + # ```yaml + # additionalConfig: | + # { + # "connect": [{ + # "ca_config": [{ + # "leaf_cert_ttl": "36h" + # }] + # }] + # } + # ``` + additionalConfig: | + {} + # Configures Consul's gossip encryption key. # (see `-encrypt` (https://consul.io/docs/agent/options#_encrypt)). # By default, gossip encryption is not enabled. The gossip encryption key may be set automatically or manually. From 84f1a8eb93cbd0d0d1b635895089851c67b28acd Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Wed, 1 Dec 2021 11:17:25 -0700 Subject: [PATCH 12/70] Support Vault server running with TLS (#874) * Change vault cluster in acceptance tests to only run with TLS. All tests will run against vault with TLS because that is the use case we think will be the most valuable for users to test * Support adding Vault CA as a secret to pods that will be using vault agent. We need to add two annotations to pods: * vault.hashicorp.com/agent-extra-secret with the value of the vault CA secret name. The secret will be mounted to vault agent at /vault/custom path. See docs here * vault.hashicorp.com/ca-cert - with the path of the ca file inside the vault agent container. This should be /vault/custom/ * Most pods will only need those annotations. The server pods also need the Vault CA secret to be mounted as a volume because it needs the CA to be on the file system for the vault connect CA provider. --- acceptance/framework/helpers/helpers.go | 4 +- acceptance/framework/vault/vault_cluster.go | 264 ++++++++-- acceptance/go.mod | 11 +- acceptance/go.sum | 492 ++++++++++++++++-- acceptance/tests/vault/vault_test.go | 16 +- charts/consul/templates/client-daemonset.yaml | 4 + .../templates/server-config-configmap.yaml | 5 +- .../consul/templates/server-statefulset.yaml | 17 + charts/consul/test/unit/client-daemonset.bats | 68 +++ .../test/unit/server-config-configmap.bats | 68 +++ .../consul/test/unit/server-statefulset.bats | 117 ++++- charts/consul/values.yaml | 9 + 12 files changed, 954 insertions(+), 121 deletions(-) diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index 1c40112e7d..7ed784d838 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -77,7 +77,7 @@ func CheckForPriorInstallations(t *testing.T, client kubernetes.Interface, optio func WaitForAllPodsToBeReady(t *testing.T, client kubernetes.Interface, namespace, podLabelSelector string) { t.Helper() - logger.Log(t, "Waiting for pods to be ready.") + logger.Logf(t, "Waiting for pods with label %q to be ready.", podLabelSelector) // Wait up to 15m. // On Azure, volume provisioning can sometimes take close to 5 min, @@ -101,7 +101,7 @@ func WaitForAllPodsToBeReady(t *testing.T, client kubernetes.Interface, namespac logger.Log(t, "Finished waiting for pods to be ready.") } -// Sets up a goroutine that will wait for interrupt signals +// SetupInterruptHandler sets up a goroutine that will wait for interrupt signals // and call cleanup function when it catches it. func SetupInterruptHandler(cleanup func()) { c := make(chan os.Signal, 1) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 01e3141e1f..9287d57035 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -1,6 +1,7 @@ package vault import ( + "context" "fmt" "testing" "time" @@ -13,33 +14,30 @@ import ( "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul-k8s/control-plane/helper/cert" "github.com/hashicorp/consul/sdk/testutil/retry" vapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) const ( - vaultNS = "default" - vaultPodLabel = "app.kubernetes.io/instance=" - vaultRootToken = "abcd1234" + releaseLabel = "app.kubernetes.io/instance=" ) -// VaultCluster +// VaultCluster represents a vault installation. type VaultCluster struct { - ctx environment.TestContext - namespace string + ctx environment.TestContext - vaultHelmOptions *helm.Options - vaultReleaseName string - vaultClient *vapi.Client + helmOptions *helm.Options + releaseName string + vaultClient *vapi.Client kubectlOptions *terratestk8s.KubectlOptions - values map[string]string kubernetesClient kubernetes.Interface - kubeConfig string - kubeContext string noCleanupOnFailure bool debugDirectory string @@ -47,21 +45,14 @@ type VaultCluster struct { } // NewVaultCluster creates a VaultCluster which will be used to install Vault using Helm. -func NewVaultCluster( - t *testing.T, - helmValues map[string]string, - ctx environment.TestContext, - cfg *config.TestConfig, - releaseName string, -) *VaultCluster { +func NewVaultCluster(t *testing.T, ctx environment.TestContext, cfg *config.TestConfig, releaseName string) *VaultCluster { logger := terratestLogger.New(logger.TestLogger{}) kopts := ctx.KubectlOptions(t) - kopts.Namespace = vaultNS vaultHelmOpts := &helm.Options{ - SetValues: defaultVaultValues(), + SetValues: defaultHelmValues(releaseName), KubectlOptions: kopts, Logger: logger, } @@ -75,35 +66,34 @@ func NewVaultCluster( return &VaultCluster{ ctx: ctx, - vaultHelmOptions: vaultHelmOpts, + helmOptions: vaultHelmOpts, kubectlOptions: kopts, - namespace: cfg.KubeNamespace, - values: helmValues, kubernetesClient: ctx.KubernetesClient(t), - kubeConfig: cfg.Kubeconfig, - kubeContext: cfg.KubeContext, noCleanupOnFailure: cfg.NoCleanupOnFailure, debugDirectory: cfg.DebugDirectory, logger: logger, - vaultReleaseName: releaseName, + releaseName: releaseName, } } // VaultClient returns the vault client. func (v *VaultCluster) VaultClient(t *testing.T) *vapi.Client { return v.vaultClient } -// Setup Vault Client returns a Vault Client. -// TODO: We need to support Vault with TLS enabled. +// SetupVaultClient sets up and returns a Vault Client. func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { t.Helper() + if v.vaultClient != nil { + return v.vaultClient + } + config := vapi.DefaultConfig() localPort := terratestk8s.GetAvailablePort(t) remotePort := 8200 // use non-secure by default - serverPod := fmt.Sprintf("%s-vault-0", v.vaultReleaseName) + serverPod := fmt.Sprintf("%s-vault-0", v.releaseName) tunnel := terratestk8s.NewTunnelWithLogger( - v.vaultHelmOptions.KubectlOptions, + v.helmOptions.KubectlOptions, terratestk8s.ResourceTypePod, serverPod, localPort, @@ -122,7 +112,10 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { tunnel.Close() }) - config.Address = fmt.Sprintf("http://127.0.0.1:%d", localPort) + config.Address = fmt.Sprintf("https://127.0.0.1:%d", localPort) + // We don't need to verify TLS for localhost traffic. + err := config.ConfigureTLS(&vapi.TLSConfig{Insecure: true}) + require.NoError(t, err) vaultClient, err := vapi.NewClient(config) require.NoError(t, err) return vaultClient @@ -132,7 +125,6 @@ func (v *VaultCluster) SetupVaultClient(t *testing.T) *vapi.Client { func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { v.vaultClient = v.SetupVaultClient(t) - v.vaultClient.SetToken(vaultRootToken) // Enable the KV-V2 Secrets engine. err := v.vaultClient.Sys().Mount("consul", &vapi.MountInput{ @@ -146,18 +138,28 @@ func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { // Enable Kube Auth. err = v.vaultClient.Sys().EnableAuthWithOptions("kubernetes", &vapi.EnableAuthOptions{ - Type: "kubernetes", - Config: vapi.MountConfigInput{}, + Type: "kubernetes", }) if err != nil { t.Fatal("unable to enable kube auth", "err", err) } - // We need to kubectl exec this one on the vault server: - // This is taken from https://learn.hashicorp.com/tutorials/vault/kubernetes-google-cloud-gke?in=vault/kubernetes#configure-kubernetes-authentication - cmdString := fmt.Sprintf("VAULT_TOKEN=%s vault write auth/kubernetes/config disable_iss_validation=\"true\" token_reviewer_jwt=\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" kubernetes_host=\"https://${KUBERNETES_PORT_443_TCP_ADDR}:443\" kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", vaultRootToken) v.logger.Logf(t, "updating vault kube auth config") - k8s.RunKubectl(t, ctx.KubectlOptions(t), "exec", "-i", fmt.Sprintf("%s-vault-0", v.vaultReleaseName), "--", "sh", "-c", cmdString) + + // To configure the auth method, we need to read the token and the ca cert from the Vault's server + // service account token. + namespace := v.helmOptions.KubectlOptions.Namespace + sa, err := v.kubernetesClient.CoreV1().ServiceAccounts(namespace).Get(context.Background(), fmt.Sprintf("%s-vault", v.releaseName), metav1.GetOptions{}) + require.NoError(t, err) + require.Len(t, sa.Secrets, 1) + tokenSecret, err := v.kubernetesClient.CoreV1().Secrets(namespace).Get(context.Background(), sa.Secrets[0].Name, metav1.GetOptions{}) + require.NoError(t, err) + _, err = v.vaultClient.Logical().Write("auth/kubernetes/config", map[string]interface{}{ + "token_reviewer_jwt": tokenSecret.StringData["token"], + "kubernetes_ca_cert": tokenSecret.StringData["ca.crt"], + "kubernetes_host": "https://kubernetes.default.svc", + }) + require.NoError(t, err) } // Create installs Vault via Helm and then calls bootstrap to initialize it. @@ -171,13 +173,19 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { }) // Fail if there are any existing installations of the Helm chart. - helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.vaultHelmOptions, "", fmt.Sprintf("%s=%s", vaultPodLabel, v.vaultReleaseName)) + helpers.CheckForPriorInstallations(t, v.kubernetesClient, v.helmOptions, "", v.releaseLabelSelector()) + + v.createTLSCerts(t) // Install Vault. - helm.Install(t, v.vaultHelmOptions, "hashicorp/vault", v.vaultReleaseName) + helm.Install(t, v.helmOptions, "hashicorp/vault", v.releaseName) + + v.initAndUnseal(t) + // Wait for the injector and vault server pods to become Ready. - helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.vaultHelmOptions.KubectlOptions.Namespace, fmt.Sprintf("%s=%s", vaultPodLabel, v.vaultReleaseName)) - // Now call bootstrap() + helpers.WaitForAllPodsToBeReady(t, v.kubernetesClient, v.helmOptions.KubectlOptions.Namespace, v.releaseLabelSelector()) + + // Now call bootstrap(). v.bootstrap(t, ctx) } @@ -185,20 +193,170 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext) { func (v *VaultCluster) Destroy(t *testing.T) { t.Helper() - k8s.WritePodsDebugInfoIfFailed(t, v.kubectlOptions, v.debugDirectory, "release="+v.vaultReleaseName) + k8s.WritePodsDebugInfoIfFailed(t, v.kubectlOptions, v.debugDirectory, v.releaseLabelSelector()) // Ignore the error returned by the helm delete here so that we can // always idempotently clean up resources in the cluster. - _ = helm.DeleteE(t, v.vaultHelmOptions, v.vaultReleaseName, true) - // We do not need to do any PVC deletion in vault dev mode. + _ = helm.DeleteE(t, v.helmOptions, v.releaseName, true) + + err := v.kubernetesClient.CoreV1().PersistentVolumeClaims(v.helmOptions.KubectlOptions.Namespace).DeleteCollection(context.Background(), + metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: v.releaseLabelSelector()}) + require.NoError(t, err) } -func defaultVaultValues() map[string]string { +func defaultHelmValues(releaseName string) map[string]string { + certSecret := certSecretName(releaseName) + caSecret := CASecretName(releaseName) + + serverConfig := fmt.Sprintf(` + listener "tcp" { + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_cert_file = "/vault/userconfig/%s/tls.crt" + tls_key_file = "/vault/userconfig/%s/tls.key" + tls_client_ca_file = "/vault/userconfig/%s/tls.crt" + } + + storage "file" { + path = "/vault/data" + }`, certSecret, certSecret, caSecret) + return map[string]string{ - "server.replicas": "1", - "server.dev.enabled": "true", - "server.dev.devRootToken": vaultRootToken, - "server.bootstrapExpect": "1", - "injector.enabled": "true", - "global.enabled": "true", + "global.tlsDisable": "false", + "server.extraEnvironmentVars.VAULT_CACERT": fmt.Sprintf("/vault/userconfig/%s/tls.crt", caSecret), + "server.extraVolumes[0].name": caSecret, + "server.extraVolumes[0].type": "secret", + "server.extraVolumes[1].name": certSecret, + "server.extraVolumes[1].type": "secret", + "server.standalone.enabled": "true", + "server.standalone.config": serverConfig, + "injector.enabled": "true", } } + +// certSecretName returns the Kubernetes secret name of the certificate and key +// for the Vault server. +func certSecretName(releaseName string) string { + return fmt.Sprintf("%s-vault-server-tls", releaseName) +} + +// CASecretName returns the Kubernetes secret name of the CA for the Vault server. +func CASecretName(releaseName string) string { + return fmt.Sprintf("%s-vault-ca", releaseName) +} + +// Address is the in-cluster API address of the Vault server. +func (v *VaultCluster) Address() string { + return fmt.Sprintf("https://%s-vault:8200", v.releaseName) +} + +// releaseLabelSelector returns label selector that selects all pods +// from a Vault installation. +func (v *VaultCluster) releaseLabelSelector() string { + return fmt.Sprintf("%s=%s", releaseLabel, v.releaseName) +} + +// createTLSCerts generates a self-signed CA and uses it to generate +// certificate and key for the Vault server. It then saves those as +// Kubernetes secrets. +func (v *VaultCluster) createTLSCerts(t *testing.T) { + v.logger.Logf(t, "generating Vault TLS certificates") + + namespace := v.helmOptions.KubectlOptions.Namespace + + // Generate CA and cert and create secrets for them. + signer, _, caPem, caCertTmpl, err := cert.GenerateCA("Vault CA") + require.NoError(t, err) + vaultService := fmt.Sprintf("%s-vault", v.releaseName) + certSANs := []string{ + vaultService, + fmt.Sprintf("%s.default", vaultService), + fmt.Sprintf("%s.default.svc", vaultService), + } + certPem, keyPem, err := cert.GenerateCert("Vault server", 24*time.Hour, caCertTmpl, signer, certSANs) + require.NoError(t, err) + + t.Cleanup(func() { + if !v.noCleanupOnFailure { + // We're ignoring error here because secret deletion is best-effort. + _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), certSecretName(v.releaseName), metav1.DeleteOptions{}) + _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), CASecretName(v.releaseName), metav1.DeleteOptions{}) + } + }) + + _, err = v.kubernetesClient.CoreV1().Secrets(namespace).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: certSecretName(v.releaseName), + }, + Data: map[string][]byte{ + corev1.TLSCertKey: []byte(certPem), + corev1.TLSPrivateKeyKey: []byte(keyPem), + }, + Type: corev1.SecretTypeTLS, + }, metav1.CreateOptions{}) + require.NoError(t, err) + + _, err = v.kubernetesClient.CoreV1().Secrets(namespace).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: CASecretName(v.releaseName), + Namespace: namespace, + }, + Data: map[string][]byte{ + corev1.TLSCertKey: []byte(caPem), + }, + Type: corev1.SecretTypeOpaque, + }, metav1.CreateOptions{}) + require.NoError(t, err) +} + +// initAndUnseal initializes and unseals Vault. +// Once initialized, it saves the Vault root token into a Kubernetes secret. +func (v *VaultCluster) initAndUnseal(t *testing.T) { + v.logger.Logf(t, "initializing and unsealing Vault") + + namespace := v.helmOptions.KubectlOptions.Namespace + retrier := &retry.Timer{Timeout: 2 * time.Minute, Wait: 1 * time.Second} + retry.RunWith(retrier, t, func(r *retry.R) { + // Wait for vault server pod to be running so that we can create Vault client without errors. + serverPod, err := v.kubernetesClient.CoreV1().Pods(namespace).Get(context.Background(), fmt.Sprintf("%s-vault-0", v.releaseName), metav1.GetOptions{}) + require.NoError(r, err) + require.Equal(r, serverPod.Status.Phase, corev1.PodRunning) + + // Set up the client so that we can make API calls to initialize and unseal. + v.vaultClient = v.SetupVaultClient(t) + + // Initialize Vault with 1 secret share. We don't need to + // more key shares for this test installation. + initResp, err := v.vaultClient.Sys().Init(&vapi.InitRequest{ + SecretShares: 1, + SecretThreshold: 1, + }) + require.NoError(r, err) + v.vaultClient.SetToken(initResp.RootToken) + + // Unseal Vault with the unseal key we got when initialized it. + // There should be one unseal key since we're only using one secret share. + _, err = v.vaultClient.Sys().Unseal(initResp.KeysB64[0]) + require.NoError(r, err) + }) + + v.logger.Logf(t, "successfully initialized and unsealed Vault") + + rootTokenSecret := fmt.Sprintf("%s-vault-root-token", v.releaseName) + v.logger.Logf(t, "saving Vault root token to %q Kubernetes secret", rootTokenSecret) + + helpers.Cleanup(t, v.noCleanupOnFailure, func() { + _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), rootTokenSecret, metav1.DeleteOptions{}) + }) + _, err := v.kubernetesClient.CoreV1().Secrets(namespace).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: rootTokenSecret, + Namespace: namespace, + }, + Data: map[string][]byte{ + "token": []byte(v.vaultClient.Token()), + }, + Type: corev1.SecretTypeOpaque, + }, metav1.CreateOptions{}) + require.NoError(t, err) +} diff --git a/acceptance/go.mod b/acceptance/go.mod index f3ae49e46d..4993a3b5df 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -4,12 +4,13 @@ go 1.14 require ( github.com/gruntwork-io/terratest v0.31.2 - github.com/hashicorp/consul/api v1.10.1-0.20211025235848-5c24ed61a89c + github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 + github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f github.com/hashicorp/consul/sdk v0.8.0 github.com/hashicorp/vault/api v1.2.0 github.com/stretchr/testify v1.7.0 - gopkg.in/yaml.v2 v2.2.8 - k8s.io/api v0.19.3 - k8s.io/apimachinery v0.19.3 - k8s.io/client-go v0.19.3 + gopkg.in/yaml.v2 v2.4.0 + k8s.io/api v0.22.2 + k8s.io/apimachinery v0.22.2 + k8s.io/client-go v0.22.2 ) diff --git a/acceptance/go.sum b/acceptance/go.sum index 21beaba9f1..c7e67332e3 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -6,29 +6,47 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= 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/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.5/go.mod h1:foo3aIXRQ90zFve3r0QiDsrjGDUwWhKl0ZOQy1CT14k= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.0/go.mod h1:QRTvSZQpxqm8mSErhnbI+tANIBAKP7B+UIE2z4ypUO0= github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4= github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= @@ -41,10 +59,12 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= 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/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.3.0/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/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -55,39 +75,56 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= -github.com/armon/go-metrics v0.3.3 h1:a9F4rlj7EWWrbj7BYw8J8+x+ZZkJeqzNyRk8hdPF+ro= github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 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-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27 h1:9gPjZWVDSoQrBO2AvqrWObS6KAZByfEJxQoCYo4ZfK0= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -96,7 +133,12 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +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/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -108,15 +150,19 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +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= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -124,11 +170,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= +github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -141,7 +193,6 @@ github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avu github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -157,21 +208,30 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= +github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +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/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -179,73 +239,100 @@ github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8= github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +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.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= 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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= 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= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= @@ -254,51 +341,74 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arnQQLM4RH+CYs= github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= -github.com/hashicorp/consul/api v1.10.1-0.20211025235848-5c24ed61a89c h1:7hQzN7YHI2XscCNqPVW5pORQSwJWdFgObnwXNFdEJI8= -github.com/hashicorp/consul/api v1.10.1-0.20211025235848-5c24ed61a89c/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 h1:Km6RYuAsJVVu3gipkTWF1SVYuvSJrksBtT89rO4hcdA= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51/go.mod h1:+Ay3RL0eZdI0wgT193r+EJTOk9cSn1WUlvBvk6Lfnmo= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= +github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +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-discover v0.0.0-20200812215701-c4b85f6ed31f/go.mod h1:D4eo8/CN92vm9/9UDG+ldX1/fMFa4kpl8qzyTolus8o= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= 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-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -309,6 +419,7 @@ github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= 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-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -327,6 +438,7 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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.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.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= @@ -334,47 +446,67 @@ github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG 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/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= -github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE= github.com/hashicorp/vault/api v1.2.0 h1:ysGFc6XRGbv05NsWPzuO5VTv68Lj8jtwATxRLFOpP9s= github.com/hashicorp/vault/api v1.2.0/go.mod h1:dAjw0T5shMnrfH7Q/Mst+LrcTKvStZBVs1PICEDpUqY= github.com/hashicorp/vault/sdk v0.1.14-0.20200519221530-14615acda45f/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10= github.com/hashicorp/vault/sdk v0.2.1 h1:S4O6Iv/dyKlE9AUTXGa7VOvZmsCvg36toPKgV4f2P4M= github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/rZwaxjBkgN4U= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -385,41 +517,54 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= 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/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -428,6 +573,9 @@ github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7p github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -439,20 +587,35 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P 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= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -460,7 +623,9 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -484,24 +649,38 @@ github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -513,21 +692,35 @@ 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/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= +github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -536,6 +729,9 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn 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/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= @@ -545,10 +741,16 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -556,19 +758,51 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= +github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -583,16 +817,24 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 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-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -602,13 +844,19 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -623,21 +871,36 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +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-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -649,8 +912,11 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -671,42 +937,77 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-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= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -717,6 +1018,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -732,16 +1034,37 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191205215504-7b8c8591a921/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200113040837-eac381796e91 h1:OOkytthzFBKHY5EfEgLUabprb0LtJVkQtNxAQ02+UE4= golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= @@ -750,13 +1073,19 @@ google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNV google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -765,12 +1094,26 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +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-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -779,8 +1122,13 @@ google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRn google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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= @@ -790,22 +1138,25 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 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= @@ -818,61 +1169,92 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= -k8s.io/api v0.19.3 h1:GN6ntFnv44Vptj/b+OnMW7FmzkpDoIDLZRvKX3XH9aU= +k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= +k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= +k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= +k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.19.3 h1:bpIQXlKjB4cB/oNpnNnV+BybGPR7iP5oYpsOTEJ4hgc= +k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk= +k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= +k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= -k8s.io/client-go v0.19.3 h1:ctqR1nQ52NUs6LpI0w+a5U+xjYwflFwA13OJKcicMxg= +k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM= +k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc= +k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= +k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug= k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= +k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/controller-runtime v0.10.2/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= -sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +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 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 94d09f1492..4b63dc8b65 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -56,7 +56,7 @@ func TestVault(t *testing.T) { consulClientServiceAccountName := fmt.Sprintf("%s-consul-client", consulReleaseName) consulServerServiceAccountName := fmt.Sprintf("%s-consul-server", consulReleaseName) - vaultCluster := vault.NewVaultCluster(t, nil, ctx, cfg, vaultReleaseName) + vaultCluster := vault.NewVaultCluster(t, ctx, cfg, vaultReleaseName) vaultCluster.Create(t, ctx) // Vault is now installed in the cluster. @@ -108,11 +108,16 @@ func TestVault(t *testing.T) { } _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) require.NoError(t, err) + + vaultCASecret := vault.CASecretName(vaultReleaseName) consulHelmValues := map[string]string{ "global.image": "docker.mirror.hashicorp.services/hashicorpdev/consul:latest", - "server.enabled": "true", - "server.replicas": "1", + "server.enabled": "true", + "server.replicas": "1", + "server.extraVolumes[0].type": "secret", + "server.extraVolumes[0].name": vaultCASecret, + "server.extraVolumes[0].load": "false", "connectInject.enabled": "true", "controller.enabled": "true", @@ -121,7 +126,10 @@ func TestVault(t *testing.T) { "global.secretsBackend.vault.consulServerRole": "consul-server", "global.secretsBackend.vault.consulClientRole": "consul-client", - "global.secretsBackend.vault.connectCA.address": fmt.Sprintf("http://%s-vault:8200", vaultReleaseName), + "global.secretsBackend.vault.ca.secretName": vaultCASecret, + "global.secretsBackend.vault.ca.secretKey": "tls.crt", + + "global.secretsBackend.vault.connectCA.address": vaultCluster.Address(), "global.secretsBackend.vault.connectCA.rootPKIPath": "connect_root", "global.secretsBackend.vault.connectCA.intermediatePKIPath": "connect_inter", diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index af213f9e4e..468af38fda 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -41,6 +41,10 @@ spec: {{- if .Values.global.secretsBackend.vault.enabled }} "vault.hashicorp.com/agent-inject": "true" "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulClientRole }}" + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} {{- if .Values.global.gossipEncryption.secretName }} {{- with .Values.global.gossipEncryption }} "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 2b8f07dc6b..27b65887b7 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -21,12 +21,15 @@ data: "ca_config": [ { "address": "{{ .connectCA.address }}", + {{- if and .ca.secretName .ca.secretKey }} + "ca_file": "/consul/vault-ca/tls.crt", + {{- end }} "intermediate_pki_path": "{{ .connectCA.intermediatePKIPath }}", "root_pki_path": "{{ .connectCA.rootPKIPath }}", "auth_method": { "type": "kubernetes", "params": { - "role": "{{.consulServerRole}}" + "role": "{{ .consulServerRole }}" } } } diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 77fa3c68de..5a3afeea4d 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -52,6 +52,10 @@ spec: {{- if .Values.global.secretsBackend.vault.enabled }} "vault.hashicorp.com/agent-inject": "true" "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulServerRole }}" + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} {{- if .Values.global.gossipEncryption.secretName }} {{- with .Values.global.gossipEncryption }} "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" @@ -120,6 +124,14 @@ spec: secret: secretName: {{ .Values.server.enterpriseLicense.secretName }} {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + - name: vault-ca + secret: + secretName: {{ .Values.global.secretsBackend.vault.ca.secretName }} + items: + - key: {{ .Values.global.secretsBackend.vault.ca.secretKey }} + path: tls.crt + {{- end }} {{- range .Values.server.extraVolumes }} - name: userconfig-{{ .name }} {{ .type }}: @@ -298,6 +310,11 @@ spec: readOnly: true mountPath: /consul/userconfig/{{ .name }} {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + - name: vault-ca + mountPath: /consul/vault-ca/ + readOnly: true + {{- end }} ports: {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - name: http diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index f83c802e32..73483651db 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -1607,3 +1607,71 @@ rollingUpdate: | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "client/DaemonSet: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 8245fb215e..bb52f7e33f 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -405,4 +405,72 @@ load _helpers . | tee /dev/stderr | yq '.data["additional-connect-ca-config.json"]' | tee /dev/stderr) [ "${actual}" = '"{\"hello\": \"world\"}\n"' ] +} + +@test "server/ConfigMap: doesn't set Vault CA cert in connect CA config by default" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("\"ca_file\": \"/consul/vault-ca/tls.crt\"")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't set Vault CA cert in connect CA config when vault CA secret name is set but secret key is not" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("\"ca_file\": \"/consul/vault-ca/tls.crt\"")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't set Vault CA cert in connect CA config when vault CA secret key is set but secret name is not" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("\"ca_file\": \"/consul/vault-ca/tls.crt\"")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: doesn't set Vault CA cert in connect CA config when both vault CA secret name and key are set" { + cd `chart_dir` + + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.connectCA.address=example.com' \ + --set 'global.secretsBackend.vault.connectCA.rootPKIPath=root' \ + --set 'global.secretsBackend.vault.connectCA.intermediatePKIPath=int' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq '.data["connect-ca-config.json"] | contains("\"ca_file\": \"/consul/vault-ca/tls.crt\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } \ No newline at end of file diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index 909fb647b2..9a180f5d98 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -1492,7 +1492,6 @@ load _helpers . | tee /dev/stderr | yq -r '.spec.template.spec' | tee /dev/stderr) - local actual=$(echo $object | yq -r '.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY")' | tee /dev/stderr) [ "${actual}" = "" ] @@ -1502,3 +1501,119 @@ load _helpers | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "server/StatefulSet: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check that the volume is defined. + local actual=$(echo $object | + yq -r '.spec.volumes[] | select(.name=="vault-ca")' | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that the volume mount is added. + local actual=$(echo $object | + yq -r '.spec.containers[] | select(.name=="consul").volumeMounts[] | select(.name=="vault-ca")' \ + | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that Vault agent annotations are added. + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check that the volume is defined. + local actual=$(echo $object | + yq -r '.spec.volumes[] | select(.name=="vault-ca")' | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that the volume mount is added. + local actual=$(echo $object | + yq -r '.spec.containers[] | select(.name=="consul").volumeMounts[] | select(.name=="vault-ca")' \ + | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that Vault agent annotations are added. + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check that the volume is defined. + local actual=$(echo $object | + yq -r '.spec.volumes[] | select(.name=="vault-ca")' | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that the volume mount is added. + local actual=$(echo $object | + yq -r '.spec.containers[] | select(.name=="consul").volumeMounts[] | select(.name=="vault-ca")' \ + | tee /dev/stderr) + [ "${actual}" = "" ] + + # Check that Vault agent annotations are added. + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check that the volume is defined. + local actual=$(echo $object | + yq -r '.spec.volumes[] | select(.name=="vault-ca").secret.secretName' | tee /dev/stderr) + [ "${actual}" = "ca" ] + + # Check that the volume mount is added. + local actual=$(echo $object | + yq -r '.spec.containers[] | select(.name=="consul").volumeMounts[] | select(.name=="vault-ca")' \ + | tee /dev/stderr) + [ "${actual}" != "" ] + + # Check that Vault agent annotations are added. + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 480e46bee5..ec6b29c2e7 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -152,6 +152,15 @@ global: # and check the name of `metadata.name`. consulClientRole: "" + # Configuration for Vault server CA certificate. This certificate will be mounted + # to any pod where Vault agent needs to run. + ca: + # secretName is the name of the Kubernetes secret that holds the Vault CA certificate. + # A Kubernetes secret must be in the same namespace that Consul is installed into. + secretName: "" + # secretKey is the key within the Kubernetes secret that holds the Vault CA certificate. + secretKey: "" + # Configuration for the Vault Connect CA provider. # The provider will be configured to use the Vault Kubernetes auth method # and therefore requires the role provided by `global.secretsBackend.vault.consulServerRole` From 13282c48eb8c14001238257803e285858add565e Mon Sep 17 00:00:00 2001 From: Saad Date: Mon, 15 Nov 2021 10:31:11 -0800 Subject: [PATCH 13/70] Made an initial try at the consul-k8s upgrade command. Running into issues with the connect-injector webhook not starting on an install? --- cli/cmd/install/install.go | 16 +- cli/cmd/install/presets.go | 53 ++-- cli/cmd/upgrade/upgrade.go | 449 ++++++++++++++++++++++++++++++++ cli/cmd/upgrade/upgrade_test.go | 35 +++ 4 files changed, 524 insertions(+), 29 deletions(-) create mode 100644 cli/cmd/upgrade/upgrade.go create mode 100644 cli/cmd/upgrade/upgrade_test.go diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index 001c1d3c2a..a603692f9c 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -81,7 +81,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range presets { + for name := range Presets { presetList = append(presetList, name) } @@ -313,7 +313,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = mergeMaps(convert(globalNameConsul), vals) + vals = MergeMaps(Convert(GlobalNameConsul), vals) // Dry Run should exit here, no need to actual locate/download the charts. if c.flagDryRun { @@ -454,15 +454,15 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := presets[c.flagPreset].(map[string]interface{}) - vals = mergeMaps(presetMap, vals) + presetMap := Presets[c.flagPreset].(map[string]interface{}) + vals = MergeMaps(presetMap, vals) } return vals, err } -// mergeMaps is a helper function used in Run. Merges two maps giving b precedent. +// MergeMaps is a helper function used in Run. Merges two maps giving b precedent. // @source: https://github.com/helm/helm/blob/main/pkg/cli/values/options.go -func mergeMaps(a, b map[string]interface{}) map[string]interface{} { +func MergeMaps(a, b map[string]interface{}) map[string]interface{} { out := make(map[string]interface{}, len(a)) for k, v := range a { out[k] = v @@ -471,7 +471,7 @@ func mergeMaps(a, b map[string]interface{}) map[string]interface{} { if v, ok := v.(map[string]interface{}); ok { if bv, ok := out[k]; ok { if bv, ok := bv.(map[string]interface{}); ok { - out[k] = mergeMaps(bv, v) + out[k] = MergeMaps(bv, v) continue } } @@ -492,7 +492,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { diff --git a/cli/cmd/install/presets.go b/cli/cmd/install/presets.go index f901d1e930..0305e19366 100644 --- a/cli/cmd/install/presets.go +++ b/cli/cmd/install/presets.go @@ -7,36 +7,47 @@ const ( PresetSecure = "secure" ) -// presets is a map of pre-configured helm values. -var presets = map[string]interface{}{ - PresetDemo: convert(demo), - PresetSecure: convert(secure), +// Presets is a map of pre-configured helm values. +var Presets = map[string]interface{}{ + PresetDemo: Convert(demo), + PresetSecure: Convert(secure), } var demo = ` global: name: consul - metrics: - enabled: true - enableAgentMetrics: true connectInject: enabled: true - metrics: - defaultEnabled: true - defaultEnableMerging: true - enableGatewayMetrics: true server: replicas: 1 -controller: - enabled: true -ui: - enabled: true - service: - enabled: true -prometheus: - enabled: true + bootstrapExpect: 1 ` +// TODO: I don't know why the following hangs for me. +//var demo = ` +//global: +// name: consul +// metrics: +// enabled: true +// enableAgentMetrics: true +//connectInject: +// enabled: true +// metrics: +// defaultEnabled: true +// defaultEnableMerging: true +// enableGatewayMetrics: true +//server: +// replicas: 1 +//controller: +// enabled: true +//ui: +// enabled: true +// service: +// enabled: true +//prometheus: +// enabled: true +//` + var secure = ` global: name: consul @@ -55,13 +66,13 @@ controller: enabled: true ` -var globalNameConsul = ` +var GlobalNameConsul = ` global: name: consul ` // convert is a helper function that converts a YAML string to a map. -func convert(s string) map[string]interface{} { +func Convert(s string) map[string]interface{} { var m map[string]interface{} _ = yaml.Unmarshal([]byte(s), &m) return m diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go new file mode 100644 index 0000000000..b324a24ebf --- /dev/null +++ b/cli/cmd/upgrade/upgrade.go @@ -0,0 +1,449 @@ +package upgrade + +import ( + "errors" + "fmt" + "os" + "strings" + "sync" + "time" + + consulChart "github.com/hashicorp/consul-k8s/charts" + "helm.sh/helm/v3/pkg/chart/loader" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/values" + "helm.sh/helm/v3/pkg/getter" + + "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + helmCLI "helm.sh/helm/v3/pkg/cli" + + "github.com/hashicorp/consul-k8s/cli/cmd/install" + + "github.com/hashicorp/consul-k8s/cli/cmd/common" + "github.com/hashicorp/consul-k8s/cli/cmd/common/flag" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/yaml" +) + +const ( + flagNamePreset = "preset" + defaultPreset = "" + + flagNameConfigFile = "config-file" + flagNameSetStringValues = "set-string" + flagNameSetValues = "set" + flagNameFileValues = "set-file" + + flagNameDryRun = "dry-run" + defaultDryRun = false + + flagNameAutoApprove = "auto-approve" + defaultAutoApprove = false + + flagNameNamespace = "namespace" + + flagNameTimeout = "timeout" + defaultTimeout = "10m" + + flagNameVerbose = "verbose" + defaultVerbose = false + + flagNameWait = "wait" + defaultWait = true +) + +type Command struct { + *common.BaseCommand + + kubernetes kubernetes.Interface + + set *flag.Sets + + flagPreset string + flagNamespace string + flagDryRun bool + flagAutoApprove bool + flagValueFiles []string + flagSetStringValues []string + flagSetValues []string + flagFileValues []string + flagTimeout string + timeoutDuration time.Duration + flagVerbose bool + flagWait bool + + flagKubeConfig string + flagKubeContext string + + once sync.Once + help string +} + +func (c *Command) init() { + // Store all the possible preset values in 'presetList'. Printed in the help message. + var presetList []string + for name := range install.Presets { + presetList = append(presetList, name) + } + + c.set = flag.NewSets() + f := c.set.NewSet("Command Options") + f.BoolVar(&flag.BoolVar{ + Name: flagNameAutoApprove, + Target: &c.flagAutoApprove, + Default: defaultAutoApprove, + Usage: "Skip confirmation prompt.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameDryRun, + Target: &c.flagDryRun, + Default: defaultDryRun, + Usage: "Run pre-install checks and display summary of installation.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameConfigFile, + Aliases: []string{"f"}, + Target: &c.flagValueFiles, + Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNameNamespace, + Target: &c.flagNamespace, + Default: common.DefaultReleaseNamespace, + Usage: "Namespace for the Consul installation.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNamePreset, + Target: &c.flagPreset, + Default: defaultPreset, + Usage: fmt.Sprintf("Use an installation preset, one of %s. Defaults to none", strings.Join(presetList, ", ")), + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameSetValues, + Target: &c.flagSetValues, + Usage: "Set a value to customize. Can be specified multiple times. Supports Consul Helm chart values.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameFileValues, + Target: &c.flagFileValues, + Usage: "Set a value to customize via a file. The contents of the file will be set as the value. Can be " + + "specified multiple times. Supports Consul Helm chart values.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameSetStringValues, + Target: &c.flagSetStringValues, + Usage: "Set a string value to customize. Can be specified multiple times. Supports Consul Helm chart values.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNameTimeout, + Target: &c.flagTimeout, + Default: defaultTimeout, + Usage: "Timeout to wait for installation to be ready.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameVerbose, + Aliases: []string{"v"}, + Target: &c.flagVerbose, + Default: defaultVerbose, + Usage: "Output verbose logs from the install command with the status of resources being installed.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameWait, + Target: &c.flagWait, + Default: defaultWait, + Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", + }) + + f = c.set.NewSet("Global Options") + f.StringVar(&flag.StringVar{ + Name: "kubeconfig", + Aliases: []string{"c"}, + Target: &c.flagKubeConfig, + Default: "", + Usage: "Path to kubeconfig file.", + }) + f.StringVar(&flag.StringVar{ + Name: "context", + Target: &c.flagKubeContext, + Default: "", + Usage: "Kubernetes context to use.", + }) + + c.help = c.set.Help() + + // c.Init() calls the embedded BaseCommand's initialization function. + c.Init() +} + +func (c *Command) Run(args []string) int { + c.once.Do(c.init) + + // The logger is initialized in main with the name cli. Here, we reset the name to install so log lines would be prefixed with install. + c.Log.ResetNamed("upgrade") + + defer common.CloseWithError(c.BaseCommand) + + if err := c.validateFlags(args); err != nil { + c.UI.Output(err.Error()) + return 1 + } + + // helmCLI.New() will create a settings object which is used by the Helm Go SDK calls. + settings := helmCLI.New() + + // Any overrides by our kubeconfig and kubecontext flags is done here. The Kube client that + // is created will use this command's flags first, then the HELM_KUBECONTEXT environment variable, + // then call out to genericclioptions.ConfigFlag + if c.flagKubeConfig != "" { + settings.KubeConfig = c.flagKubeConfig + } + if c.flagKubeContext != "" { + settings.KubeContext = c.flagKubeContext + } + + // Setup logger to stream Helm library logs + var uiLogger = func(s string, args ...interface{}) { + logMsg := fmt.Sprintf(s, args...) + + if c.flagVerbose { + // Only output all logs when verbose is enabled + c.UI.Output(logMsg, terminal.WithLibraryStyle()) + } else { + // When verbose is not enabled, output all logs except not ready messages for resources + if !strings.Contains(logMsg, "not ready") { + c.UI.Output(logMsg, terminal.WithLibraryStyle()) + } + } + } + + // Set up the kubernetes client to use for non Helm SDK calls to the Kubernetes API + // The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will + // use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. + if c.kubernetes == nil { + restConfig, err := settings.RESTClientGetter().ToRESTConfig() + if err != nil { + c.UI.Output("Retrieving Kubernetes auth: %v", err, terminal.WithErrorStyle()) + return 1 + } + c.kubernetes, err = kubernetes.NewForConfig(restConfig) + if err != nil { + c.UI.Output("Initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) + return 1 + } + } + + c.UI.Output("Pre-Upgrade Checks", terminal.WithHeaderStyle()) + + // Note the logic here, common's CheckForInstallations function returns an error if + // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) + return 1 + } else { + c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) + c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + } + + // Handle preset, value files, and set values logic. + vals, err := c.mergeValuesFlagsWithPrecedence(settings) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + valuesYaml, err := yaml.Marshal(vals) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Print out the upgrade summary. + // TODO: Fix this, it's just incorrect. + if !c.flagAutoApprove { + c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) + c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + + if len(vals) == 0 { + c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) + } else { + c.UI.Output("Overrides:"+"\n"+string(valuesYaml), terminal.WithInfoStyle()) + } + } + + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + + if !c.flagAutoApprove && !c.flagDryRun { + confirmation, err := c.UI.Input(&terminal.Input{ + Prompt: "Proceed with upgrade? (y/N)", + Style: terminal.InfoStyle, + Secret: false, + }) + + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + if common.Abort(confirmation) { + c.UI.Output("Upgrade aborted. To learn how to customize your upgrade, run:\nconsul-k8s upgrade --help", terminal.WithInfoStyle()) + return 1 + } + } + + if !c.flagDryRun { + c.UI.Output("Running Upgrade", terminal.WithHeaderStyle()) + } else { + c.UI.Output("Performing Dry Upgrade", terminal.WithHeaderStyle()) + } + + // Setup action configuration for Helm Go SDK function calls. + actionConfig := new(action.Configuration) + actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Setup the upgrade action. + // TODO: So many things to add here. + upgrade := action.NewUpgrade(actionConfig) + upgrade.Namespace = c.flagNamespace + upgrade.DryRun = c.flagDryRun + upgrade.Wait = c.flagWait + upgrade.Timeout = c.timeoutDuration + + // Read the embedded chart files into []*loader.BufferedFile. + chartFiles, err := common.ReadChartFiles(consulChart.ConsulHelmChart, common.TopLevelChartDirName) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Create a *chart.Chart object from the files to run the installation from. + chart, err := loader.LoadFiles(chartFiles) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + c.UI.Output("Downloaded charts", terminal.WithSuccessStyle()) + + // Run the install. + re, err := upgrade.Run(common.DefaultReleaseName, chart, vals) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Dry Run should exit here, printing the release's config. + if c.flagDryRun { + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) + + configYaml, err := yaml.Marshal(re.Config) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + if len(re.Config) == 0 { + c.UI.Output("Config: "+string(configYaml), terminal.WithInfoStyle()) + } else { + c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) + } + + return 0 + } + + c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + + return 0 +} + +// TODO: Make sure the following function is consistent. +// TODO: Move these functions to common? +// validateFlags is a helper function that performs sanity checks on the user's provided flags. +func (c *Command) validateFlags(args []string) error { + if err := c.set.Parse(args); err != nil { + return err + } + if len(c.set.Args()) > 0 { + return errors.New("should have no non-flag arguments") + } + if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { + return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) + } + if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) + } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } + duration, err := time.ParseDuration(c.flagTimeout) + if err != nil { + return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) + } + c.timeoutDuration = duration + if len(c.flagValueFiles) != 0 { + for _, filename := range c.flagValueFiles { + if _, err := os.Stat(filename); err != nil && os.IsNotExist(err) { + return fmt.Errorf("File '%s' does not exist.", filename) + } + } + } + + if c.flagDryRun { + c.UI.Output("Performing dry run installation.", terminal.WithInfoStyle()) + } + return nil +} + +// TODO: Make sure the following function is consistent. +// TODO: Move these functions to common? +// validLabel is a helper function that checks if a string follows RFC 1123 labels. +func validLabel(s string) bool { + for i, c := range s { + alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') + // If the character is not the last or first, it can be a dash. + if i != 0 && i != (len(s)-1) { + alphanum = alphanum || (c == '-') + } + if !alphanum { + return false + } + } + return true +} + +// TODO: Move these functions to common? +// mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the +// installation based on the following precedence order from lowest to highest: +// 1. -preset +// 2. -f values-file +// 3. -set +// 4. -set-string +// 5. -set-file +// For example, -set-file will override a value provided via -set. +// Within each of these groups the rightmost flag value has the highest precedence. +func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) (map[string]interface{}, error) { + p := getter.All(settings) + v := &values.Options{ + ValueFiles: c.flagValueFiles, + StringValues: c.flagSetStringValues, + Values: c.flagSetValues, + FileValues: c.flagFileValues, + } + vals, err := v.MergeValues(p) + if err != nil { + return nil, fmt.Errorf("error merging values: %s", err) + } + if c.flagPreset != defaultPreset { + // Note the ordering of the function call, presets have lower precedence than set vals. + presetMap := install.Presets[c.flagPreset].(map[string]interface{}) + vals = install.MergeMaps(presetMap, vals) + } + return vals, err +} diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go new file mode 100644 index 0000000000..52c06e127d --- /dev/null +++ b/cli/cmd/upgrade/upgrade_test.go @@ -0,0 +1,35 @@ +package upgrade + +import ( + "os" + "testing" + + "github.com/hashicorp/consul-k8s/cli/cmd/common" + "github.com/hashicorp/go-hclog" +) + +/* Just using this to play around with the Go debugger. */ +func TestDebugger(t *testing.T) { + c := getInitializedCommand(t) + c.Run([]string{"-dry-run"}) +} + +// getInitializedCommand sets up a command struct for tests. +func getInitializedCommand(t *testing.T) *Command { + t.Helper() + log := hclog.New(&hclog.LoggerOptions{ + Name: "cli", + Level: hclog.Info, + Output: os.Stdout, + }) + + baseCommand := &common.BaseCommand{ + Log: log, + } + + c := &Command{ + BaseCommand: baseCommand, + } + c.init() + return c +} From a9260b34feef4d6fc36d2b652bc1a2bdc120f3c7 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 10:14:20 -0800 Subject: [PATCH 14/70] Upgrade commit --- cli/cmd/upgrade/upgrade.go | 11 +++++++++++ cli/commands.go | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index b324a24ebf..99407416c4 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -238,6 +238,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { @@ -447,3 +448,13 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } return vals, err } + +func (c *Command) Help() string { + c.once.Do(c.init) + s := "Usage: consul-k8s upgrade [flags]" + "\n" + "Upgrade Consul from an existing installation." + "\n" + return s + "\n" + c.help +} + +func (c *Command) Synopsis() string { + return "Upgrade Consul on Kubernetes." +} diff --git a/cli/commands.go b/cli/commands.go index 50da5806d4..17726ac5aa 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/consul-k8s/cli/cmd/install" "github.com/hashicorp/consul-k8s/cli/cmd/status" "github.com/hashicorp/consul-k8s/cli/cmd/uninstall" + "github.com/hashicorp/consul-k8s/cli/cmd/upgrade" cmdversion "github.com/hashicorp/consul-k8s/cli/cmd/version" "github.com/hashicorp/consul-k8s/cli/version" "github.com/hashicorp/go-hclog" @@ -36,6 +37,11 @@ func initializeCommands(ctx context.Context, log hclog.Logger) (*common.BaseComm BaseCommand: baseCommand, }, nil }, + "upgrade": func() (cli.Command, error) { + return &upgrade.Command{ + BaseCommand: baseCommand, + }, nil + }, "version": func() (cli.Command, error) { return &cmdversion.Command{ BaseCommand: baseCommand, From 412117dca2a3cff0e70545e2bf19382f7692f9c9 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 23:55:46 -0800 Subject: [PATCH 15/70] First pass at upgrade was successful. --- cli/cmd/upgrade/upgrade.go | 35 ++++++++++++--------------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 99407416c4..b115f60e83 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -61,7 +61,6 @@ type Command struct { set *flag.Sets flagPreset string - flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -107,12 +106,6 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) - f.StringVar(&flag.StringVar{ - Name: flagNameNamespace, - Target: &c.flagNamespace, - Default: common.DefaultReleaseNamespace, - Usage: "Namespace for the Consul installation.", - }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -237,6 +230,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) @@ -245,6 +239,8 @@ func (c *Command) Run(args []string) int { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + + foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -264,7 +260,7 @@ func (c *Command) Run(args []string) int { if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -273,10 +269,11 @@ func (c *Command) Run(args []string) int { } } - // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // TODO: Fix this! + //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + //// aren't double prefixed with "consul-consul-...". + //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -303,7 +300,7 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 @@ -312,7 +309,7 @@ func (c *Command) Run(args []string) int { // Setup the upgrade action. // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = c.flagNamespace + upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -341,8 +338,6 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) - configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -354,11 +349,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) return 0 } - c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) return 0 } @@ -379,10 +374,6 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } - if !validLabel(c.flagNamespace) { - return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ - "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) - } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 52c06e127d..ffb220efc7 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-dry-run"}) + c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) } // getInitializedCommand sets up a command struct for tests. From 855a94f28574edd840fd8372972c3946289b6abe Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Tue, 23 Nov 2021 14:20:03 -0800 Subject: [PATCH 16/70] notes from sync with Saad on what's left --- cli/cmd/upgrade/upgrade.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index b115f60e83..49a11800fc 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,6 +51,9 @@ const ( flagNameWait = "wait" defaultWait = true + // action/upgrade + // --install, --reset-values vs --reuse-values, + // atomic ) type Command struct { @@ -256,7 +259,7 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this, it's just incorrect. + // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -269,7 +272,7 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! + // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources //// aren't double prefixed with "consul-consul-...". @@ -307,7 +310,7 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. + // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun From bcfd881060b6951e87f8d6b112213c898824ebb3 Mon Sep 17 00:00:00 2001 From: Saad Date: Mon, 15 Nov 2021 10:31:11 -0800 Subject: [PATCH 17/70] Made an initial try at the consul-k8s upgrade command. Running into issues with the connect-injector webhook not starting on an install? --- cli/cmd/upgrade/upgrade.go | 42 ++++++++++++++++++--------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 49a11800fc..a86f1a49f3 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,9 +51,6 @@ const ( flagNameWait = "wait" defaultWait = true - // action/upgrade - // --install, --reset-values vs --reuse-values, - // atomic ) type Command struct { @@ -64,6 +61,7 @@ type Command struct { set *flag.Sets flagPreset string + flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -109,6 +107,12 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) + f.StringVar(&flag.StringVar{ + Name: flagNameNamespace, + Target: &c.flagNamespace, + Default: common.DefaultReleaseNamespace, + Usage: "Namespace for the Consul installation.", + }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -233,17 +237,13 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. - foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { - // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) - - foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -259,11 +259,10 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -272,11 +271,10 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. - //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - //// aren't double prefixed with "consul-consul-...". - //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -303,16 +301,16 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 } // Setup the upgrade action. - // TODO: So many things to add here. (Could add upgrade.<> features) + // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = foundNamespace + upgrade.Namespace = c.flagNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -341,6 +339,8 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) + configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -352,11 +352,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) + return 0 } - c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) return 0 } @@ -377,6 +377,10 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index ffb220efc7..52c06e127d 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) + c.Run([]string{"-dry-run"}) } // getInitializedCommand sets up a command struct for tests. From c01583e06020f2913f2abd783567ba7950de307b Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 10:14:20 -0800 Subject: [PATCH 18/70] Upgrade commit --- cli/cmd/upgrade/upgrade.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index a86f1a49f3..93ebb1cac9 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -238,6 +238,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { From cdcccfd51f13e2814354fedae7898203e135bec0 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 23:55:46 -0800 Subject: [PATCH 19/70] First pass at upgrade was successful. --- cli/cmd/upgrade/upgrade.go | 35 ++++++++++++--------------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 93ebb1cac9..9ec724f604 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -61,7 +61,6 @@ type Command struct { set *flag.Sets flagPreset string - flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -107,12 +106,6 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) - f.StringVar(&flag.StringVar{ - Name: flagNameNamespace, - Target: &c.flagNamespace, - Default: common.DefaultReleaseNamespace, - Usage: "Namespace for the Consul installation.", - }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -237,6 +230,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) @@ -245,6 +239,8 @@ func (c *Command) Run(args []string) int { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + + foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -263,7 +259,7 @@ func (c *Command) Run(args []string) int { if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -272,10 +268,11 @@ func (c *Command) Run(args []string) int { } } - // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // TODO: Fix this! + //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + //// aren't double prefixed with "consul-consul-...". + //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -302,7 +299,7 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 @@ -311,7 +308,7 @@ func (c *Command) Run(args []string) int { // Setup the upgrade action. // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = c.flagNamespace + upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -340,8 +337,6 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) - configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -353,11 +348,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) return 0 } - c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) return 0 } @@ -378,10 +373,6 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } - if !validLabel(c.flagNamespace) { - return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ - "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) - } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 52c06e127d..ffb220efc7 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-dry-run"}) + c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) } // getInitializedCommand sets up a command struct for tests. From eb68ee8a3b1586a478370347428df7b181fdcecc Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Tue, 23 Nov 2021 14:20:03 -0800 Subject: [PATCH 20/70] notes from sync with Saad on what's left --- cli/cmd/upgrade/upgrade.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 9ec724f604..49a11800fc 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,6 +51,9 @@ const ( flagNameWait = "wait" defaultWait = true + // action/upgrade + // --install, --reset-values vs --reuse-values, + // atomic ) type Command struct { @@ -256,6 +259,7 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. + // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -268,7 +272,7 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! + // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources //// aren't double prefixed with "consul-consul-...". @@ -306,7 +310,7 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. + // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun From ed58f2f8b82044d129d885c0a9735d3b29619f19 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 1 Dec 2021 14:49:35 -0500 Subject: [PATCH 21/70] Some basic cleanup --- cli/cmd/upgrade/upgrade.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 49a11800fc..e356eb34a2 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -174,8 +174,6 @@ func (c *Command) init() { func (c *Command) Run(args []string) int { c.once.Do(c.init) - - // The logger is initialized in main with the name cli. Here, we reset the name to install so log lines would be prefixed with install. c.Log.ResetNamed("upgrade") defer common.CloseWithError(c.BaseCommand) @@ -259,7 +257,6 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -272,11 +269,10 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. - //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - //// aren't double prefixed with "consul-consul-...". - //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -310,7 +306,6 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun @@ -362,8 +357,7 @@ func (c *Command) Run(args []string) int { } // TODO: Make sure the following function is consistent. -// TODO: Move these functions to common? -// validateFlags is a helper function that performs sanity checks on the user's provided flags. +// validateFlags checks that the user's provided flags are valid. func (c *Command) validateFlags(args []string) error { if err := c.set.Parse(args); err != nil { return err @@ -372,7 +366,7 @@ func (c *Command) validateFlags(args []string) error { return errors.New("should have no non-flag arguments") } if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { - return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) + return fmt.Errorf("cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) @@ -385,7 +379,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 { for _, filename := range c.flagValueFiles { if _, err := os.Stat(filename); err != nil && os.IsNotExist(err) { - return fmt.Errorf("File '%s' does not exist.", filename) + return fmt.Errorf("file '%s' does not exist", filename) } } } @@ -397,8 +391,7 @@ func (c *Command) validateFlags(args []string) error { } // TODO: Make sure the following function is consistent. -// TODO: Move these functions to common? -// validLabel is a helper function that checks if a string follows RFC 1123 labels. +// validLabel checks if a string follows RFC 1123 labels. func validLabel(s string) bool { for i, c := range s { alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') @@ -413,7 +406,6 @@ func validLabel(s string) bool { return true } -// TODO: Move these functions to common? // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset From 2666ff6a83aa5a5ffeb90e7ed6a82fc84467f593 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 1 Dec 2021 15:08:30 -0500 Subject: [PATCH 22/70] Remove TestDebugger --- cli/cmd/upgrade/upgrade_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index ffb220efc7..3f68dd0548 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -8,12 +8,6 @@ import ( "github.com/hashicorp/go-hclog" ) -/* Just using this to play around with the Go debugger. */ -func TestDebugger(t *testing.T) { - c := getInitializedCommand(t) - c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) -} - // getInitializedCommand sets up a command struct for tests. func getInitializedCommand(t *testing.T) *Command { t.Helper() From 1a9dcf96a55274281d975df1aafc45f3e68b120c Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 2 Dec 2021 14:37:35 -0500 Subject: [PATCH 23/70] Remove validateLabels (unused) --- cli/cmd/upgrade/upgrade.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index e356eb34a2..3830f4f134 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -390,22 +390,6 @@ func (c *Command) validateFlags(args []string) error { return nil } -// TODO: Make sure the following function is consistent. -// validLabel checks if a string follows RFC 1123 labels. -func validLabel(s string) bool { - for i, c := range s { - alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') - // If the character is not the last or first, it can be a dash. - if i != 0 && i != (len(s)-1) { - alphanum = alphanum || (c == '-') - } - if !alphanum { - return false - } - } - return true -} - // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset From fd8255d53f55d701e5c1eece354d61fa5631cffc Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 2 Dec 2021 14:56:45 -0500 Subject: [PATCH 24/70] Add the namespace and install flags --- cli/cmd/upgrade/upgrade.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 3830f4f134..8b494d4a10 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -41,7 +41,8 @@ const ( flagNameAutoApprove = "auto-approve" defaultAutoApprove = false - flagNameNamespace = "namespace" + flagNamespace = "namespace" + defaultNamespace = "consul" flagNameTimeout = "timeout" defaultTimeout = "10m" @@ -51,9 +52,9 @@ const ( flagNameWait = "wait" defaultWait = true - // action/upgrade - // --install, --reset-values vs --reuse-values, - // atomic + + flagInstall = "install" + defaultInstall = false ) type Command struct { @@ -66,6 +67,7 @@ type Command struct { flagPreset string flagDryRun bool flagAutoApprove bool + flagNamespace string flagValueFiles []string flagSetStringValues []string flagSetValues []string @@ -74,6 +76,7 @@ type Command struct { timeoutDuration time.Duration flagVerbose bool flagWait bool + flagInstall bool flagKubeConfig string flagKubeContext string @@ -97,6 +100,12 @@ func (c *Command) init() { Default: defaultAutoApprove, Usage: "Skip confirmation prompt.", }) + f.StringVar(&flag.StringVar{ + Name: flagNamespace, + Target: &c.flagNamespace, + Default: defaultNamespace, + Usage: "Namespace where Consul is installed. Defaults to 'consul'.", + }) f.BoolVar(&flag.BoolVar{ Name: flagNameDryRun, Target: &c.flagDryRun, @@ -150,6 +159,12 @@ func (c *Command) init() { Default: defaultWait, Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", }) + f.BoolVar(&flag.BoolVar{ + Name: flagInstall, + Target: &c.flagInstall, + Default: defaultInstall, + Usage: "Fall back to installing Consul if not already installed. Defaults to false.", + }) f = c.set.NewSet("Global Options") f.StringVar(&flag.StringVar{ From bf38f5b39577a8a981c90d41d4032ad1a8f62590 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 12:01:56 -0500 Subject: [PATCH 25/70] Add flag test and remove install option --- cli/cmd/upgrade/upgrade.go | 34 ++++++++++++++++---------- cli/cmd/upgrade/upgrade_test.go | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 8b494d4a10..c19d5ceee3 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -52,9 +52,6 @@ const ( flagNameWait = "wait" defaultWait = true - - flagInstall = "install" - defaultInstall = false ) type Command struct { @@ -159,12 +156,6 @@ func (c *Command) init() { Default: defaultWait, Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", }) - f.BoolVar(&flag.BoolVar{ - Name: flagInstall, - Target: &c.flagInstall, - Default: defaultInstall, - Usage: "Fall back to installing Consul if not already installed. Defaults to false.", - }) f = c.set.NewSet("Global Options") f.StringVar(&flag.StringVar{ @@ -246,10 +237,9 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. - foundNamespace := "" + var foundNamespace string if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { - // TODO: Don't just error, install. - c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) + c.UI.Output("could not find existing Consul installation - run `consul-k8s install`") return 1 } else { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) @@ -371,7 +361,6 @@ func (c *Command) Run(args []string) int { return 0 } -// TODO: Make sure the following function is consistent. // validateFlags checks that the user's provided flags are valid. func (c *Command) validateFlags(args []string) error { if err := c.set.Parse(args); err != nil { @@ -386,6 +375,10 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) @@ -405,6 +398,21 @@ func (c *Command) validateFlags(args []string) error { return nil } +// validLabel is a helper function that checks if a string follows RFC 1123 labels. +func validLabel(s string) bool { + for i, c := range s { + alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') + // If the character is not the last or first, it can be a dash. + if i != 0 && i != (len(s)-1) { + alphanum = alphanum || (c == '-') + } + if !alphanum { + return false + } + } + return true +} + // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 3f68dd0548..cd47928f9f 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -8,6 +8,49 @@ import ( "github.com/hashicorp/go-hclog" ) +// TestValidateFlags tests the validate flags function. +func TestValidateFlags(t *testing.T) { + // The following cases should all error, if they fail to this test fails. + testCases := []struct { + description string + input []string + }{ + { + "Should disallow non-flag arguments.", + []string{"foo", "-auto-approve"}, + }, + { + "Should disallow specifying both values file AND presets.", + []string{"-f='f.txt'", "-preset=demo"}, + }, + { + "Should error on invalid presets.", + []string{"-preset=foo"}, + }, + { + "Should error on invalid timeout.", + []string{"-timeout=invalid-timeout"}, + }, + { + "Should error on an invalid namespace.", + []string{"-namespace=\" nsWithSpace\""}, + }, + { + "Should have errored on a non-existant file.", + []string{"-f=\"does_not_exist.txt\""}, + }, + } + + for _, testCase := range testCases { + c := getInitializedCommand(t) + t.Run(testCase.description, func(t *testing.T) { + if err := c.validateFlags(testCase.input); err == nil { + t.Errorf("Test case should have failed.") + } + }) + } +} + // getInitializedCommand sets up a command struct for tests. func getInitializedCommand(t *testing.T) *Command { t.Helper() From b6a91c2dae7a2a004bcf7f9e435cca615aea1b79 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 12:28:11 -0500 Subject: [PATCH 26/70] Move presets into a config package --- cli/cmd/install/install.go | 12 +++++++----- cli/cmd/upgrade/upgrade.go | 10 +++++----- cli/{cmd/install => config}/presets.go | 9 +++++---- 3 files changed, 17 insertions(+), 14 deletions(-) rename cli/{cmd/install => config}/presets.go (90%) diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index a603692f9c..30c938f258 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -3,16 +3,18 @@ package install import ( "errors" "fmt" - k8serrors "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" "time" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + consulChart "github.com/hashicorp/consul-k8s/charts" "github.com/hashicorp/consul-k8s/cli/cmd/common" "github.com/hashicorp/consul-k8s/cli/cmd/common/flag" "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + "github.com/hashicorp/consul-k8s/cli/config" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" helmCLI "helm.sh/helm/v3/pkg/cli" @@ -81,7 +83,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range Presets { + for name := range config.Presets { presetList = append(presetList, name) } @@ -313,7 +315,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = MergeMaps(Convert(GlobalNameConsul), vals) + vals = MergeMaps(config.Convert(config.GlobalNameConsul), vals) // Dry Run should exit here, no need to actual locate/download the charts. if c.flagDryRun { @@ -454,7 +456,7 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := Presets[c.flagPreset].(map[string]interface{}) + presetMap := config.Presets[c.flagPreset].(map[string]interface{}) vals = MergeMaps(presetMap, vals) } return vals, err @@ -492,7 +494,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := config.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index c19d5ceee3..e85f8b87d9 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -16,6 +16,7 @@ import ( "helm.sh/helm/v3/pkg/getter" "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + "github.com/hashicorp/consul-k8s/cli/config" helmCLI "helm.sh/helm/v3/pkg/cli" "github.com/hashicorp/consul-k8s/cli/cmd/install" @@ -73,7 +74,6 @@ type Command struct { timeoutDuration time.Duration flagVerbose bool flagWait bool - flagInstall bool flagKubeConfig string flagKubeContext string @@ -85,7 +85,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range install.Presets { + for name := range config.Presets { presetList = append(presetList, name) } @@ -277,7 +277,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + vals = install.MergeMaps(config.Convert(config.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -372,7 +372,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := config.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { @@ -436,7 +436,7 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := install.Presets[c.flagPreset].(map[string]interface{}) + presetMap := config.Presets[c.flagPreset].(map[string]interface{}) vals = install.MergeMaps(presetMap, vals) } return vals, err diff --git a/cli/cmd/install/presets.go b/cli/config/presets.go similarity index 90% rename from cli/cmd/install/presets.go rename to cli/config/presets.go index 0305e19366..557cb24363 100644 --- a/cli/cmd/install/presets.go +++ b/cli/config/presets.go @@ -1,4 +1,4 @@ -package install +package config import "sigs.k8s.io/yaml" @@ -13,7 +13,7 @@ var Presets = map[string]interface{}{ PresetSecure: Convert(secure), } -var demo = ` +const demo = ` global: name: consul connectInject: @@ -24,6 +24,7 @@ server: ` // TODO: I don't know why the following hangs for me. +// TODO: This was hanging for Saad. I will look into it. //var demo = ` //global: // name: consul @@ -48,7 +49,7 @@ server: // enabled: true //` -var secure = ` +const secure = ` global: name: consul gossipEncryption: @@ -66,7 +67,7 @@ controller: enabled: true ` -var GlobalNameConsul = ` +const GlobalNameConsul = ` global: name: consul ` From 1fd8497f4f72ab4670e0ead118ca2942146a1347 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 14:00:59 -0500 Subject: [PATCH 27/70] Add Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11988f4b27..8143b1983d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ BREAKING CHANGES: * Update minimum go version for project to 1.17 [[GH-878](https://github.com/hashicorp/consul-k8s/pull/878)] +FEATURES: +* CLI + * Add `upgrade` command to modify Consul installation on Kubernetes. [[GH-898](https://github.com/hashicorp/consul-k8s/pull/898)] + IMPROVEMENTS: * CLI * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] From e0f3b71702a9083798d417ae17cb7857eb4c4b00 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Mon, 6 Dec 2021 14:26:29 -0500 Subject: [PATCH 28/70] Fail if partitions enabled with federation (#892) * Fail if both adminPartitions and wan federation are enabled. * Update CHANGELOG and fix indentation. --- CHANGELOG.md | 13 +++++++------ charts/consul/templates/client-daemonset.yaml | 1 + charts/consul/templates/server-statefulset.yaml | 1 + charts/consul/test/unit/client-daemonset.bats | 12 ++++++++++++ charts/consul/test/unit/server-statefulset.bats | 15 +++++++++++++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1165ade1f4..873d49b793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,21 @@ ## UNRELEASED BREAKING CHANGES: -* Update minimum go version for project to 1.17 [[GH-878](https://github.com/hashicorp/consul-k8s/pull/878)] +* Control Plane + * Update minimum go version for project to 1.17 [[GH-878](https://github.com/hashicorp/consul-k8s/pull/878)] IMPROVEMENTS: * CLI - * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] + * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] * Control Plane - * Add a label "managed-by" to every secret the control-plane creates. Only delete said secrets on an uninstall. [[GH-835](https://github.com/hashicorp/consul-k8s/pull/835)] + * Add a label "managed-by" to every secret the control-plane creates. Only delete said secrets on an uninstall. [[GH-835](https://github.com/hashicorp/consul-k8s/pull/835)] * Add support for labeling a Kubernetes service with `consul.hashicorp.com/service-ignore` to prevent services from being registered in Consul. [[GH-858](https://github.com/hashicorp/consul-k8s/pull/858)] +* Helm Chart + * Fail an installation/upgrade if WAN federation and Admin Partitions are both enabled. [[GH-892](https://github.com/hashicorp/consul-k8s/issues/892)] BUG FIXES: * Control Plane: - * Add a workaround to check that the ACL token is replicated to other Consul servers. [[GH-862](https://github.com/hashicorp/consul-k8s/issues/862)] - -BUG FIXES: + * Add a workaround to check that the ACL token is replicated to other Consul servers. [[GH-862](https://github.com/hashicorp/consul-k8s/issues/862)] * Helm Chart * Admin Partitions **(Consul Enterprise only)**: Do not mount Consul CA certs to partition-init job if `externalServers.useSystemRoots` is `true`. [[GH-885](https://github.com/hashicorp/consul-k8s/pull/885)] diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index c98265480d..3b03c17fa8 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -2,6 +2,7 @@ {{- if (and (and .Values.global.tls.enabled .Values.global.tls.httpsOnly) (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics))}}{{ fail "global.metrics.enableAgentMetrics cannot be enabled if TLS (HTTPS only) is enabled" }}{{ end -}} {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (and .Values.global.adminPartitions.enabled $serverEnabled (ne .Values.global.adminPartitions.name "default"))}}{{ fail "global.adminPartitions.name has to be \"default\" in the server cluster" }}{{ end -}} +{{- if and .Values.global.federation.enabled .Values.global.adminPartitions.enabled }}{{ fail "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" }}{{ end }} # DaemonSet to run the Consul clients on every node. apiVersion: apps/v1 kind: DaemonSet diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 2380486793..af43a146e3 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -1,4 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if and .Values.global.federation.enabled .Values.global.adminPartitions.enabled }}{{ fail "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" }}{{ end }} {{- if and .Values.global.federation.enabled (not .Values.global.tls.enabled) }}{{ fail "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" }}{{ end }} {{- if and .Values.global.federation.enabled (not .Values.meshGateway.enabled) }}{{ fail "If global.federation.enabled is true, meshGateway.enabled must be true because mesh gateways are required for federation" }}{{ end }} {{- if and .Values.server.serverCert.secretName (not .Values.global.tls.caCert.secretName) }}{{ fail "If server.serverCert.secretName is provided, global.tls.caCert must also be provided" }}{{ end }} diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index 20b5aac856..848243c8f8 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -1465,6 +1465,18 @@ rollingUpdate: [[ "$output" =~ "global.adminPartitions.name has to be \"default\" in the server cluster" ]] } +@test "client/DaemonSet: federation and admin partitions cannot be enabled together" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.adminPartitions.enabled=true' \ + --set 'global.federation.enabled=true' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" ]] +} + #-------------------------------------------------------------------- # extraContainers diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index e11018f279..95a36423bd 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -52,6 +52,21 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# admin-partitions + +@test "server/StatefulSet: federation and admin partitions cannot be enabled together" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.adminPartitions.enabled=true' \ + --set 'global.federation.enabled=true' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" ]] +} + #-------------------------------------------------------------------- # image From d08821b58b9e3a9a16a169dcc78491f3c4bca7df Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:04:58 -0800 Subject: [PATCH 29/70] Change error handling when scraping metrics (#551) * If Envoy returns an error then also respond with a 500 in our merged metrics response so that Prometheus will know that we had an error, not that there are no metrics. * If the service metrics return with a non-2xx status code then don't include the response body in the merged metrics. This will stop issues where users accidentally turn on metrics merging but they don't have an exporter and so their metrics endpoint returns 404. I could have responded with a 500 in this case in order to indicate that there is an error, however I think it's more likely that users are accidentally turning on metrics merging and the error indication is accomplished via a new metric (see below). * Append a new metric that indicates the success of the service scraping. This can be used for alerting by users since the response code of the service metrics response is discarded: * success: consul_metrics_merging_service_metrics_success 1 * fail: consul_metrics_merging_service_metrics_success 0 * modify logging to use key/value pairs * Fixes #546 --- CHANGELOG.md | 4 + .../subcommand/consul-sidecar/command.go | 80 +++++++++++--- .../subcommand/consul-sidecar/command_test.go | 100 +++++++++++------- 3 files changed, 131 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 873d49b793..d977798e5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ BREAKING CHANGES: * Control Plane * Update minimum go version for project to 1.17 [[GH-878](https://github.com/hashicorp/consul-k8s/pull/878)] + * Add boolean metric to merged metrics response `consul_merged_service_metrics_success` to indicate if service metrics were + scraped successfully. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] IMPROVEMENTS: * CLI @@ -16,6 +18,8 @@ IMPROVEMENTS: BUG FIXES: * Control Plane: * Add a workaround to check that the ACL token is replicated to other Consul servers. [[GH-862](https://github.com/hashicorp/consul-k8s/issues/862)] + * Return 500 on prometheus response if unable to get metrics from Envoy. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] + * Don't include body of failed service metrics calls in merged metrics response. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] * Helm Chart * Admin Partitions **(Consul Enterprise only)**: Do not mount Consul CA certs to partition-init job if `externalServers.useSystemRoots` is `true`. [[GH-885](https://github.com/hashicorp/consul-k8s/pull/885)] diff --git a/control-plane/subcommand/consul-sidecar/command.go b/control-plane/subcommand/consul-sidecar/command.go index dcb05199ba..b6ff0d9d39 100644 --- a/control-plane/subcommand/consul-sidecar/command.go +++ b/control-plane/subcommand/consul-sidecar/command.go @@ -21,8 +21,13 @@ import ( "github.com/mitchellh/cli" ) -const metricsServerShutdownTimeout = 5 * time.Second -const envoyMetricsAddr = "http://127.0.0.1:19000/stats/prometheus" +const ( + metricsServerShutdownTimeout = 5 * time.Second + envoyMetricsAddr = "http://127.0.0.1:19000/stats/prometheus" + // prometheusServiceMetricsSuccessKey is the key of the prometheus metric used to + // indicate if service metrics were scraped successfully. + prometheusServiceMetricsSuccessKey = "consul_merged_service_metrics_success" +) type Command struct { UI cli.Ui @@ -240,27 +245,36 @@ func (c *Command) createMergedMetricsServer() *http.Server { mergedMetricsServerAddr := fmt.Sprintf("127.0.0.1:%s", c.flagMergedMetricsPort) server := &http.Server{Addr: mergedMetricsServerAddr, Handler: mux} + // http.Client satisfies the metricsGetter interface. // The default http.Client timeout is indefinite, so adding a timeout makes // sure that requests don't hang. client := &http.Client{ Timeout: time.Second * 10, } - // http.Client satisfies the metricsGetter interface. - c.envoyMetricsGetter = client - c.serviceMetricsGetter = client + + // During tests these may already be set to mocks. + if c.envoyMetricsGetter == nil { + c.envoyMetricsGetter = client + } + if c.serviceMetricsGetter == nil { + c.serviceMetricsGetter = client + } return server } // mergedMetricsHandler has the logic to append both Envoy and service metrics // together, logging if it's unsuccessful at either. +// If the Envoy scrape fails, we respond with a 500 code which follows the Prometheus +// exporter guidelines. If the service scrape fails, we respond with a 200 so +// that the Envoy metrics are still scraped. +// We also include a metric line in each response indicating the success or +// failure of the service metric scraping. func (c *Command) mergedMetricsHandler(rw http.ResponseWriter, _ *http.Request) { - envoyMetrics, err := c.envoyMetricsGetter.Get(envoyMetricsAddr) if err != nil { - // If there is an error scraping Envoy, we want the handler to return - // without writing anything to the response, and log the error. - c.logger.Error(fmt.Sprintf("Error scraping Envoy proxy metrics: %s", err.Error())) + c.logger.Error("Error scraping Envoy proxy metrics", "err", err) + http.Error(rw, fmt.Sprintf("Error scraping Envoy proxy metrics: %s", err), http.StatusInternalServerError) return } @@ -273,18 +287,22 @@ func (c *Command) mergedMetricsHandler(rw http.ResponseWriter, _ *http.Request) }() envoyMetricsBody, err := ioutil.ReadAll(envoyMetrics.Body) if err != nil { - c.logger.Error(fmt.Sprintf("Couldn't read Envoy proxy metrics: %s", err.Error())) + c.logger.Error("Could not read Envoy proxy metrics", "err", err) + http.Error(rw, fmt.Sprintf("Could not read Envoy proxy metrics: %s", err), http.StatusInternalServerError) return } - _, err = rw.Write(envoyMetricsBody) - if err != nil { - c.logger.Error(fmt.Sprintf("Error writing envoy metrics body: %s", err.Error())) + if non2xxCode(envoyMetrics.StatusCode) { + c.logger.Error("Received non-2xx status code scraping Envoy proxy metrics", "code", envoyMetrics.StatusCode, "response", string(envoyMetricsBody)) + http.Error(rw, fmt.Sprintf("Received non-2xx status code scraping Envoy proxy metrics: %d: %s", envoyMetrics.StatusCode, string(envoyMetricsBody)), http.StatusInternalServerError) + return } + writeResponse(rw, envoyMetricsBody, "envoy metrics", c.logger) serviceMetricsAddr := fmt.Sprintf("http://127.0.0.1:%s%s", c.flagServiceMetricsPort, c.flagServiceMetricsPath) serviceMetrics, err := c.serviceMetricsGetter.Get(serviceMetricsAddr) if err != nil { - c.logger.Warn(fmt.Sprintf("Error scraping service metrics: %s", err.Error())) + c.logger.Warn("Error scraping service metrics", "err", err) + writeResponse(rw, serviceMetricSuccess(false), "service metrics success", c.logger) // Since we've already written the Envoy metrics to the response, we can // return at this point if we were unable to get service metrics. return @@ -300,12 +318,25 @@ func (c *Command) mergedMetricsHandler(rw http.ResponseWriter, _ *http.Request) }() serviceMetricsBody, err := ioutil.ReadAll(serviceMetrics.Body) if err != nil { - c.logger.Error(fmt.Sprintf("Couldn't read service metrics: %s", err.Error())) + c.logger.Error("Could not read service metrics", "err", err) + writeResponse(rw, serviceMetricSuccess(false), "service metrics success", c.logger) return } - _, err = rw.Write(serviceMetricsBody) + if non2xxCode(serviceMetrics.StatusCode) { + c.logger.Error("Received non-2xx status code scraping service metrics", "code", serviceMetrics.StatusCode, "response", string(serviceMetricsBody)) + writeResponse(rw, serviceMetricSuccess(false), "service metrics success", c.logger) + return + } + writeResponse(rw, serviceMetricsBody, "service metrics", c.logger) + writeResponse(rw, serviceMetricSuccess(true), "service metrics success", c.logger) +} + +// writeResponse is a helper method to write resp to rw and log if there is an error writing. +// respName is the name of this response that will be used in the error log. +func writeResponse(rw http.ResponseWriter, resp []byte, respName string, logger hclog.Logger) { + _, err := rw.Write(resp) if err != nil { - c.logger.Error(fmt.Sprintf("Error writing service metrics body: %s", err.Error())) + logger.Error(fmt.Sprintf("Error writing %s: %s", respName, err.Error())) } } @@ -339,6 +370,21 @@ func (c *Command) validateFlags() error { return nil } +// non2xxCode returns true if code is not in the range of 200-299 inclusive. +func non2xxCode(code int) bool { + return code < 200 || code >= 300 +} + +// serviceMetricSuccess returns a prometheus metric line indicating +// the success of the metrics merging. +func serviceMetricSuccess(success bool) []byte { + boolAsInt := 0 + if success { + boolAsInt = 1 + } + return []byte(fmt.Sprintf("%s %d\n", prometheusServiceMetricsSuccessKey, boolAsInt)) +} + // parseConsulFlags creates Consul client command flags // from command's HTTP flags and returns them as an array of strings. func (c *Command) parseConsulFlags() []string { diff --git a/control-plane/subcommand/consul-sidecar/command_test.go b/control-plane/subcommand/consul-sidecar/command_test.go index 6ee55f8ea0..370b4afd8f 100644 --- a/control-plane/subcommand/consul-sidecar/command_test.go +++ b/control-plane/subcommand/consul-sidecar/command_test.go @@ -214,50 +214,88 @@ func TestRunSignalHandlingAllProcessesEnabled(t *testing.T) { } } -type envoyMetrics struct { +type mockEnvoyMetricsGetter struct { + respStatusCode int } -func (em *envoyMetrics) Get(url string) (resp *http.Response, err error) { +func (em *mockEnvoyMetricsGetter) Get(_ string) (resp *http.Response, err error) { response := &http.Response{} + response.StatusCode = em.respStatusCode response.Body = ioutil.NopCloser(bytes.NewReader([]byte("envoy metrics\n"))) return response, nil } -type serviceMetrics struct { - url string +// mockServiceMetricsGetter +type mockServiceMetricsGetter struct { + // reqURL is the last URL that was passed to Get(url) + reqURL string + + // respStatusCode is the status code to use for the response. + respStatusCode int } -func (sm *serviceMetrics) Get(url string) (resp *http.Response, err error) { +func (sm *mockServiceMetricsGetter) Get(url string) (resp *http.Response, err error) { + // Record the URL that we were called with. + sm.reqURL = url + response := &http.Response{} response.Body = ioutil.NopCloser(bytes.NewReader([]byte("service metrics\n"))) - sm.url = url + response.StatusCode = sm.respStatusCode + return response, nil } func TestMergedMetricsServer(t *testing.T) { cases := []struct { - name string - runEnvoyMetricsServer bool - runServiceMetricsServer bool - expectedOutput string + name string + envoyMetricsGetter *mockEnvoyMetricsGetter + serviceMetricsGetter *mockServiceMetricsGetter + expectedStatusCode int + expectedOutput string }{ { - name: "happy path: envoy and service metrics are merged", - runEnvoyMetricsServer: true, - runServiceMetricsServer: true, - expectedOutput: "envoy metrics\nservice metrics\n", + name: "happy path: envoy and service metrics are merged", + envoyMetricsGetter: &mockEnvoyMetricsGetter{ + respStatusCode: 200, + }, + serviceMetricsGetter: &mockServiceMetricsGetter{ + respStatusCode: 200, + }, + expectedStatusCode: 200, + expectedOutput: "envoy metrics\nservice metrics\nconsul_merged_service_metrics_success 1\n", }, { - name: "no service metrics", - runEnvoyMetricsServer: true, - runServiceMetricsServer: false, - expectedOutput: "envoy metrics\n", + name: "service metrics non-200", + envoyMetricsGetter: &mockEnvoyMetricsGetter{ + respStatusCode: 200, + }, + serviceMetricsGetter: &mockServiceMetricsGetter{ + respStatusCode: 404, + }, + expectedStatusCode: 200, + expectedOutput: "envoy metrics\nconsul_merged_service_metrics_success 0\n", }, { - name: "no envoy metrics", - runEnvoyMetricsServer: false, - runServiceMetricsServer: true, - expectedOutput: "", + name: "envoy metrics non-200", + envoyMetricsGetter: &mockEnvoyMetricsGetter{ + respStatusCode: 404, + }, + serviceMetricsGetter: &mockServiceMetricsGetter{ + respStatusCode: 200, + }, + expectedStatusCode: 500, + expectedOutput: "Received non-2xx status code scraping Envoy proxy metrics: 404: envoy metrics\n\n", + }, + { + name: "envoy and service metrics non-200", + envoyMetricsGetter: &mockEnvoyMetricsGetter{ + respStatusCode: 500, + }, + serviceMetricsGetter: &mockServiceMetricsGetter{ + respStatusCode: 500, + }, + expectedStatusCode: 500, + expectedOutput: "Received non-2xx status code scraping Envoy proxy metrics: 500: envoy metrics\n\n", }, } @@ -272,21 +310,11 @@ func TestMergedMetricsServer(t *testing.T) { flagServiceMetricsPort: fmt.Sprint(randomPorts[1]), flagServiceMetricsPath: "/metrics", logger: hclog.Default(), + envoyMetricsGetter: c.envoyMetricsGetter, + serviceMetricsGetter: c.serviceMetricsGetter, } server := cmd.createMergedMetricsServer() - - // Override the cmd's envoyMetricsGetter and serviceMetricsGetter - // with stubs. - em := &envoyMetrics{} - sm := &serviceMetrics{} - if c.runEnvoyMetricsServer { - cmd.envoyMetricsGetter = em - } - if c.runServiceMetricsServer { - cmd.serviceMetricsGetter = sm - } - go func() { _ = server.ListenAndServe() }() @@ -304,8 +332,8 @@ func TestMergedMetricsServer(t *testing.T) { // Verify the correct service metrics url was used. The service // metrics endpoint is only called if the Envoy metrics endpoint // call succeeds. - if c.runServiceMetricsServer && c.runEnvoyMetricsServer { - require.Equal(r, fmt.Sprintf("http://127.0.0.1:%d%s", randomPorts[1], "/metrics"), sm.url) + if c.envoyMetricsGetter.respStatusCode == 200 { + require.Equal(r, fmt.Sprintf("http://127.0.0.1:%d%s", randomPorts[1], "/metrics"), c.serviceMetricsGetter.reqURL) } }) }) From 738d80eb2912feb1153eed96fefbf614479b9858 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Mon, 6 Dec 2021 18:45:03 -0600 Subject: [PATCH 30/70] Server TLS bootstrapping (#881) * Support Vault server running with TLS (#874) * Change vault cluster in acceptance tests to only run with TLS. All tests will run against vault with TLS because that is the use case we think will be the most valuable for users to test * Support adding Vault CA as a secret to pods that will be using vault agent. We need to add two annotations to pods: * vault.hashicorp.com/agent-extra-secret with the value of the vault CA secret name. The secret will be mounted to vault agent at /vault/custom path. See docs here * vault.hashicorp.com/ca-cert - with the path of the ca file inside the vault agent container. This should be /vault/custom/ * Most pods will only need those annotations. The server pods also need the Vault CA secret to be mounted as a volume because it needs the CA to be on the file system for the vault connect CA provider. * add terminating and ingress gateways TLS support (#894) * Support TLS with vault for the server-acl-init job (#889) * Support TLS with Vault for the sync catalog deployment (#890) * Support server TLS with vault for the client snapshot agent deployment (#891) Co-authored-by: Iryna Shustava Co-authored-by: Luke Kysow <1034429+lkysow@users.noreply.github.com> --- acceptance/framework/vault/vault_cluster.go | 17 ++- acceptance/tests/vault/vault_test.go | 84 ++++++++++- charts/consul/templates/_helpers.tpl | 36 +++++ charts/consul/templates/client-daemonset.yaml | 19 ++- .../client-snapshot-agent-deployment.yaml | 11 ++ .../templates/connect-inject-deployment.yaml | 11 ++ .../templates/controller-deployment.yaml | 11 ++ .../ingress-gateways-deployment.yaml | 11 ++ .../consul/templates/server-acl-init-job.yaml | 19 ++- .../consul/templates/server-statefulset.yaml | 31 +++- .../templates/sync-catalog-deployment.yaml | 11 ++ .../terminating-gateways-deployment.yaml | 11 ++ .../templates/tls-init-cleanup-job.yaml | 2 + .../tls-init-cleanup-podsecuritypolicy.yaml | 2 + .../templates/tls-init-cleanup-role.yaml | 2 + .../tls-init-cleanup-rolebinding.yaml | 2 + .../tls-init-cleanup-serviceaccount.yaml | 2 + charts/consul/templates/tls-init-job.yaml | 2 + .../templates/tls-init-podsecuritypolicy.yaml | 2 + charts/consul/templates/tls-init-role.yaml | 2 + .../templates/tls-init-rolebinding.yaml | 2 + .../templates/tls-init-serviceaccount.yaml | 2 + charts/consul/test/unit/client-daemonset.bats | 124 ++++++++++++++++ .../client-snapshot-agent-deployment.bats | 124 ++++++++++++++++ .../test/unit/connect-inject-deployment.bats | 131 +++++++++++++++- .../test/unit/controller-deployment.bats | 130 ++++++++++++++++ charts/consul/test/unit/helpers.bats | 23 +++ .../unit/ingress-gateways-deployment.bats | 125 ++++++++++++++++ .../consul/test/unit/server-acl-init-job.bats | 133 +++++++++++++++++ .../consul/test/unit/server-statefulset.bats | 140 ++++++++++++++++-- .../test/unit/sync-catalog-deployment.bats | 123 +++++++++++++++ .../unit/terminating-gateways-deployment.bats | 124 ++++++++++++++++ .../test/unit/tls-init-cleanup-job.bats | 17 +++ .../tls-init-cleanup-podsecuritypolicy.bats | 17 +++ .../test/unit/tls-init-cleanup-role.bats | 17 +++ .../unit/tls-init-cleanup-rolebinding.bats | 17 +++ .../unit/tls-init-cleanup-serviceaccount.bats | 17 +++ charts/consul/test/unit/tls-init-job.bats | 17 +++ .../test/unit/tls-init-podsecuritypolicy.bats | 17 +++ charts/consul/test/unit/tls-init-role.bats | 17 +++ .../test/unit/tls-init-rolebinding.bats | 17 +++ .../test/unit/tls-init-serviceaccount.bats | 16 ++ charts/consul/test/unit/ui-ingress.bats | 6 + charts/consul/values.yaml | 43 ++++-- 44 files changed, 1641 insertions(+), 46 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 9287d57035..b0f444f85e 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -131,18 +131,20 @@ func (v *VaultCluster) bootstrap(t *testing.T, ctx environment.TestContext) { Type: "kv-v2", Config: vapi.MountConfigInput{}, }) - if err != nil { - t.Fatal("unable to mount kv-v2 secrets engine", "err", err) - } - // TODO: add the PKI Secrets Engine when we have a need for it. + require.NoError(t, err) + + // Enable the PKI Secrets engine. + err = v.vaultClient.Sys().Mount("pki", &vapi.MountInput{ + Type: "pki", + Config: vapi.MountConfigInput{}, + }) + require.NoError(t, err) // Enable Kube Auth. err = v.vaultClient.Sys().EnableAuthWithOptions("kubernetes", &vapi.EnableAuthOptions{ Type: "kubernetes", }) - if err != nil { - t.Fatal("unable to enable kube auth", "err", err) - } + require.NoError(t, err) v.logger.Logf(t, "updating vault kube auth config") @@ -230,6 +232,7 @@ func defaultHelmValues(releaseName string) map[string]string { "server.standalone.enabled": "true", "server.standalone.config": serverConfig, "injector.enabled": "true", + "ui.enabled": "true", } } diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 4b63dc8b65..e19e196c84 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -43,6 +43,14 @@ path "/connect_inter/*" { capabilities = [ "create", "read", "update", "delete", "list" ] } ` + serverTLSPolicy = ` +path "pki/issue/consul-server" { + capabilities = ["create", "update"] +}` + caPolicy = ` +path "pki/cert/ca" { + capabilities = ["read"] +}` ) // TestVault installs Vault, bootstraps it with secrets, policies, and Kube Auth Method. @@ -50,6 +58,7 @@ path "/connect_inter/*" { func TestVault(t *testing.T) { cfg := suite.Config() ctx := suite.Environment().DefaultContext(t) + ns := ctx.KubectlOptions(t).Namespace consulReleaseName := helpers.RandomName() vaultReleaseName := helpers.RandomName() @@ -68,6 +77,7 @@ func TestVault(t *testing.T) { err := vaultClient.Sys().PutPolicy("consul-gossip", gossipPolicy) require.NoError(t, err) + // Create the Vault Policy for the connect-ca. err = vaultClient.Sys().PutPolicy("connect-ca", connectCAPolicy) require.NoError(t, err) @@ -80,7 +90,7 @@ func TestVault(t *testing.T) { logger.Log(t, "Creating the consul-server and consul-client roles") params := map[string]interface{}{ "bound_service_account_names": consulClientServiceAccountName, - "bound_service_account_namespaces": "default", + "bound_service_account_namespaces": ns, "policies": "consul-gossip", "ttl": "24h", } @@ -89,13 +99,24 @@ func TestVault(t *testing.T) { params = map[string]interface{}{ "bound_service_account_names": consulServerServiceAccountName, - "bound_service_account_namespaces": "default", - "policies": "consul-gossip,connect-ca", + "bound_service_account_namespaces": ns, + "policies": "consul-gossip,connect-ca,consul-server", "ttl": "24h", } _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-server", params) require.NoError(t, err) + // Create the CA role that all components will use to fetch the Server CA certs. + params = map[string]interface{}{ + "bound_service_account_names": "*", + "bound_service_account_namespaces": ns, + "policies": "consul-ca", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("auth/kubernetes/role/consul-ca", params) + require.NoError(t, err) + + // Generate the gossip secret. gossipKey, err := generateGossipSecret() require.NoError(t, err) @@ -110,7 +131,39 @@ func TestVault(t *testing.T) { require.NoError(t, err) vaultCASecret := vault.CASecretName(vaultReleaseName) + + // Bootstrap TLS by creating the CA infrastructure required for Consul server TLS and also create the `consul-server` PKI role. + // Using https://learn.hashicorp.com/tutorials/consul/vault-pki-consul-secure-tls. + // Generate the root CA. + params = map[string]interface{}{ + "common_name": "dc1.consul", + "ttl": "24h", + } + _, err = vaultClient.Logical().Write("pki/root/generate/internal", params) + require.NoError(t, err) + + // Create the Vault PKI Role. + name := consulReleaseName + "-consul" + allowedDomains := fmt.Sprintf("dc1.consul,%s-server,%s-server.%s,%s-server.%s.svc", name, name, ns, name, ns) + params = map[string]interface{}{ + "allowed_domains": allowedDomains, + "allow_bare_domains": "true", + "allow_localhost": "true", + "allow_subdomains": "true", + "generate_lease": "true", + "max_ttl": "1h", + } + _, err = vaultClient.Logical().Write("pki/roles/consul-server", params) + require.NoError(t, err) + + // Create the server and ca policies + err = vaultClient.Sys().PutPolicy("consul-server", serverTLSPolicy) + require.NoError(t, err) + err = vaultClient.Sys().PutPolicy("consul-ca", caPolicy) + require.NoError(t, err) + consulHelmValues := map[string]string{ + // TODO: Update the global image once 1.11 is GA. "global.image": "docker.mirror.hashicorp.services/hashicorpdev/consul:latest", "server.enabled": "true", @@ -118,13 +171,16 @@ func TestVault(t *testing.T) { "server.extraVolumes[0].type": "secret", "server.extraVolumes[0].name": vaultCASecret, "server.extraVolumes[0].load": "false", + "global.datacenter": "dc1", - "connectInject.enabled": "true", - "controller.enabled": "true", + "connectInject.enabled": "true", + "connectInject.replicas": "1", + "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", "global.secretsBackend.vault.consulServerRole": "consul-server", "global.secretsBackend.vault.consulClientRole": "consul-client", + "global.secretsBackend.vault.consulCARole": "consul-ca", "global.secretsBackend.vault.ca.secretName": vaultCASecret, "global.secretsBackend.vault.ca.secretKey": "tls.crt", @@ -137,6 +193,24 @@ func TestVault(t *testing.T) { "global.tls.enabled": "true", "global.gossipEncryption.secretName": "consul/data/secret/gossip", "global.gossipEncryption.secretKey": "gossip", + + "ingressGateways.enabled": "true", + "ingressGateways.defaults.replicas": "1", + "terminatingGateways.enabled": "true", + "terminatingGateways.defaults.replicas": "1", + + "server.serverCert.secretName": "pki/issue/consul-server", + "global.tls.caCert.secretName": "pki/cert/ca", + "global.tls.httpsOnly": "false", + "global.tls.enableAutoEncrypt": "true", + + // For sync catalog, it is sufficient to check that the deployment is running and ready + // because we only care that get-auto-encrypt-client-ca init container was able + // to talk to the Consul server using the CA from Vault. For this reason, + // we don't need any services to be synced in either direction. + "syncCatalog.enabled": "true", + "syncCatalog.toConsul": "false", + "syncCatalog.toK8S": "false", } logger.Log(t, "Installing Consul") consulCluster := consul.NewHelmCluster(t, consulHelmValues, ctx, cfg, consulReleaseName) diff --git a/charts/consul/templates/_helpers.tpl b/charts/consul/templates/_helpers.tpl index 07ced2d778..8b9f1e836d 100644 --- a/charts/consul/templates/_helpers.tpl +++ b/charts/consul/templates/_helpers.tpl @@ -21,6 +21,36 @@ as well as the global.name setting. {{ "{{" }}- {{ printf ".Data.data.%s" .secretKey }} -{{ "}}" }} {{ "{{" }}- end -{{ "}}" }} {{- end -}} + +{{- define "consul.serverTLSCATemplate" -}} + | + {{ "{{" }}- with secret "{{ .Values.global.tls.caCert.secretName }}" -{{ "}}" }} + {{ "{{" }}- .Data.certificate -{{ "}}" }} + {{ "{{" }}- end -{{ "}}" }} +{{- end -}} + +{{- define "consul.serverTLSCertTemplate" -}} + | + {{ "{{" }}- with secret "{{ .Values.server.serverCert.secretName }}" "{{ printf "common_name=server.%s.%s" .Values.global.datacenter .Values.global.domain }}" + "ttl=1h" "alt_names={{ include "consul.serverTLSAltNames" . }}" "ip_sans=127.0.0.1" -{{ "}}" }} + {{ "{{" }}- .Data.certificate -{{ "}}" }} + {{ "{{" }}- end -{{ "}}" }} +{{- end -}} + +{{- define "consul.serverTLSKeyTemplate" -}} + | + {{ "{{" }}- with secret "{{ .Values.server.serverCert.secretName }}" "{{ printf "common_name=server.%s.%s" .Values.global.datacenter .Values.global.domain }}" + "ttl=1h" "alt_names={{ include "consul.serverTLSAltNames" . }}" "ip_sans=127.0.0.1" -{{ "}}" }} + {{ "{{" }}- .Data.private_key -{{ "}}" }} + {{ "{{" }}- end -{{ "}}" }} +{{- end -}} + +{{- define "consul.serverTLSAltNames" -}} +{{- $name := include "consul.fullname" . -}} +{{- $ns := .Release.Namespace -}} +{{ printf "localhost,%s-server,*.%s-server,*.%s-server.%s,*.%s-server.%s.svc,*.server.%s.%s" $name $name $name $ns $name $ns (.Values.global.datacenter ) (.Values.global.domain) }} +{{- end -}} + {{/* Sets up the extra-from-values config file passed to consul and then uses sed to do any necessary substitution for HOST_IP/POD_IP/HOSTNAME. Useful for dogstats telemetry. The output file @@ -108,13 +138,19 @@ This template is for an init container. {{- else }} -server-addr={{ template "consul.fullname" . }}-server \ -server-port=8501 \ + {{- if .Values.global.secretsBackend.vault.enabled }} + -ca-file=/vault/secrets/serverca.crt + {{- else }} -ca-file=/consul/tls/ca/tls.crt {{- end }} + {{- end }} volumeMounts: {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: consul-ca-cert mountPath: /consul/tls/ca {{- end }} + {{- end }} - name: consul-auto-encrypt-ca-cert mountPath: /consul/tls/client/ca resources: diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index 468af38fda..2fb04423fc 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -3,6 +3,9 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (and .Values.global.adminPartitions.enabled $serverEnabled (ne .Values.global.adminPartitions.name "default"))}}{{ fail "global.adminPartitions.name has to be \"default\" in the server cluster" }}{{ end -}} {{- if (and (not .Values.global.secretsBackend.vault.consulClientRole) .Values.global.secretsBackend.vault.enabled) }}{{ fail "global.secretsBackend.vault.consulClientRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.caCert.secretName)) }}{{ fail "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.enableAutoEncrypt)) }}{{ fail "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.secretsBackend.vault.consulCARole)) }}{{ fail "global.secretsBackend.vault.consulCARole must be provided if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} # DaemonSet to run the Consul clients on every node. apiVersion: apps/v1 kind: DaemonSet @@ -47,10 +50,14 @@ spec: {{- end }} {{- if .Values.global.gossipEncryption.secretName }} {{- with .Values.global.gossipEncryption }} - "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-secret-gossip.txt": {{ .secretName }} "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultGossipTemplate" . }} {{- end }} {{- end }} + {{- if .Values.global.tls.enabled }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- end }} {{- end }} "consul.hashicorp.com/connect-inject": "false" "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/client-config-configmap.yaml") . | sha256sum }} @@ -104,6 +111,7 @@ spec: configMap: name: {{ template "consul.fullname" . }}-client-config {{- if .Values.global.tls.enabled }} + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -132,6 +140,7 @@ spec: medium: "Memory" {{- end }} {{- end }} + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} {{ .type }}: @@ -235,7 +244,11 @@ spec: {{- end }} -hcl='leave_on_terminate = true' \ {{- if .Values.global.tls.enabled }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -hcl='ca_file = "/vault/secrets/serverca.crt"' \ + {{- else }} -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ + {{- end }} {{- if .Values.global.tls.enableAutoEncrypt }} -hcl='auto_encrypt = {tls = true}' \ -hcl="auto_encrypt = {ip_san = [\"$HOST_IP\",\"$POD_IP\"]}" \ @@ -304,6 +317,7 @@ spec: - name: config mountPath: /consul/config {{- if .Values.global.tls.enabled }} + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true @@ -313,6 +327,7 @@ spec: readOnly: true {{- end }} {{- end }} + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} readOnly: true @@ -446,6 +461,7 @@ spec: mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0.pem tls.crt mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0-key.pem tls.key volumeMounts: + {{- if not .Values.global.secretsBackend.vault.enabled }} - name: consul-client-cert mountPath: /consul/tls/client - name: consul-ca-cert @@ -454,6 +470,7 @@ spec: - name: consul-ca-key mountPath: /consul/tls/ca/key readOnly: true + {{- end }} resources: requests: memory: "50Mi" diff --git a/charts/consul/templates/client-snapshot-agent-deployment.yaml b/charts/consul/templates/client-snapshot-agent-deployment.yaml index 864c2125d1..7a8c679084 100644 --- a/charts/consul/templates/client-snapshot-agent-deployment.yaml +++ b/charts/consul/templates/client-snapshot-agent-deployment.yaml @@ -27,6 +27,17 @@ spec: component: client-snapshot-agent annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- end }} spec: {{- if .Values.client.tolerations }} tolerations: diff --git a/charts/consul/templates/connect-inject-deployment.yaml b/charts/consul/templates/connect-inject-deployment.yaml index f3f9f9a754..32717e2286 100644 --- a/charts/consul/templates/connect-inject-deployment.yaml +++ b/charts/consul/templates/connect-inject-deployment.yaml @@ -36,6 +36,17 @@ spec: component: connect-injector annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- end }} spec: serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account containers: diff --git a/charts/consul/templates/controller-deployment.yaml b/charts/consul/templates/controller-deployment.yaml index 151c08b1e8..5caf5e6a48 100644 --- a/charts/consul/templates/controller-deployment.yaml +++ b/charts/consul/templates/controller-deployment.yaml @@ -30,6 +30,17 @@ spec: component: controller annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- end }} spec: {{- if or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: diff --git a/charts/consul/templates/ingress-gateways-deployment.yaml b/charts/consul/templates/ingress-gateways-deployment.yaml index 36671fb2b8..5b8c8dc4b7 100644 --- a/charts/consul/templates/ingress-gateways-deployment.yaml +++ b/charts/consul/templates/ingress-gateways-deployment.yaml @@ -55,6 +55,17 @@ spec: component: ingress-gateway ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} annotations: + {{- if (and $root.Values.global.secretsBackend.vault.enabled $root.Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ $root.Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ $root.Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" $root }} + {{- if and $root.Values.global.secretsBackend.vault.ca.secretName $root.Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": {{ $root.Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ $root.Values.global.secretsBackend.vault.ca.secretKey }} + {{- end }} + {{- end }} "consul.hashicorp.com/connect-inject": "false" {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} "prometheus.io/scrape": "true" diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index 07b9ab8e6b..bc303e2607 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -33,12 +33,23 @@ spec: component: server-acl-init annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-pre-populate-only": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey)) }} volumes: - {{- if .Values.global.tls.enabled }} + {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -76,7 +87,7 @@ spec: fieldPath: metadata.namespace {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey)) }} volumeMounts: - {{- if .Values.global.tls.enabled }} + {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true @@ -118,8 +129,12 @@ spec: {{- if .Values.global.tls.enabled }} -use-https \ {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -consul-ca-cert=/vault/secrets/serverca.crt \ + {{- else }} -consul-ca-cert=/consul/tls/ca/tls.crt \ {{- end }} + {{- end }} {{- if not .Values.externalServers.enabled }} -server-port=8501 \ {{- end }} diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 5a3afeea4d..a73c56e40d 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -8,6 +8,10 @@ {{- if (and .Values.global.gossipEncryption.secretName (not .Values.global.gossipEncryption.secretKey)) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} {{- if (and (not .Values.global.gossipEncryption.secretName) .Values.global.gossipEncryption.secretKey) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} {{- if (and .Values.global.secretsBackend.vault.enabled (not .Values.global.secretsBackend.vault.consulServerRole)) }}{{ fail "global.secretsBackend.vault.consulServerRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and .Values.server.serverCert.secretName (not .Values.global.tls.caCert.secretName)) }}{{ fail "If server.serverCert.secretName is provided, global.tls.caCert.secretName must also be provided" }}{{ end }} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.caCert.secretName)) }}{{ fail "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.enableAutoEncrypt)) }}{{ fail "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.secretsBackend.vault.consulCARole)) }}{{ fail "global.secretsBackend.vault.consulCARole must be provided if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} # StatefulSet to run the actual Consul server cluster. apiVersion: apps/v1 kind: StatefulSet @@ -53,8 +57,8 @@ spec: "vault.hashicorp.com/agent-inject": "true" "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulServerRole }}" {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} - "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" - "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + "vault.hashicorp.com/agent-extra-secret": {{ .Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }} {{- end }} {{- if .Values.global.gossipEncryption.secretName }} {{- with .Values.global.gossipEncryption }} @@ -62,6 +66,14 @@ spec: "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultGossipTemplate" . }} {{- end }} {{- end }} + {{- if .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-secret-servercert.crt": {{ .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-template-servercert.crt": {{ include "consul.serverTLSCertTemplate" . }} + "vault.hashicorp.com/agent-inject-secret-servercert.key": {{ .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-template-servercert.key": {{ include "consul.serverTLSKeyTemplate" . }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ include "consul.serverTLSCATemplate" . }} + {{- end }} {{- end }} "consul.hashicorp.com/connect-inject": "false" "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/server-config-configmap.yaml") . | sha256sum }} @@ -100,7 +112,7 @@ spec: - name: config configMap: name: {{ template "consul.fullname" . }}-server-config - {{- if .Values.global.tls.enabled }} + {{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -219,7 +231,7 @@ spec: - | CONSUL_FULLNAME="{{template "consul.fullname" . }}" - {{- if .Values.global.secretsBackend.vault.enabled }} + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.gossipEncryption.secretName }} GOSSIP_KEY=`cat /vault/secrets/gossip.txt` {{- end }} @@ -230,9 +242,15 @@ spec: -bind=0.0.0.0 \ -bootstrap-expect={{ if .Values.server.bootstrapExpect }}{{ .Values.server.bootstrapExpect }}{{ else }}{{ .Values.server.replicas }}{{ end }} \ {{- if .Values.global.tls.enabled }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -hcl='ca_file = "/vault/secrets/serverca.crt"' \ + -hcl='cert_file = "/vault/secrets/servercert.crt"' \ + -hcl='key_file = "/vault/secrets/servercert.key"' \ + {{- else }} -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ -hcl='cert_file = "/consul/tls/server/tls.crt"' \ -hcl='key_file = "/consul/tls/server/tls.key"' \ + {{- end }} {{- if .Values.global.tls.enableAutoEncrypt }} -hcl='auto_encrypt = {allow_tls = true}' \ {{- end }} @@ -292,7 +310,7 @@ spec: mountPath: /consul/data - name: config mountPath: /consul/config - {{- if .Values.global.tls.enabled }} + {{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }} - name: consul-ca-cert mountPath: /consul/tls/ca/ readOnly: true @@ -368,8 +386,7 @@ spec: - "-ec" - | {{- if .Values.global.tls.enabled }} - curl \ - --cacert /consul/tls/ca/tls.crt \ + curl -k \ https://127.0.0.1:8501/v1/status/leader \ {{- else }} curl http://127.0.0.1:8500/v1/status/leader \ diff --git a/charts/consul/templates/sync-catalog-deployment.yaml b/charts/consul/templates/sync-catalog-deployment.yaml index 50a847b354..696a8d4c77 100644 --- a/charts/consul/templates/sync-catalog-deployment.yaml +++ b/charts/consul/templates/sync-catalog-deployment.yaml @@ -31,6 +31,17 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- end }} spec: serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog {{- if .Values.global.tls.enabled }} diff --git a/charts/consul/templates/terminating-gateways-deployment.yaml b/charts/consul/templates/terminating-gateways-deployment.yaml index a53743918d..f99d9f1c26 100644 --- a/charts/consul/templates/terminating-gateways-deployment.yaml +++ b/charts/consul/templates/terminating-gateways-deployment.yaml @@ -53,6 +53,17 @@ spec: component: terminating-gateway terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} annotations: + {{- if (and $root.Values.global.secretsBackend.vault.enabled $root.Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ $root.Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ $root.Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" $root }} + {{- if and $root.Values.global.secretsBackend.vault.ca.secretName $root.Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": {{ $root.Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ $root.Values.global.secretsBackend.vault.ca.secretKey }} + {{- end }} + {{- end }} "consul.hashicorp.com/connect-inject": "false" {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} "prometheus.io/scrape": "true" diff --git a/charts/consul/templates/tls-init-cleanup-job.yaml b/charts/consul/templates/tls-init-cleanup-job.yaml index dc658d733d..ad95cbed16 100644 --- a/charts/consul/templates/tls-init-cleanup-job.yaml +++ b/charts/consul/templates/tls-init-cleanup-job.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} # tls-init-cleanup job deletes Kubernetes secrets created by tls-init apiVersion: batch/v1 kind: Job @@ -62,3 +63,4 @@ spec: cpu: "50m" {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml b/charts/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml index c8dc00f62d..360b23c4ff 100644 --- a/charts/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml +++ b/charts/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: @@ -38,3 +39,4 @@ spec: readOnlyRootFilesystem: false {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-cleanup-role.yaml b/charts/consul/templates/tls-init-cleanup-role.yaml index 3922144997..27a324eeac 100644 --- a/charts/consul/templates/tls-init-cleanup-role.yaml +++ b/charts/consul/templates/tls-init-cleanup-role.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -36,3 +37,4 @@ rules: {{- end }} {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-cleanup-rolebinding.yaml b/charts/consul/templates/tls-init-cleanup-rolebinding.yaml index c02f4d2e40..444d1ecf1a 100644 --- a/charts/consul/templates/tls-init-cleanup-rolebinding.yaml +++ b/charts/consul/templates/tls-init-cleanup-rolebinding.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: @@ -22,3 +23,4 @@ subjects: name: {{ template "consul.fullname" . }}-tls-init-cleanup {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-cleanup-serviceaccount.yaml b/charts/consul/templates/tls-init-cleanup-serviceaccount.yaml index f26d14122f..ca8924e579 100644 --- a/charts/consul/templates/tls-init-cleanup-serviceaccount.yaml +++ b/charts/consul/templates/tls-init-cleanup-serviceaccount.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: v1 kind: ServiceAccount metadata: @@ -21,3 +22,4 @@ imagePullSecrets: {{- end }} {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-job.yaml b/charts/consul/templates/tls-init-job.yaml index 019513c897..ecb166c8fc 100644 --- a/charts/consul/templates/tls-init-job.yaml +++ b/charts/consul/templates/tls-init-job.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} # tls-init job generate Consul cluster CA and certificates for the Consul servers # and creates Kubernetes secrets for them. apiVersion: batch/v1 @@ -102,3 +103,4 @@ spec: cpu: "50m" {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-podsecuritypolicy.yaml b/charts/consul/templates/tls-init-podsecuritypolicy.yaml index 4f188bd819..2d03ac748c 100644 --- a/charts/consul/templates/tls-init-podsecuritypolicy.yaml +++ b/charts/consul/templates/tls-init-podsecuritypolicy.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: @@ -38,3 +39,4 @@ spec: readOnlyRootFilesystem: false {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-role.yaml b/charts/consul/templates/tls-init-role.yaml index 5a27d8b44b..6ee785807f 100644 --- a/charts/consul/templates/tls-init-role.yaml +++ b/charts/consul/templates/tls-init-role.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -33,3 +34,4 @@ rules: {{- end }} {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-rolebinding.yaml b/charts/consul/templates/tls-init-rolebinding.yaml index 3ac92e7316..9d83e9075c 100644 --- a/charts/consul/templates/tls-init-rolebinding.yaml +++ b/charts/consul/templates/tls-init-rolebinding.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: @@ -22,3 +23,4 @@ subjects: name: {{ template "consul.fullname" . }}-tls-init {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/templates/tls-init-serviceaccount.yaml b/charts/consul/templates/tls-init-serviceaccount.yaml index e8b2d94ab1..06efeddcf4 100644 --- a/charts/consul/templates/tls-init-serviceaccount.yaml +++ b/charts/consul/templates/tls-init-serviceaccount.yaml @@ -1,5 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} apiVersion: v1 kind: ServiceAccount metadata: @@ -21,3 +22,4 @@ imagePullSecrets: {{- end }} {{- end }} {{- end }} +{{- end }} diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index 73483651db..03f4de7d43 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -1531,6 +1531,65 @@ rollingUpdate: [[ "$output" =~ "global.secretsBackend.vault.consulClientRole must be provided if global.secretsBackend.vault.enabled=true" ]] } +@test "client/DaemonSet: fail when vault, tls are enabled but no caCert provided" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.tls.enabled=true' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." ]] +} + +@test "client/DaemonSet: fail when vault, tls are enabled with a serverCert but no autoencrypt" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + +@test "client/DaemonSet: fail when vault is enabled with tls but autoencrypt is disabled" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.server.serverCert.secretName=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + +@test "client/DaemonSet: fail when vault is enabled with tls but no consulCARole is provided" { + cd `chart_dir` + run helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.server.serverCert.secretName=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.secretsBackend.vault.consulCARole must be provided if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + @test "client/DaemonSet: vault annotations not set by default" { cd `chart_dir` local object=$(helm template \ @@ -1553,6 +1612,7 @@ rollingUpdate: --set 'global.secretsBackend.vault.enabled=true' \ --set 'global.secretsBackend.vault.consulClientRole=foo' \ --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ . | tee /dev/stderr | yq -r '.spec.template.metadata' | tee /dev/stderr) @@ -1571,6 +1631,7 @@ rollingUpdate: --set 'global.secretsBackend.vault.enabled=true' \ --set 'global.secretsBackend.vault.consulClientRole=test' \ --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ --set 'global.gossipEncryption.secretName=path/to/secret' \ --set 'global.gossipEncryption.secretKey=gossip' \ . | tee /dev/stderr | @@ -1592,6 +1653,7 @@ rollingUpdate: --set 'global.secretsBackend.vault.enabled=true' \ --set 'global.secretsBackend.vault.consulClientRole=test' \ --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ --set 'global.gossipEncryption.secretName=a/b/c/d' \ --set 'global.gossipEncryption.secretKey=gossip' \ . | tee /dev/stderr | @@ -1675,3 +1737,65 @@ rollingUpdate: local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') [ "${actual}" = "/vault/custom/tls.crt" ] } + +@test "client/DaemonSet: vault tls annotations are set when tls is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual="$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/cert/ca" ] + + local actual="$(echo $object | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"pki_int/cert/ca\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] +} + +@test "client/DaemonSet: tls related volumes not attached and command is modified correctly when tls is enabled with vault" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-daemonset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=pki_int/ca/pem' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec' | tee /dev/stderr) + + + local actual=$(echo $object | + yq -r '.volumes[] | select(.name == "consul-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.volumes[] | select(.name == "consul-ca-key") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[0].volumeMounts[] | select(.name == "consul-client-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[0].volumeMounts[] | select(.name == "consul-ca-key")' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[0].command | any(contains("ca_file = \"/vault/secrets/serverca.crt\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/charts/consul/test/unit/client-snapshot-agent-deployment.bats b/charts/consul/test/unit/client-snapshot-agent-deployment.bats index 07d96a68bf..22dc6c9855 100644 --- a/charts/consul/test/unit/client-snapshot-agent-deployment.bats +++ b/charts/consul/test/unit/client-snapshot-agent-deployment.bats @@ -458,3 +458,127 @@ exec /bin/consul snapshot agent \' yq -r -c '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_LICENSE_PATH")' | tee /dev/stderr) [ "${actual}" = "" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "client/SnapshotAgentDeployment: configures server CA to come from vault when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check annotations + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "carole" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = $'{{- with secret \"foo\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' ] +} + +@test "client/SnapshotAgentDeployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} diff --git a/charts/consul/test/unit/connect-inject-deployment.bats b/charts/consul/test/unit/connect-inject-deployment.bats index 75df185d3f..8730a2b21e 100755 --- a/charts/consul/test/unit/connect-inject-deployment.bats +++ b/charts/consul/test/unit/connect-inject-deployment.bats @@ -1512,4 +1512,133 @@ EOF yq '.spec.replicas' | tee /dev/stderr) [ "${actual}" = "3" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# Vault + +@test "connectInject/Deployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} + +@test "connectInject/Deployment: vault tls annotations are set when tls is enabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=bar' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"pki_int/cert/ca\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/cert/ca" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr)" + [ "${actual}" = "true" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr)" + [ "${actual}" = "true" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr)" + [ "${actual}" = "test" ] +} diff --git a/charts/consul/test/unit/controller-deployment.bats b/charts/consul/test/unit/controller-deployment.bats index 158c6edaaa..29cd9a1026 100644 --- a/charts/consul/test/unit/controller-deployment.bats +++ b/charts/consul/test/unit/controller-deployment.bats @@ -550,3 +550,133 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# Vault + +@test "controller/Deployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/controller-deployment.yaml \ + --set 'controller.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "controller/Deployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/controller-deployment.yaml \ + --set 'controller.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "controller/Deployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/controller-deployment.yaml \ + --set 'controller.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "controller/Deployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/controller-deployment.yaml \ + --set 'controller.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} + +@test "controller/Deployment: vault tls annotations are set when tls is enabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/controller-deployment.yaml \ + --set 'controller.enabled=true' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=bar' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata' | tee /dev/stderr) + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"pki_int/cert/ca\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/cert/ca" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr)" + [ "${actual}" = "true" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr)" + [ "${actual}" = "true" ] + + local actual="$(echo $cmd | + yq -r '.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr)" + [ "${actual}" = "test" ] +} + + diff --git a/charts/consul/test/unit/helpers.bats b/charts/consul/test/unit/helpers.bats index 235338adc6..75e90165a9 100644 --- a/charts/consul/test/unit/helpers.bats +++ b/charts/consul/test/unit/helpers.bats @@ -270,3 +270,26 @@ load _helpers [ "${actual}" = "" ] } + +@test "helper/consul.getAutoEncryptClientCA: uses the correct -ca-file when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/tests/test-runner.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/ca/pem' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca")' | tee /dev/stderr) + + actual=$(echo $object | jq '.command | join(" ") | contains("-ca-file=/vault/secrets/serverca.crt")') + [ "${actual}" = "true" ] + + actual=$(echo $object | jq '.volumeMounts[] | select(.name == "consul-ca-cert")') + [ "${actual}" = "" ] +} diff --git a/charts/consul/test/unit/ingress-gateways-deployment.bats b/charts/consul/test/unit/ingress-gateways-deployment.bats index c4b623e4be..ee1ac5f303 100644 --- a/charts/consul/test/unit/ingress-gateways-deployment.bats +++ b/charts/consul/test/unit/ingress-gateways-deployment.bats @@ -1485,3 +1485,128 @@ EOF local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "ingressGateway/Deployment: vault tls annotations are set when tls is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check annotations + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "carole" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = $'{{- with secret \"foo\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' ] +} + +@test "ingressGateway/Deployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + + +@test "ingressGateway/Deployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "ingressGateway/Deployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "ingressGateway/Deployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} \ No newline at end of file diff --git a/charts/consul/test/unit/server-acl-init-job.bats b/charts/consul/test/unit/server-acl-init-job.bats index a0ae9a34c5..117f77d37d 100644 --- a/charts/consul/test/unit/server-acl-init-job.bats +++ b/charts/consul/test/unit/server-acl-init-job.bats @@ -593,6 +593,139 @@ load _helpers [ "${actual}" = "key" ] } +@test "serverACLInit/Job: configures server CA to come from vault when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.server.serverCert.secretName=foo' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check annotations + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-pre-populate-only"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "carole" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = $'{{- with secret \"foo\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' ] + + # Check that the consul-ca-cert volume is not attached + local actual=$(echo $object | jq -r '.spec.volumes') + [ "${actual}" = "null" ] + + local actual=$(echo $object | jq -r '.spec.containers[] | select(.name="post-install-job").volumeMounts') + [ "${actual}" = "null" ] +} + +@test "serverACLInit/Job: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.server.serverCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.server.serverCert.secretName=foo' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.server.serverCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.server.serverCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} + #-------------------------------------------------------------------- # namespaces diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index 9a180f5d98..9ff08dbd85 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -818,7 +818,7 @@ load _helpers #-------------------------------------------------------------------- # global.openshift.enabled & client.containerSecurityContext -@test "client/DaemonSet: container level securityContexts are not set when global.openshift.enabled=true" { +@test "server/StatefulSet: container level securityContexts are not set when global.openshift.enabled=true" { cd `chart_dir` local manifest=$(helm template \ -s templates/server-statefulset.yaml \ @@ -1036,16 +1036,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "server/StatefulSet: CA certificate is specified when TLS is enabled" { - cd `chart_dir` - local actual=$(helm template \ - -s templates/server-statefulset.yaml \ - --set 'global.tls.enabled=true' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("--cacert /consul/tls/ca/tls.crt")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - @test "server/StatefulSet: HTTP is disabled in agent when httpsOnly is enabled" { cd `chart_dir` local actual=$(helm template \ @@ -1424,6 +1414,63 @@ load _helpers [[ "$output" =~ "global.secretsBackend.vault.consulServerRole must be provided if global.secretsBackend.vault.enabled=true" ]] } +@test "server/StatefulSet: fail when vault is enabled with tls but autoencrypt is disabled" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.server.serverCert.secretName=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + +@test "server/StatefulSet: fail when vault, tls are enabled but no caCert provided" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.tls.enabled=true' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." ]] +} + +@test "server/StatefulSet: fail when vault, tls are enabled with a serverCert but no autoencrypt" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.tls.enabled=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + +@test "server/StatefulSet: fail when vault is enabled with tls but no consulCARole is provided" { + cd `chart_dir` + run helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.server.serverCert.secretName=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.secretsBackend.vault.consulCARole must be provided if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" ]] +} + @test "server/StatefulSet: vault annotations not set by default" { cd `chart_dir` local object=$(helm template \ @@ -1617,3 +1664,74 @@ load _helpers local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') [ "${actual}" = "/vault/custom/tls.crt" ] } + +@test "server/StatefulSet: vault tls annotations are set when tls is enabled and command modified correctly" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.datacenter=dc2' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual="$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/cert/ca" ] + + local actual="$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"pki_int/cert/ca\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] + + local actual="$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-servercert.crt"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/issue/test" ] + + local actual=$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-servercert.crt"]' | tee /dev/stderr) + local expected=$'{{- with secret \"pki_int/issue/test\" \"common_name=server.dc2.consul\"\n\"ttl=1h\" \"alt_names=localhost,RELEASE-NAME-consul-server,*.RELEASE-NAME-consul-server,*.RELEASE-NAME-consul-server.default,*.RELEASE-NAME-consul-server.default.svc,*.server.dc2.consul\" \"ip_sans=127.0.0.1\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] + + local actual="$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-servercert.key"]' | tee /dev/stderr)" + [ "${actual}" = "pki_int/issue/test" ] + + local actual="$(echo $object | + yq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-servercert.key"]' | tee /dev/stderr)" + local expected=$'{{- with secret \"pki_int/issue/test\" \"common_name=server.dc2.consul\"\n\"ttl=1h\" \"alt_names=localhost,RELEASE-NAME-consul-server,*.RELEASE-NAME-consul-server,*.RELEASE-NAME-consul-server.default,*.RELEASE-NAME-consul-server.default.svc,*.server.dc2.consul\" \"ip_sans=127.0.0.1\" -}}\n{{- .Data.private_key -}}\n{{- end -}}' + [ "${actual}" = "${expected}" ] + + local actual=$(echo $object | + yq -r '.spec.containers[0].command | any(contains("ca_file = \"/vault/secrets/serverca.crt\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: tls related volumes not attached when tls is enabled on vault" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.serverCert.secretName=pki_int/issue/test' \ + --set 'global.tls.caCert.secretName=pki_int/cert/ca' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.volumes[] | select(.name == "consul-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] + + local actual=$(echo $object | + yq -r '.containers[0].volumeMounts[] | select(.name == "consul-ca-key")' | tee /dev/stderr) + [ "${actual}" = "" ] +} diff --git a/charts/consul/test/unit/sync-catalog-deployment.bats b/charts/consul/test/unit/sync-catalog-deployment.bats index 904ac699ce..f69937c886 100755 --- a/charts/consul/test/unit/sync-catalog-deployment.bats +++ b/charts/consul/test/unit/sync-catalog-deployment.bats @@ -978,3 +978,126 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# Vault + +@test "syncCatalog/Deployment: configures server CA to come from vault when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check annotations + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "carole" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] + local actual + actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = $'{{- with secret \"foo\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' ] +} + +@test "syncCatalog/Deployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} diff --git a/charts/consul/test/unit/terminating-gateways-deployment.bats b/charts/consul/test/unit/terminating-gateways-deployment.bats index 5a36e639be..e0bbdcd0a4 100644 --- a/charts/consul/test/unit/terminating-gateways-deployment.bats +++ b/charts/consul/test/unit/terminating-gateways-deployment.bats @@ -1295,3 +1295,127 @@ EOF local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "terminatingGateway/Deployment: configures server CA to come from vault when vault is enabled" { + cd `chart_dir` + local object=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=test' \ + --set 'global.secretsBackend.vault.consulServerRole=foo' \ + --set 'global.secretsBackend.vault.consulCARole=carole' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + + # Check annotations + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-init-first"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/role"]' | tee /dev/stderr) + [ "${actual}" = "carole" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-secret-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + local actual=$(echo $object | jq -r '.metadata.annotations["vault.hashicorp.com/agent-inject-template-serverca.crt"]' | tee /dev/stderr) + [ "${actual}" = $'{{- with secret \"foo\" -}}\n{{- .Data.certificate -}}\n{{- end -}}' ] +} + +@test "terminatingGateway/Deployment: vault CA is not configured by default" { + cd `chart_dir` + local object=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "terminatingGateway/Deployment: vault CA is not configured when secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "terminatingGateway/Deployment: vault CA is not configured when secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/agent-extra-secret")') + [ "${actual}" = "false" ] + local actual=$(echo $object | yq -r '.metadata.annotations | has("vault.hashicorp.com/ca-cert")') + [ "${actual}" = "false" ] +} + +@test "terminatingGateway/Deployment: vault CA is configured when both secretName and secretKey are set" { + cd `chart_dir` + local object=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.tls.caCert.secretName=foo' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.secretsBackend.vault.ca.secretName=ca' \ + --set 'global.secretsBackend.vault.ca.secretKey=tls.crt' \ + . | tee /dev/stderr | + yq -r '.spec.template' | tee /dev/stderr) + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/agent-extra-secret"') + [ "${actual}" = "ca" ] + local actual=$(echo $object | yq -r '.metadata.annotations."vault.hashicorp.com/ca-cert"') + [ "${actual}" = "/vault/custom/tls.crt" ] +} diff --git a/charts/consul/test/unit/tls-init-cleanup-job.bats b/charts/consul/test/unit/tls-init-cleanup-job.bats index d75abf7d6d..76da65bfe5 100644 --- a/charts/consul/test/unit/tls-init-cleanup-job.bats +++ b/charts/consul/test/unit/tls-init-cleanup-job.bats @@ -58,3 +58,20 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInitCleanup/Job: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-cleanup-job.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-cleanup-podsecuritypolicy.bats b/charts/consul/test/unit/tls-init-cleanup-podsecuritypolicy.bats index 34d747aecb..72d1812c69 100644 --- a/charts/consul/test/unit/tls-init-cleanup-podsecuritypolicy.bats +++ b/charts/consul/test/unit/tls-init-cleanup-podsecuritypolicy.bats @@ -47,3 +47,20 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInitCleanup/PodSecurityPolicy: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-cleanup-role.bats b/charts/consul/test/unit/tls-init-cleanup-role.bats index ad3ca7bbe6..cfcf5be7ba 100644 --- a/charts/consul/test/unit/tls-init-cleanup-role.bats +++ b/charts/consul/test/unit/tls-init-cleanup-role.bats @@ -70,3 +70,20 @@ load _helpers [ "${actual}" = "RELEASE-NAME-consul-tls-init-cleanup" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInitCleanup/Role: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-cleanup-role.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-cleanup-rolebinding.bats b/charts/consul/test/unit/tls-init-cleanup-rolebinding.bats index 5fd3632ed4..07cd485852 100644 --- a/charts/consul/test/unit/tls-init-cleanup-rolebinding.bats +++ b/charts/consul/test/unit/tls-init-cleanup-rolebinding.bats @@ -58,3 +58,20 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInitCleanup/RoleBinding: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-cleanup-rolebinding.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-cleanup-serviceaccount.bats b/charts/consul/test/unit/tls-init-cleanup-serviceaccount.bats index d2a89e4e48..283c1ad73f 100644 --- a/charts/consul/test/unit/tls-init-cleanup-serviceaccount.bats +++ b/charts/consul/test/unit/tls-init-cleanup-serviceaccount.bats @@ -79,3 +79,20 @@ load _helpers yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) [ "${actual}" = "my-secret2" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInitCleanup/ServiceAccount: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-job.bats b/charts/consul/test/unit/tls-init-job.bats index 9c751fa3d8..8db52fcfbd 100644 --- a/charts/consul/test/unit/tls-init-job.bats +++ b/charts/consul/test/unit/tls-init-job.bats @@ -115,3 +115,20 @@ load _helpers actual=$(echo $spec | jq -r '.containers[0].command | join(" ") | contains("consul tls ca create")' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInit/Job: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-podsecuritypolicy.bats b/charts/consul/test/unit/tls-init-podsecuritypolicy.bats index 5ec0729d05..459097a9db 100644 --- a/charts/consul/test/unit/tls-init-podsecuritypolicy.bats +++ b/charts/consul/test/unit/tls-init-podsecuritypolicy.bats @@ -47,3 +47,20 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInit/PodSecurityPolicy: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-podsecuritypolicy.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-role.bats b/charts/consul/test/unit/tls-init-role.bats index fe601be911..12af5ed2d0 100644 --- a/charts/consul/test/unit/tls-init-role.bats +++ b/charts/consul/test/unit/tls-init-role.bats @@ -70,3 +70,20 @@ load _helpers [ "${actual}" = "RELEASE-NAME-consul-tls-init" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInit/Role: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-role.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-rolebinding.bats b/charts/consul/test/unit/tls-init-rolebinding.bats index cac2a97f53..3085d4b85b 100644 --- a/charts/consul/test/unit/tls-init-rolebinding.bats +++ b/charts/consul/test/unit/tls-init-rolebinding.bats @@ -58,3 +58,20 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# Vault + +@test "tlsInit/RoleBinding: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-rolebinding.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/tls-init-serviceaccount.bats b/charts/consul/test/unit/tls-init-serviceaccount.bats index 9eb3560ba7..3acf6f281e 100644 --- a/charts/consul/test/unit/tls-init-serviceaccount.bats +++ b/charts/consul/test/unit/tls-init-serviceaccount.bats @@ -80,3 +80,19 @@ load _helpers [ "${actual}" = "my-secret2" ] } +#-------------------------------------------------------------------- +# Vault + +@test "tlsInit/ServiceAccount: disabled with global.secretsBackend.vault.enabled=true and global.tls.enabled=true" { + cd `chart_dir` + assert_empty helm template \ + -s templates/tls-init-serviceaccount.yaml \ + --set 'global.secretsBackend.vault.enabled=true' \ + --set 'global.secretsBackend.vault.consulClientRole=foo' \ + --set 'global.secretsBackend.vault.consulServerRole=test' \ + --set 'global.secretsBackend.vault.consulCARole=test' \ + --set 'global.tls.caCert.secretName=test' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . +} diff --git a/charts/consul/test/unit/ui-ingress.bats b/charts/consul/test/unit/ui-ingress.bats index 3a4e1b6bd1..f26d181d2b 100755 --- a/charts/consul/test/unit/ui-ingress.bats +++ b/charts/consul/test/unit/ui-ingress.bats @@ -69,6 +69,7 @@ load _helpers # --kube-version "1.18" \ # . | tee /dev/stderr | # yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -89,6 +90,7 @@ load _helpers # --kube-version "1.18" \ # . | tee /dev/stderr | # yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -110,6 +112,7 @@ load _helpers # --kube-version "1.18" \ # . | tee /dev/stderr | # yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -132,6 +135,7 @@ load _helpers # --kube-version "1.18" \ # . | tee /dev/stderr | # yq -r '.spec.rules[0].http.paths[1].backend.servicePort' | tee /dev/stderr) + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -207,6 +211,7 @@ load _helpers # pathtype @test "ui/Ingress: default PathType Prefix" { + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -218,6 +223,7 @@ load _helpers } @test "ui/Ingress: set PathType ImplementationSpecific" { + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index ec6b29c2e7..adc1edb6e0 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -118,10 +118,11 @@ global: enablePodSecurityPolicies: false # secretsBackend is used to configure Vault as the secrets backend for the Consul on Kubernetes installation. - # The Vault cluster needs to have the Kubernetes Auth Method, - # KV2 and PKI secrets engines enabled and have necessary secrets, - # policies and roles created prior to installing Consul. - # The Vault cluster should not have Consul as its storage backend. + # The Vault cluster needs to have the Kubernetes Auth Method, KV2 and PKI secrets engines enabled + # and have necessary secrets, policies and roles created prior to installing Consul. + # The Vault cluster *must* not have the Consul cluster installed by this Helm chart as its storage backend. + # It can have Consul as its storage backend as long as that Consul cluster is not running on this Kubernetes cluster + # and is being managed separately from this Helm installation. # Note: When using Vault KV2 secrets engines the "data" field is implicitly required for Vault API calls, # secretName should be in the form of "vault-kv2-mount-path/data/secret-name". # secretKey should be in the form of "key". @@ -152,6 +153,12 @@ global: # and check the name of `metadata.name`. consulClientRole: "" + # The Vault role for all Consul components to read the ServerTLS CA Certificate (unauthenticated). + # The role should be connected to the service accounts of all Consul components, or alternatively `*` since it + # will be used only against the `pki/cert/ca` endpoint which is unauthenticated. A policy must be created which grants + # read capabilities to `global.tls.caCert.secretName`, which is usually `pki/cert/ca`. + consulCARole: "" + # Configuration for Vault server CA certificate. This certificate will be mounted # to any pod where Vault agent needs to run. ca: @@ -206,7 +213,7 @@ global: # Values for secretName and secretKey should not be set if autoGenerate is true. # To manually generate a gossip encryption key, set secretName and secretKey and use Consul to generate # a key, saving this as a Kubernetes secret or Vault secret path and key. - # If `global.secretsBackend.vault.enabled=true`, be sure to add the "data" field to the secretName as required by + # If `global.secretsBackend.vault.enabled=true`, be sure to add the "data" component of the secretName path as required by # the Vault KV-2 secrets engine [see example]. # # ``` @@ -274,15 +281,19 @@ global: # both clients and servers and to only accept HTTPS connections. httpsOnly: true - # A Kubernetes secret containing the certificate of the CA to use for - # TLS communication within the Consul cluster. If you have generated the CA yourself - # with the consul CLI, you could use the following command to create the secret + # A secret containing the certificate of the CA to use for TLS communication within the Consul cluster. + # If you have generated the CA yourself with the consul CLI, you could use the following command to create the secret # in Kubernetes: # # ```bash # kubectl create secret generic consul-ca-cert \ # --from-file='tls.crt=./consul-agent-ca.pem' # ``` + # If you are using Vault as a secrets backend with TLS, `caCert.secretName` must be provided and should reference + # the CA path for your PKI secrets engine. This should be of the form `pki/cert/ca` where `pki` is the mount point of your PKI secrets engine. + # A read policy must be created and associated with the CA cert path for `global.tls.caCert.secretName`. + # This will be consumed by the `global.secretsBackend.vault.consulCARole` role by all Consul components. + # When using Vault the secretKey is not used. caCert: # The name of the Kubernetes secret. secretName: null @@ -470,10 +481,11 @@ server: # Manages license autoload. Required in Consul 1.10.0+, 1.9.7+ and 1.8.12+. enableLicenseAutoload: true - # A Kubernetes secret containing a certificate & key for the server agents to use + # A secret containing a certificate & key for the server agents to use # for TLS communication within the Consul cluster. Cert needs to be provided with # additional DNS name SANs so that it will work within the Kubernetes cluster: # + # Kubernetes Secrets backend: # ```bash # consul tls cert create -server -days=730 -domain=consul -ca=consul-agent-ca.pem \ # -key=consul-agent-ca-key.pem -dc={{datacenter}} \ @@ -485,8 +497,7 @@ server: # -additional-dnsname="server.{{datacenter}}.{{domain}}" # ``` # - # If you have generated the - # server-cert yourself with the consul CLI, you could use the following command + # If you have generated the server-cert yourself with the consul CLI, you could use the following command # to create the secret in Kubernetes: # # ```bash @@ -494,8 +505,16 @@ server: # --from-file='tls.crt=./dc1-server-consul-0.pem' # --from-file='tls.key=./dc1-server-consul-0-key.pem' # ``` + # + # Vault Secrets backend: + # If you are using Vault as a secrets backend, a Vault Policy must be created which allows `["create", "update"]` + # capabilities on the PKI issuing endpoint, which is usually of the form `pki/issue/consul-server`. + # Please see the following guide for steps to generate a compatible certificate: + # https://learn.hashicorp.com/tutorials/consul/vault-pki-consul-secure-tls + # Note: when using TLS, both the `server.serverCert` and `global.tls.caCert` which points to the CA endpoint of this PKI engine + # must be provided. serverCert: - # The name of the Kubernetes secret. + # The name of the Kubernetes secret or Vault secret path containing the PEM encoded server certificate. secretName: null # Exposes the servers' gossip and RPC ports as hostPorts. To enable a client From 8107dd1f3b0cb33c7a814a5233c9e7412e599df8 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Mon, 6 Dec 2021 19:30:21 -0600 Subject: [PATCH 31/70] mod tidy --- acceptance/go.mod | 56 ++++++++++++++++++------- acceptance/go.sum | 104 +++++++++++++++++++++++----------------------- 2 files changed, 92 insertions(+), 68 deletions(-) diff --git a/acceptance/go.mod b/acceptance/go.mod index e86a0091d8..c43c0816aa 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/gruntwork-io/terratest v0.31.2 github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 + github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f github.com/hashicorp/consul/sdk v0.8.0 github.com/hashicorp/vault/api v1.2.0 github.com/stretchr/testify v1.7.0 @@ -16,57 +17,82 @@ require ( require ( cloud.google.com/go v0.54.0 // indirect - github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect - github.com/aws/aws-sdk-go v1.27.1 // indirect + github.com/armon/go-metrics v0.3.9 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/aws/aws-sdk-go v1.30.27 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/evanphx/json-patch v4.11.0+incompatible // indirect - github.com/fatih/color v1.9.0 // indirect + github.com/fatih/color v1.12.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect github.com/go-logr/logr v0.4.0 // indirect - github.com/go-sql-driver/mysql v1.4.1 // indirect + github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.5 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.1.2 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/gruntwork-io/gruntwork-cli v0.7.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.1 // indirect - github.com/hashicorp/go-hclog v0.12.0 // indirect - github.com/hashicorp/go-immutable-radix v1.0.0 // 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-immutable-radix v1.3.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.0.1 // 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/parseutil v0.1.1 // indirect + 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.2.0 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/serf v0.9.6 // indirect - github.com/imdario/mergo v0.3.7 // indirect - github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect + github.com/hashicorp/vault/sdk v0.2.1 // indirect + github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/jmespath/go-jmespath v0.3.0 // indirect github.com/json-iterator/go v1.1.11 // indirect - github.com/mattn/go-colorable v0.1.6 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.13 // indirect + github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/mitchellh/go-testing-interface v1.14.0 // indirect + github.com/mitchellh/mapstructure v1.4.2 // indirect + github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pquerna/otp v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/urfave/cli v1.22.2 // indirect + go.uber.org/atomic v1.7.0 // indirect golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect + golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect golang.org/x/text v0.3.6 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - google.golang.org/appengine v1.6.5 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect + google.golang.org/grpc v1.38.0 // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.9.0 // indirect k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index a2cdcd5bba..de7c95fae2 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -223,12 +223,12 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +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/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= -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/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -313,14 +313,14 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= @@ -332,10 +332,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -388,10 +387,10 @@ github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51/go.mod h1:+Ay3RL0eZdI0wgT193r+EJTOk9cSn1WUlvBvk6Lfnmo= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -457,11 +456,16 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO 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= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= +github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= +github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE= github.com/hashicorp/vault/api v1.2.0 h1:ysGFc6XRGbv05NsWPzuO5VTv68Lj8jtwATxRLFOpP9s= @@ -472,11 +476,6 @@ github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/r github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -559,6 +558,7 @@ github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJc github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= @@ -586,10 +586,10 @@ github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -605,17 +605,16 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -625,20 +624,18 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= @@ -765,11 +762,11 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 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= @@ -829,6 +826,7 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -884,6 +882,7 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -914,17 +913,17 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 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-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-20201021035429-f5854403a974/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -941,13 +940,13 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -996,30 +995,29 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= @@ -1089,11 +1087,11 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1142,12 +1140,12 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1177,12 +1175,12 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= @@ -1232,15 +1230,15 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= +k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= +k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= +k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= -k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= -k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk= k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= @@ -1291,13 +1289,13 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.10.2/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= +sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= +sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 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 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= From 09f0ac2964e328f6e87cb92c22d07b2ffc72d38c Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Mon, 6 Dec 2021 20:20:43 -0600 Subject: [PATCH 32/70] fix merge error --- charts/consul/values.yaml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 857abbf501..c8239f4f78 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -481,21 +481,6 @@ server: # @type: int bootstrapExpect: null - # [Enterprise Only] This value refers to a Kubernetes secret that you have created - # that contains your enterprise license. It is required if you are using an - # enterprise binary. Defining it here applies it to your cluster once a leader - # has been elected. If you are not using an enterprise image or if you plan to - # introduce the license key via another route, then set these fields to null. - # Note: the job to apply license runs on both Helm installs and upgrades. - enterpriseLicense: - # The name of the Kubernetes secret that holds the enterprise license. - # The secret must be in the same namespace that Consul is installed into. - secretName: null - # The key within the Kubernetes secret that holds the enterprise license. - secretKey: null - # Manages license autoload. Required in Consul 1.10.0+, 1.9.7+ and 1.8.12+. - enableLicenseAutoload: true - # A secret containing a certificate & key for the server agents to use # for TLS communication within the Consul cluster. Cert needs to be provided with # additional DNS name SANs so that it will work within the Kubernetes cluster: From ea85df12eb3da7a283ae9558058ffbdd60def957 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Mon, 6 Dec 2021 21:08:27 -0600 Subject: [PATCH 33/70] add changelog entries --- CHANGELOG.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d977798e5c..f48138a1c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,72 @@ BREAKING CHANGES: * Control Plane * Update minimum go version for project to 1.17 [[GH-878](https://github.com/hashicorp/consul-k8s/pull/878)] - * Add boolean metric to merged metrics response `consul_merged_service_metrics_success` to indicate if service metrics were - scraped successfully. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] + * Add boolean metric to merged metrics response `consul_merged_service_metrics_success` to indicate if service metrics + were scraped successfully. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] IMPROVEMENTS: +* Vault as a Secrets Backend + * Add support for Vault as a secrets backend for Gossip Encryption, Server TLS certs and Service Mesh TLS certificates, + removing the existing usage of Kubernetes Secrets for the respective secrets. [[GH-904](https://github.com/hashicorp/consul-k8s/pull/904/)] + * Consul 1.11+ is required. + * Vault 1.19+ is required and Vault-K8s 0.14+ must be installed with the Vault Agent Injector (`injector.enabled=true`) + and must be configured to talk to the Vault server installation from the Kubernetes cluster that Consul is installed. + * `global.tls.enableAutoEncryption=true` is required for TLS support. + * If TLS is enabled in Vault `global.secretsBackend.vault.ca` must be provided and should reference a Kube secret + which holds a copy of the Vault CA cert. + +To enable the Vault Secrets backend for the Consul cluster use the following config: + +```yaml +global: + image: hashicorp/consul:1.11.0 + + # Gossip Encryption. + gossipEncryption: + secretName="consul/data/secrets/gossip" + secretKey="key" + + tls: + enabled: true + enableAutoEncryption: true + + # Server CA certificate. + caCert: + secretName: "pki/cert/ca" + + # Vault configuration. + secretsBackend: + vault: + enabled: true + + # Vault Auth Roles. + consulServerRole: "consul-server" + consulClientRole: "consul-client" + consulCARole: "consul-ca" + + # If Vault TLS is enabled. + ca: + secretName: "vault-CA-cert" + secretKey: "tls.crt" + + # Connect CA configuration. + connectCA: + address: "https://vault:8200" + rootPKIPath: "connect_root" + intermediatePKIPath: "connect_inter" + +# Server TLS Certificates. +server: + serverCert: + secretName: "pki/issue/consul-server" + extraVolumes: + - name: "vault-CA-cert" + type: "secret" + load: false +``` +Note: See `values.yaml` and [Consul - Vault documentation](https://www.consul.io/docs/k8s/installation/vault/index.mdx) +for additional information on required Vault policies and configurations. + * CLI * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] * Control Plane From 2e9da0da16e70877df338b48465d7fe63c4d44e5 Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Tue, 7 Dec 2021 06:59:46 -0800 Subject: [PATCH 34/70] cli: allow enterprise images to be named without the string "-ent" (#903) In a case where users might have a Consul enterprise image that may not contain the string "-ent" in the name, we don't want to fail the installation. This is a fairly common case, so we've removed the check. --- cli/cmd/install/install.go | 15 ++++++--------- cli/cmd/install/install_test.go | 13 ++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index 001c1d3c2a..44b1bca41f 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -3,12 +3,13 @@ package install import ( "errors" "fmt" - k8serrors "k8s.io/apimachinery/pkg/api/errors" "os" "strings" "sync" "time" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + consulChart "github.com/hashicorp/consul-k8s/charts" "github.com/hashicorp/consul-k8s/cli/cmd/common" "github.com/hashicorp/consul-k8s/cli/cmd/common/flag" @@ -179,7 +180,6 @@ type helmValues struct { } type globalValues struct { - Image string `yaml:"image"` EnterpriseLicense enterpriseLicense `yaml:"enterpriseLicense"` } @@ -291,7 +291,7 @@ func (c *Command) Run(args []string) int { // If an enterprise license secret was provided check that the secret exists // and that the enterprise Consul image is set. if v.Global.EnterpriseLicense.SecretName != "" { - if err := c.checkValidEnterprise(v.Global.EnterpriseLicense.SecretName, v.Global.Image); err != nil { + if err := c.checkValidEnterprise(v.Global.EnterpriseLicense.SecretName); err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 } @@ -535,8 +535,8 @@ func validLabel(s string) bool { // checkValidEnterprise checks and validates an enterprise installation. // When an enterprise license secret is provided, check that the secret exists -// in the "consul" namespace, and that the enterprise Consul image is provided. -func (c *Command) checkValidEnterprise(secretName string, image string) error { +// in the "consul" namespace. +func (c *Command) checkValidEnterprise(secretName string) error { _, err := c.kubernetes.CoreV1().Secrets(c.flagNamespace).Get(c.Ctx, secretName, metav1.GetOptions{}) if k8serrors.IsNotFound(err) { @@ -544,9 +544,6 @@ func (c *Command) checkValidEnterprise(secretName string, image string) error { } else if err != nil { return fmt.Errorf("error getting the enterprise license secret %q in the %q namespace: %s", secretName, c.flagNamespace, err) } - if !strings.Contains(image, "-ent") { - return fmt.Errorf("enterprise Consul image is not provided when enterprise license secret is set: %s", image) - } - c.UI.Output("Valid enterprise Consul image and secret found.", terminal.WithSuccessStyle()) + c.UI.Output("Valid enterprise Consul secret found.", terminal.WithSuccessStyle()) return nil } diff --git a/cli/cmd/install/install_test.go b/cli/cmd/install/install_test.go index f9e4028d05..ba6608d256 100644 --- a/cli/cmd/install/install_test.go +++ b/cli/cmd/install/install_test.go @@ -203,24 +203,19 @@ func TestCheckValidEnterprise(t *testing.T) { }, } - // Enterprise secret and image are valid. + // Enterprise secret is valid. c.kubernetes.CoreV1().Secrets("consul").Create(context.Background(), secret, metav1.CreateOptions{}) - err := c.checkValidEnterprise(secret.Name, "consul-enterprise:-ent") + err := c.checkValidEnterprise(secret.Name) require.NoError(t, err) - // Enterprise secret provided but not an enterprise image. - err = c.checkValidEnterprise(secret.Name, "consul:") - require.Error(t, err) - require.Contains(t, err.Error(), "enterprise Consul image is not provided") - // Enterprise secret does not exist. - err = c.checkValidEnterprise("consul-unrelated-secret", "consul-enterprise:-ent") + err = c.checkValidEnterprise("consul-unrelated-secret") require.Error(t, err) require.Contains(t, err.Error(), "please make sure that the secret exists") // Enterprise secret exists in a different namespace. c.kubernetes.CoreV1().Secrets("unrelated").Create(context.Background(), secret2, metav1.CreateOptions{}) - err = c.checkValidEnterprise(secret2.Name, "consul-enterprise:-ent") + err = c.checkValidEnterprise(secret2.Name) require.Error(t, err) require.Contains(t, err.Error(), "please make sure that the secret exists") } From c1df868522c876b07d1382efc1b9a2d58b5be114 Mon Sep 17 00:00:00 2001 From: Niklas Wagner Date: Tue, 12 Oct 2021 16:17:15 +0200 Subject: [PATCH 35/70] Add support for ingressClassName Signed-off-by: Niklas Wagner --- charts/consul/templates/ui-ingress.yaml | 7 +++++-- charts/consul/test/unit/ui-ingress.bats | 22 ++++++++++++++++++++++ charts/consul/values.yaml | 3 ++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/charts/consul/templates/ui-ingress.yaml b/charts/consul/templates/ui-ingress.yaml index 28d3069768..b91e780415 100644 --- a/charts/consul/templates/ui-ingress.yaml +++ b/charts/consul/templates/ui-ingress.yaml @@ -5,7 +5,7 @@ This is because while networks.k8s.io/v1 was introduced in Kubernetes v1.15+, the Ingress resource was promoted to v1 only in Kubernetes v1.19+. This ensures the correct API version is chosen that supports the Ingress resource. */}} -{{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} +{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} apiVersion: networking.k8s.io/v1 {{- else }} apiVersion: networking.k8s.io/v1beta1 @@ -25,9 +25,12 @@ metadata: {{ tpl .Values.ui.ingress.annotations . | nindent 4 | trim }} {{- end }} spec: + {{- if and .Values.ui.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ui.ingress.className }} + {{- end }} rules: {{ $global := .Values.global }} - {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} {{- range .Values.ui.ingress.hosts }} - host: {{ .host | quote }} http: diff --git a/charts/consul/test/unit/ui-ingress.bats b/charts/consul/test/unit/ui-ingress.bats index f26d181d2b..e44eac5b7f 100755 --- a/charts/consul/test/unit/ui-ingress.bats +++ b/charts/consul/test/unit/ui-ingress.bats @@ -234,3 +234,25 @@ load _helpers yq -r '.spec.rules[0].http.paths[0].pathType' | tee /dev/stderr) [ "${actual}" = "ImplementationSpecific" ] } + +#-------------------------------------------------------------------- +# ingressClassName + +@test "ui/Ingress: no ingressClassName by default" { + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ingressClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ui/Ingress: no ingressClassName by default" { + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'ui.ingress.ingressClassName=nginx' \ + . | tee /dev/stderr | + yq -r '.spec.ingressClassName' | tee /dev/stderr) + [ "${actual}" = "nginx" ] +} diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index a6ab7223fe..ebc0a05dc4 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -1220,7 +1220,8 @@ ui: ingress: # This will create an Ingress resource for the Consul UI. # @type: boolean - enabled: false + enabled: true + className: "" # pathType override - see: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types pathType: Prefix From adc71cac3b4378fd43b89e219d5ee9fabc549668 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Tue, 7 Dec 2021 14:28:11 -0600 Subject: [PATCH 36/70] Apply suggestions from code review Co-authored-by: Luke Kysow <1034429+lkysow@users.noreply.github.com> --- CHANGELOG.md | 72 +++++++-------------------------------- charts/consul/values.yaml | 9 +++-- 2 files changed, 18 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f48138a1c2..151a3c5cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,70 +6,22 @@ BREAKING CHANGES: * Add boolean metric to merged metrics response `consul_merged_service_metrics_success` to indicate if service metrics were scraped successfully. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] -IMPROVEMENTS: -* Vault as a Secrets Backend - * Add support for Vault as a secrets backend for Gossip Encryption, Server TLS certs and Service Mesh TLS certificates, +FEATURES: +* Vault as a Secrets Backend: Add support for Vault as a secrets backend for Gossip Encryption, Server TLS certs and Service Mesh TLS certificates, removing the existing usage of Kubernetes Secrets for the respective secrets. [[GH-904](https://github.com/hashicorp/consul-k8s/pull/904/)] - * Consul 1.11+ is required. - * Vault 1.19+ is required and Vault-K8s 0.14+ must be installed with the Vault Agent Injector (`injector.enabled=true`) - and must be configured to talk to the Vault server installation from the Kubernetes cluster that Consul is installed. + + See the [Consul Kubernetes and Vault documentation](https://www.consul.io/docs/k8s/installation/vault) + for full install instructions. + + Requirements: + * Consul 1.11+ + * Vault 1.19+ and Vault-K8s 0.14+ must be installed with the Vault Agent Injector enabled (`injector.enabled=true`) + into the Kubernetes cluster that Consul is installed into. * `global.tls.enableAutoEncryption=true` is required for TLS support. - * If TLS is enabled in Vault `global.secretsBackend.vault.ca` must be provided and should reference a Kube secret + * If TLS is enabled in Vault, `global.secretsBackend.vault.ca` must be provided and should reference a Kube secret which holds a copy of the Vault CA cert. -To enable the Vault Secrets backend for the Consul cluster use the following config: - -```yaml -global: - image: hashicorp/consul:1.11.0 - - # Gossip Encryption. - gossipEncryption: - secretName="consul/data/secrets/gossip" - secretKey="key" - - tls: - enabled: true - enableAutoEncryption: true - - # Server CA certificate. - caCert: - secretName: "pki/cert/ca" - - # Vault configuration. - secretsBackend: - vault: - enabled: true - - # Vault Auth Roles. - consulServerRole: "consul-server" - consulClientRole: "consul-client" - consulCARole: "consul-ca" - - # If Vault TLS is enabled. - ca: - secretName: "vault-CA-cert" - secretKey: "tls.crt" - - # Connect CA configuration. - connectCA: - address: "https://vault:8200" - rootPKIPath: "connect_root" - intermediatePKIPath: "connect_inter" - -# Server TLS Certificates. -server: - serverCert: - secretName: "pki/issue/consul-server" - extraVolumes: - - name: "vault-CA-cert" - type: "secret" - load: false -``` -Note: See `values.yaml` and [Consul - Vault documentation](https://www.consul.io/docs/k8s/installation/vault/index.mdx) -for additional information on required Vault policies and configurations. - -* CLI +IMPROVEMENTS: * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] * Control Plane * Add a label "managed-by" to every secret the control-plane creates. Only delete said secrets on an uninstall. [[GH-835](https://github.com/hashicorp/consul-k8s/pull/835)] diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index c8239f4f78..bcf6d088ad 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -120,7 +120,10 @@ global: # secretsBackend is used to configure Vault as the secrets backend for the Consul on Kubernetes installation. # The Vault cluster needs to have the Kubernetes Auth Method, KV2 and PKI secrets engines enabled # and have necessary secrets, policies and roles created prior to installing Consul. - # The Vault cluster *must* not have the Consul cluster installed by this Helm chart as its storage backend. + # See https://www.consul.io/docs/k8s/installation/vault for full instructions. + # + # The Vault cluster *must* not have the Consul cluster installed by this Helm chart as its storage backend + # as that would cause a circular dependency. # It can have Consul as its storage backend as long as that Consul cluster is not running on this Kubernetes cluster # and is being managed separately from this Helm installation. # Note: When using Vault KV2 secrets engines the "data" field is implicitly required for Vault API calls, @@ -137,7 +140,7 @@ global: # - gossip encryption key defined by `global.gossipEncryption.secretName`. # To discover the service account name of the Consul server, run # ``` - # helm template -s templates/server-serviceaccount.yaml charts/consul + # helm template -s templates/server-serviceaccount.yaml hashicorp/consul # ``` # and check the name of `metadata.name`. consulServerRole: "" @@ -153,7 +156,7 @@ global: # and check the name of `metadata.name`. consulClientRole: "" - # The Vault role for all Consul components to read the ServerTLS CA Certificate (unauthenticated). + # The Vault role for all Consul components to read the Consul's server's CA Certificate (unauthenticated). # The role should be connected to the service accounts of all Consul components, or alternatively `*` since it # will be used only against the `pki/cert/ca` endpoint which is unauthenticated. A policy must be created which grants # read capabilities to `global.tls.caCert.secretName`, which is usually `pki/cert/ca`. From 6c510cc81f656466eaadb17015a803178a7be369 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 7 Dec 2021 15:29:49 -0500 Subject: [PATCH 37/70] Reset ui ingress default to false --- charts/consul/values.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index ebc0a05dc4..c637b927a6 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -1220,8 +1220,10 @@ ui: ingress: # This will create an Ingress resource for the Consul UI. # @type: boolean - enabled: true - className: "" + enabled: false + + # Optionally set the ingressClassName. + ingressClassName: "" # pathType override - see: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types pathType: Prefix From 737b970b83225d62764b8a6affd3fec0cf401f13 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 7 Dec 2021 15:30:11 -0500 Subject: [PATCH 38/70] Test ingress UI with different Kube versions --- charts/consul/templates/ui-ingress.yaml | 8 +- charts/consul/test/unit/ui-ingress.bats | 121 +++++++++++++++--------- 2 files changed, 82 insertions(+), 47 deletions(-) diff --git a/charts/consul/templates/ui-ingress.yaml b/charts/consul/templates/ui-ingress.yaml index b91e780415..7b6e6bab4f 100644 --- a/charts/consul/templates/ui-ingress.yaml +++ b/charts/consul/templates/ui-ingress.yaml @@ -5,7 +5,7 @@ This is because while networks.k8s.io/v1 was introduced in Kubernetes v1.15+, the Ingress resource was promoted to v1 only in Kubernetes v1.19+. This ensures the correct API version is chosen that supports the Ingress resource. */}} -{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} +{{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} apiVersion: networking.k8s.io/v1 {{- else }} apiVersion: networking.k8s.io/v1beta1 @@ -25,12 +25,12 @@ metadata: {{ tpl .Values.ui.ingress.annotations . | nindent 4 | trim }} {{- end }} spec: - {{- if and .Values.ui.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ .Values.ui.ingress.className }} + {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "18" ) }} + ingressClassName: {{ .Values.ui.ingress.ingressClassName }} {{- end }} rules: {{ $global := .Values.global }} - {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} + {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} {{- range .Values.ui.ingress.hosts }} - host: {{ .host | quote }} http: diff --git a/charts/consul/test/unit/ui-ingress.bats b/charts/consul/test/unit/ui-ingress.bats index e44eac5b7f..aaa4e56653 100755 --- a/charts/consul/test/unit/ui-ingress.bats +++ b/charts/consul/test/unit/ui-ingress.bats @@ -59,59 +59,73 @@ load _helpers [ "${actual}" = "foo.com" ] } -@test "ui/Ingress: exposes single port 80 when global.tls.enabled=false" { -# todo: test for Kube versions < 1.19 when helm supports --kube-version flag (https://github.com/helm/helm/pull/9040) -# local actual=$(helm template \ -# -s templates/ui-ingress.yaml \ -# --set 'ui.ingress.enabled=true' \ -# --set 'global.tls.enabled=false' \ -# --set 'ui.ingress.hosts[0].host=foo.com' \ -# --kube-version "1.18" \ -# . | tee /dev/stderr | -# yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) +@test "ui/Ingress: exposes single port 80 when global.tls.enabled=false when Kube version < 1.19" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'global.tls.enabled=false' \ + --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.18" \ + . | tee /dev/stderr | + yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + [ "${actual}" = "80" ] +} + +@test "ui/Ingress: exposes single port 80 when global.tls.enabled=false when Kube version >= 1.19" { cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ --set 'global.tls.enabled=false' \ --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.19" \ . | tee /dev/stderr | yq -r '.spec.rules[0].http.paths[0].backend.service.port.number' | tee /dev/stderr) [ "${actual}" = "80" ] } -@test "ui/Ingress: exposes single port 443 when global.tls.enabled=true and global.tls.httpsOnly=true" { -# todo: test for Kube versions < 1.19 when helm supports --kube-version flag (https://github.com/helm/helm/pull/9040) -# local actual=$(helm template \ -# -s templates/ui-ingress.yaml \ -# --set 'ui.ingress.enabled=true' \ -# --set 'global.tls.enabled=true' \ -# --set 'ui.ingress.hosts[0].host=foo.com' \ -# --kube-version "1.18" \ -# . | tee /dev/stderr | -# yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) +@test "ui/Ingress: exposes single port 443 when global.tls.enabled=true and global.tls.httpsOnly=true when Kube version < 1.19" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.18" \ + . | tee /dev/stderr | + yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + [ "${actual}" = "443" ] +} + +@test "ui/Ingress: exposes single port 443 when global.tls.enabled=true and global.tls.httpsOnly=true when Kube version >= 1.19" { cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ --set 'global.tls.enabled=true' \ --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.19" \ . | tee /dev/stderr | yq -r '.spec.rules[0].http.paths[0].backend.service.port.number' | tee /dev/stderr) [ "${actual}" = "443" ] } -@test "ui/Ingress: exposes the port 80 when global.tls.enabled=true and global.tls.httpsOnly=false" { -# todo: test for Kube versions < 1.19 when helm supports --kube-version flag (https://github.com/helm/helm/pull/9040) -# local actual=$(helm template \ -# -s templates/ui-ingress.yaml \ -# --set 'ui.ingress.enabled=true' \ -# --set 'global.tls.enabled=true' \ -# --set 'global.tls.httpsOnly=false' \ -# --set 'ui.ingress.hosts[0].host=foo.com' \ -# --kube-version "1.18" \ -# . | tee /dev/stderr | -# yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) +@test "ui/Ingress: exposes the port 80 when global.tls.enabled=true and global.tls.httpsOnly=false when Kube version < 1.19" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.18" \ + . | tee /dev/stderr | + yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr) + [ "${actual}" = "80" ] +} + +@test "ui/Ingress: exposes the port 80 when global.tls.enabled=true and global.tls.httpsOnly=false when Kube version >= 1.19" { cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ @@ -119,22 +133,27 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'global.tls.httpsOnly=false' \ --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.19" \ . | tee /dev/stderr | yq -r '.spec.rules[0].http.paths[0].backend.service.port.number' | tee /dev/stderr) [ "${actual}" = "80" ] } -@test "ui/Ingress: exposes the port 443 when global.tls.enabled=true and global.tls.httpsOnly=false" { -# todo: test for Kube versions < 1.19 when helm supports --kube-version flag (https://github.com/helm/helm/pull/9040) -# local actual=$(helm template \ -# -s templates/ui-ingress.yaml \ -# --set 'ui.ingress.enabled=true' \ -# --set 'global.tls.enabled=true' \ -# --set 'global.tls.httpsOnly=false' \ -# --set 'ui.ingress.hosts[0].host=foo.com' \ -# --kube-version "1.18" \ -# . | tee /dev/stderr | -# yq -r '.spec.rules[0].http.paths[1].backend.servicePort' | tee /dev/stderr) +@test "ui/Ingress: exposes the port 443 when global.tls.enabled=true and global.tls.httpsOnly=false when Kube version < 1.19" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.18" \ + . | tee /dev/stderr | + yq -r '.spec.rules[0].http.paths[1].backend.servicePort' | tee /dev/stderr) + [ "${actual}" = "443" ] +} + +@test "ui/Ingress: exposes the port 443 when global.tls.enabled=true and global.tls.httpsOnly=false when Kube version >= 1.19" { cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ @@ -142,6 +161,7 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'global.tls.httpsOnly=false' \ --set 'ui.ingress.hosts[0].host=foo.com' \ + --kube-version "1.19" \ . | tee /dev/stderr | yq -r '.spec.rules[0].http.paths[1].backend.service.port.number' | tee /dev/stderr) [ "${actual}" = "443" ] @@ -239,6 +259,7 @@ load _helpers # ingressClassName @test "ui/Ingress: no ingressClassName by default" { + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -247,7 +268,8 @@ load _helpers [ "${actual}" = "null" ] } -@test "ui/Ingress: no ingressClassName by default" { +@test "ui/Ingress: can set ingressClassName" { + cd `chart_dir` local actual=$(helm template \ -s templates/ui-ingress.yaml \ --set 'ui.ingress.enabled=true' \ @@ -256,3 +278,16 @@ load _helpers yq -r '.spec.ingressClassName' | tee /dev/stderr) [ "${actual}" = "nginx" ] } + +@test "ui/Ingress: cannot set ingressClassName for Kube version < 1.18" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/ui-ingress.yaml \ + --set 'ui.ingress.enabled=true' \ + --set 'ui.ingress.ingressClassName=nginx' \ + --kube-version "1.17" \ + . | tee /dev/stderr | + yq -r '.spec.ingressClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + From 5df000415132a5f1732a8ed60ea9f7d427798cc1 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Tue, 7 Dec 2021 14:30:35 -0600 Subject: [PATCH 39/70] Apply suggestions from code review Co-authored-by: Luke Kysow <1034429+lkysow@users.noreply.github.com> --- charts/consul/values.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index bcf6d088ad..6c5f200320 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -126,6 +126,7 @@ global: # as that would cause a circular dependency. # It can have Consul as its storage backend as long as that Consul cluster is not running on this Kubernetes cluster # and is being managed separately from this Helm installation. + # # Note: When using Vault KV2 secrets engines the "data" field is implicitly required for Vault API calls, # secretName should be in the form of "vault-kv2-mount-path/data/secret-name". # secretKey should be in the form of "key". From 5a728f4b08360272ebb2514014f360184cef3d32 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Tue, 7 Dec 2021 15:34:56 -0500 Subject: [PATCH 40/70] Add Changelog entry for ingressClassName --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d977798e5c..e31b3eb46c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ IMPROVEMENTS: * Add support for labeling a Kubernetes service with `consul.hashicorp.com/service-ignore` to prevent services from being registered in Consul. [[GH-858](https://github.com/hashicorp/consul-k8s/pull/858)] * Helm Chart * Fail an installation/upgrade if WAN federation and Admin Partitions are both enabled. [[GH-892](https://github.com/hashicorp/consul-k8s/issues/892)] + * Add support for setting `ingressClassName` for UI. [[GH-909](https://github.com/hashicorp/consul-k8s/pull/909)] BUG FIXES: * Control Plane: From aea9efea5638e7d560ffa34ec03f3663d0d7d2ec Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 7 Dec 2021 13:22:34 -0800 Subject: [PATCH 41/70] Add docs about choosing storage class (#907) --- charts/consul/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 6c5f200320..709e3c2b46 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -556,6 +556,8 @@ server: # storage classes, the PersistentVolumeClaims would need to be manually created. # A `null` value will use the Kubernetes cluster's default StorageClass. If a default # StorageClass does not exist, you will need to create one. + # See https://www.consul.io/docs/install/performance#read-write-tuning for considerations around choosing a + # performant storage class. # @type: string storageClass: null From 6408674e418ec49e1b57567a3642e32446e11353 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 8 Dec 2021 12:36:35 -0500 Subject: [PATCH 42/70] Rename to exported services (#902) * Rename partitionExports to exportedServices - Update anonymous token job to not run in non-default partitions. The current implementation breaks against the latest consul version. * Update consul API where exportedservices are renamed. --- CHANGELOG.md | 5 + acceptance/go.mod | 2 +- acceptance/go.sum | 4 +- .../controller/controller_namespaces_test.go | 26 +-- .../bases/admin-partitions/kustomization.yaml | 3 - .../exportedservices-default.yaml} | 2 +- .../kustomization.yaml | 2 + .../exportedservices-secondary.yaml} | 2 +- .../kustomization.yaml | 2 + .../kustomization.yaml | 2 +- .../default-partition-default/patch.yaml | 2 +- .../default-partition-ns1/kustomization.yaml | 2 +- .../default-partition-ns1/patch.yaml | 2 +- .../kustomization.yaml | 2 +- .../secondary-partition-default/patch.yaml | 2 +- .../kustomization.yaml | 2 +- .../secondary-partition-ns1/patch.yaml | 2 +- ...tionexports.yaml => exportedservices.yaml} | 2 +- .../cases/crds-ent/kustomization.yaml | 2 +- .../tests/partitions/partitions_test.go | 6 +- .../templates/controller-clusterrole.yaml | 4 +- ...ntroller-mutatingwebhookconfiguration.yaml | 21 +++ ...exports.yaml => crd-exportedservices.yaml} | 14 +- ...exports.bats => crd-exportedservices.bats} | 8 +- control-plane/PROJECT | 2 +- control-plane/api/common/common.go | 2 +- ...rts_types.go => exportedservices_types.go} | 72 ++++---- ...test.go => exportedservices_types_test.go} | 130 +++++++------- ...webhook.go => exportedservices_webhook.go} | 14 +- ...st.go => exportedservices_webhook_test.go} | 46 ++--- .../api/v1alpha1/zz_generated.deepcopy.go | 163 +++++++++--------- .../config/certmanager/certificate.yaml | 26 --- .../config/certmanager/kustomization.yaml | 5 - .../config/certmanager/kustomizeconfig.yaml | 16 -- ...onsul.hashicorp.com_exportedservices.yaml} | 14 +- control-plane/config/crd/kustomization.yaml | 45 ----- control-plane/config/crd/kustomizeconfig.yaml | 17 -- .../cainjection_in_ingressgateways.yaml | 8 - .../patches/cainjection_in_proxydefaults.yaml | 8 - .../cainjection_in_servicedefaults.yaml | 8 - .../cainjection_in_serviceintentions.yaml | 8 - .../cainjection_in_serviceresolvers.yaml | 8 - .../cainjection_in_servicerouters.yaml | 8 - .../cainjection_in_servicesplitters.yaml | 8 - .../cainjection_in_terminatinggateways.yaml | 8 - .../patches/webhook_in_ingressgateways.yaml | 17 -- .../patches/webhook_in_partitionexports.yaml | 17 -- .../crd/patches/webhook_in_proxydefaults.yaml | 17 -- .../patches/webhook_in_servicedefaults.yaml | 17 -- .../patches/webhook_in_serviceintentions.yaml | 17 -- .../patches/webhook_in_serviceresolvers.yaml | 17 -- .../patches/webhook_in_servicerouters.yaml | 17 -- .../patches/webhook_in_servicesplitters.yaml | 17 -- .../webhook_in_terminatinggateways.yaml | 17 -- .../config/default/kustomization.yaml | 74 -------- .../default/manager_auth_proxy_patch.yaml | 25 --- .../config/default/manager_webhook_patch.yaml | 23 --- .../default/webhookcainjection_patch.yaml | 8 - .../config/manager/kustomization.yaml | 9 - control-plane/config/manager/manager.yaml | 48 ------ .../rbac/auth_proxy_client_clusterrole.yaml | 7 - .../config/rbac/auth_proxy_role.yaml | 13 -- .../config/rbac/auth_proxy_role_binding.yaml | 12 -- .../config/rbac/auth_proxy_service.yaml | 14 -- .../rbac/ingressgateway_editor_role.yaml | 24 --- .../rbac/ingressgateway_viewer_role.yaml | 20 --- control-plane/config/rbac/kustomization.yaml | 12 -- .../config/rbac/leader_election_role.yaml | 33 ---- .../rbac/leader_election_role_binding.yaml | 12 -- .../rbac/partitionexport_editor_role.yaml | 24 --- .../rbac/partitionexport_viewer_role.yaml | 20 --- .../rbac/proxydefaults_editor_role.yaml | 24 --- .../rbac/proxydefaults_viewer_role.yaml | 20 --- control-plane/config/rbac/role.yaml | 12 +- control-plane/config/rbac/role_binding.yaml | 12 -- .../rbac/servicedefaults_editor_role.yaml | 24 --- .../rbac/servicedefaults_viewer_role.yaml | 20 --- .../rbac/serviceintentions_editor_role.yaml | 24 --- .../rbac/serviceintentions_viewer_role.yaml | 20 --- .../rbac/serviceresolver_editor_role.yaml | 24 --- .../rbac/serviceresolver_viewer_role.yaml | 20 --- .../rbac/servicerouter_editor_role.yaml | 24 --- .../rbac/servicerouter_viewer_role.yaml | 20 --- .../rbac/servicesplitter_editor_role.yaml | 24 --- .../rbac/servicesplitter_viewer_role.yaml | 20 --- .../rbac/terminatinggateway_editor_role.yaml | 24 --- .../rbac/terminatinggateway_viewer_role.yaml | 20 --- .../consul_v1alpha1_ingressgateway.yaml | 12 -- .../consul_v1alpha1_partitionexport.yaml | 7 - .../consul_v1alpha1_proxydefaults.yaml | 7 - .../consul_v1alpha1_servicedefaults.yaml | 6 - .../consul_v1alpha1_serviceintentions.yaml | 7 - .../consul_v1alpha1_serviceresolver.yaml | 7 - .../consul_v1alpha1_servicerouter.yaml | 11 -- .../consul_v1alpha1_servicesplitter.yaml | 7 - .../consul_v1alpha1_terminatinggateway.yaml | 11 -- .../config/samples/kustomization.yaml | 3 - .../config/webhook/kustomization.yaml | 6 - .../config/webhook/kustomizeconfig.yaml | 25 --- control-plane/config/webhook/manifests.yaml | 18 +- control-plane/config/webhook/service.yaml | 12 -- ...ller.go => exportedservices_controller.go} | 20 +-- ...> exportedservices_controller_ent_test.go} | 79 +++++---- control-plane/go.mod | 2 +- control-plane/go.sum | 4 +- .../subcommand/controller/command.go | 12 +- .../subcommand/partition-init/command.go | 2 +- .../partition-init/command_ent_test.go | 2 +- .../subcommand/server-acl-init/command.go | 6 + 109 files changed, 379 insertions(+), 1487 deletions(-) delete mode 100644 acceptance/tests/fixtures/bases/admin-partitions/kustomization.yaml rename acceptance/tests/fixtures/bases/{admin-partitions/partitionexports-default.yaml => exportedservices-default/exportedservices-default.yaml} (79%) create mode 100644 acceptance/tests/fixtures/bases/exportedservices-default/kustomization.yaml rename acceptance/tests/fixtures/bases/{admin-partitions/partitionexports-secondary.yaml => exportedservices-secondary/exportedservices-secondary.yaml} (79%) create mode 100644 acceptance/tests/fixtures/bases/exportedservices-secondary/kustomization.yaml rename acceptance/tests/fixtures/cases/crds-ent/{partitionexports.yaml => exportedservices.yaml} (87%) rename charts/consul/templates/{crd-partitionexports.yaml => crd-exportedservices.yaml} (93%) rename charts/consul/test/unit/{crd-partitionexports.bats => crd-exportedservices.bats} (73%) rename control-plane/api/v1alpha1/{partitionexports_types.go => exportedservices_types.go} (72%) rename control-plane/api/v1alpha1/{partitionexports_types_test.go => exportedservices_types_test.go} (61%) rename control-plane/api/v1alpha1/{partitionexports_webhook.go => exportedservices_webhook.go} (75%) rename control-plane/api/v1alpha1/{partitionexports_webhook_test.go => exportedservices_webhook_test.go} (79%) delete mode 100644 control-plane/config/certmanager/certificate.yaml delete mode 100644 control-plane/config/certmanager/kustomization.yaml delete mode 100644 control-plane/config/certmanager/kustomizeconfig.yaml rename control-plane/config/crd/bases/{consul.hashicorp.com_partitionexports.yaml => consul.hashicorp.com_exportedservices.yaml} (93%) delete mode 100644 control-plane/config/crd/kustomization.yaml delete mode 100644 control-plane/config/crd/kustomizeconfig.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_ingressgateways.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_proxydefaults.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_servicedefaults.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_serviceintentions.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_serviceresolvers.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_servicerouters.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_servicesplitters.yaml delete mode 100644 control-plane/config/crd/patches/cainjection_in_terminatinggateways.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_ingressgateways.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_partitionexports.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_proxydefaults.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_servicedefaults.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_serviceintentions.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_serviceresolvers.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_servicerouters.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_servicesplitters.yaml delete mode 100644 control-plane/config/crd/patches/webhook_in_terminatinggateways.yaml delete mode 100644 control-plane/config/default/kustomization.yaml delete mode 100644 control-plane/config/default/manager_auth_proxy_patch.yaml delete mode 100644 control-plane/config/default/manager_webhook_patch.yaml delete mode 100644 control-plane/config/default/webhookcainjection_patch.yaml delete mode 100644 control-plane/config/manager/kustomization.yaml delete mode 100644 control-plane/config/manager/manager.yaml delete mode 100644 control-plane/config/rbac/auth_proxy_client_clusterrole.yaml delete mode 100644 control-plane/config/rbac/auth_proxy_role.yaml delete mode 100644 control-plane/config/rbac/auth_proxy_role_binding.yaml delete mode 100644 control-plane/config/rbac/auth_proxy_service.yaml delete mode 100644 control-plane/config/rbac/ingressgateway_editor_role.yaml delete mode 100644 control-plane/config/rbac/ingressgateway_viewer_role.yaml delete mode 100644 control-plane/config/rbac/kustomization.yaml delete mode 100644 control-plane/config/rbac/leader_election_role.yaml delete mode 100644 control-plane/config/rbac/leader_election_role_binding.yaml delete mode 100644 control-plane/config/rbac/partitionexport_editor_role.yaml delete mode 100644 control-plane/config/rbac/partitionexport_viewer_role.yaml delete mode 100644 control-plane/config/rbac/proxydefaults_editor_role.yaml delete mode 100644 control-plane/config/rbac/proxydefaults_viewer_role.yaml delete mode 100644 control-plane/config/rbac/role_binding.yaml delete mode 100644 control-plane/config/rbac/servicedefaults_editor_role.yaml delete mode 100644 control-plane/config/rbac/servicedefaults_viewer_role.yaml delete mode 100644 control-plane/config/rbac/serviceintentions_editor_role.yaml delete mode 100644 control-plane/config/rbac/serviceintentions_viewer_role.yaml delete mode 100644 control-plane/config/rbac/serviceresolver_editor_role.yaml delete mode 100644 control-plane/config/rbac/serviceresolver_viewer_role.yaml delete mode 100644 control-plane/config/rbac/servicerouter_editor_role.yaml delete mode 100644 control-plane/config/rbac/servicerouter_viewer_role.yaml delete mode 100644 control-plane/config/rbac/servicesplitter_editor_role.yaml delete mode 100644 control-plane/config/rbac/servicesplitter_viewer_role.yaml delete mode 100644 control-plane/config/rbac/terminatinggateway_editor_role.yaml delete mode 100644 control-plane/config/rbac/terminatinggateway_viewer_role.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_ingressgateway.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_partitionexport.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_proxydefaults.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_servicedefaults.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_serviceintentions.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_serviceresolver.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_servicerouter.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_servicesplitter.yaml delete mode 100644 control-plane/config/samples/consul_v1alpha1_terminatinggateway.yaml delete mode 100644 control-plane/config/samples/kustomization.yaml delete mode 100644 control-plane/config/webhook/kustomization.yaml delete mode 100644 control-plane/config/webhook/kustomizeconfig.yaml delete mode 100644 control-plane/config/webhook/service.yaml rename control-plane/controller/{partitionexports_controller.go => exportedservices_controller.go} (52%) rename control-plane/controller/{partitionexports_controller_ent_test.go => exportedservices_controller_ent_test.go} (80%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 151a3c5cfe..77a02d9b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,13 @@ FEATURES: * `global.tls.enableAutoEncryption=true` is required for TLS support. * If TLS is enabled in Vault, `global.secretsBackend.vault.ca` must be provided and should reference a Kube secret which holds a copy of the Vault CA cert. + * Add boolean metric to merged metrics response `consul_merged_service_metrics_success` to indicate if service metrics were + scraped successfully. [[GH-551](https://github.com/hashicorp/consul-k8s/pull/551)] +* Helm + * Rename `PartitionExports` CRD to `ExportedServices`. [[GH-902](https://github.com/hashicorp/consul-k8s/pull/902)] IMPROVEMENTS: +* CLI * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] * Control Plane * Add a label "managed-by" to every secret the control-plane creates. Only delete said secrets on an uninstall. [[GH-835](https://github.com/hashicorp/consul-k8s/pull/835)] diff --git a/acceptance/go.mod b/acceptance/go.mod index c43c0816aa..62efc96a62 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/gruntwork-io/terratest v0.31.2 github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 - github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f + github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc github.com/hashicorp/consul/sdk v0.8.0 github.com/hashicorp/vault/api v1.2.0 github.com/stretchr/testify v1.7.0 diff --git a/acceptance/go.sum b/acceptance/go.sum index de7c95fae2..3340d47075 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -386,10 +386,10 @@ github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 h1:Km6RYuAsJVVu3gipkTWF1SVYuvSJrksBtT89rO4hcdA= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51/go.mod h1:+Ay3RL0eZdI0wgT193r+EJTOk9cSn1WUlvBvk6Lfnmo= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= diff --git a/acceptance/tests/controller/controller_namespaces_test.go b/acceptance/tests/controller/controller_namespaces_test.go index d68b2c5414..e303246bfe 100644 --- a/acceptance/tests/controller/controller_namespaces_test.go +++ b/acceptance/tests/controller/controller_namespaces_test.go @@ -74,7 +74,7 @@ func TestControllerNamespaces(t *testing.T) { ctx := suite.Environment().DefaultContext(t) helmValues := map[string]string{ - "global.image": "hashicorp/consul-enterprise:1.11.0-ent-beta3", + "global.image": "ashwinvenkatesh/consul@sha256:4be07b9c90fc590827ad72328da332c2003a14d237df317a0c977817f6fdaf0b", "global.enableConsulNamespaces": "true", "global.adminPartitions.enabled": "true", @@ -156,12 +156,12 @@ func TestControllerNamespaces(t *testing.T) { require.True(r, ok, "could not cast to ProxyConfigEntry") require.Equal(r, api.MeshGatewayModeLocal, proxyDefaultEntry.MeshGateway.Mode) - // partition-exports - entry, _, err = consulClient.ConfigEntries().Get(api.PartitionExports, "default", defaultOpts) + // exported-services + entry, _, err = consulClient.ConfigEntries().Get(api.ExportedServices, "default", defaultOpts) require.NoError(r, err) - partitionExportsEntry, ok := entry.(*api.PartitionExportsConfigEntry) - require.True(r, ok, "could not cast to PartitionExportsConfigEntry") - require.Equal(r, "frontend", partitionExportsEntry.Services[0].Name) + exportedServicesEntry, ok := entry.(*api.ExportedServicesConfigEntry) + require.True(r, ok, "could not cast to ExportedServicesConfigEntry") + require.Equal(r, "frontend", exportedServicesEntry.Services[0].Name) // mesh entry, _, err = consulClient.ConfigEntries().Get(api.MeshConfig, "mesh", defaultOpts) @@ -232,7 +232,7 @@ func TestControllerNamespaces(t *testing.T) { logger.Log(t, "patching partition-exports custom resource") patchServiceName := "backend" - k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "-n", KubeNS, "partitionexports", "default", "-p", fmt.Sprintf(`{"spec":{"services":[{"name": "%s", "namespace": "front", "consumers":[{"partition": "foo"}]}]}}`, patchServiceName), "--type=merge") + k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "-n", KubeNS, "exportedservices", "default", "-p", fmt.Sprintf(`{"spec":{"services":[{"name": "%s", "namespace": "front", "consumers":[{"partition": "foo"}]}]}}`, patchServiceName), "--type=merge") logger.Log(t, "patching mesh custom resource") k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "-n", KubeNS, "mesh", "mesh", "-p", fmt.Sprintf(`{"spec":{"transparentProxy":{"meshDestinationsOnly": %t}}}`, false), "--type=merge") @@ -279,11 +279,11 @@ func TestControllerNamespaces(t *testing.T) { require.Equal(r, api.MeshGatewayModeRemote, proxyDefaultsEntry.MeshGateway.Mode) // partition-exports - entry, _, err = consulClient.ConfigEntries().Get(api.PartitionExports, "default", defaultOpts) + entry, _, err = consulClient.ConfigEntries().Get(api.ExportedServices, "default", defaultOpts) require.NoError(r, err) - partitionExportsEntry, ok := entry.(*api.PartitionExportsConfigEntry) - require.True(r, ok, "could not cast to PartitionExportsConfigEntry") - require.Equal(r, "backend", partitionExportsEntry.Services[0].Name) + exportedServicesEntry, ok := entry.(*api.ExportedServicesConfigEntry) + require.True(r, ok, "could not cast to ExportedServicesConfigEntry") + require.Equal(r, "backend", exportedServicesEntry.Services[0].Name) // mesh entry, _, err = consulClient.ConfigEntries().Get(api.MeshConfig, "mesh", defaultOpts) @@ -343,7 +343,7 @@ func TestControllerNamespaces(t *testing.T) { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "-n", KubeNS, "proxydefaults", "global") logger.Log(t, "deleting partition-exports custom resource") - k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "-n", KubeNS, "partitionexports", "default") + k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "-n", KubeNS, "exportedservices", "default") logger.Log(t, "deleting mesh custom resource") k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "-n", KubeNS, "mesh", "mesh") @@ -381,7 +381,7 @@ func TestControllerNamespaces(t *testing.T) { require.Contains(r, err.Error(), "404 (Config entry not found") // partition-exports - _, _, err = consulClient.ConfigEntries().Get(api.PartitionExports, "default", defaultOpts) + _, _, err = consulClient.ConfigEntries().Get(api.ExportedServices, "default", defaultOpts) require.Error(r, err) require.Contains(r, err.Error(), "404 (Config entry not found") diff --git a/acceptance/tests/fixtures/bases/admin-partitions/kustomization.yaml b/acceptance/tests/fixtures/bases/admin-partitions/kustomization.yaml deleted file mode 100644 index 04a88496e8..0000000000 --- a/acceptance/tests/fixtures/bases/admin-partitions/kustomization.yaml +++ /dev/null @@ -1,3 +0,0 @@ -resources: - - partitionexports-default.yaml - - partitionexports-secondary.yaml diff --git a/acceptance/tests/fixtures/bases/admin-partitions/partitionexports-default.yaml b/acceptance/tests/fixtures/bases/exportedservices-default/exportedservices-default.yaml similarity index 79% rename from acceptance/tests/fixtures/bases/admin-partitions/partitionexports-default.yaml rename to acceptance/tests/fixtures/bases/exportedservices-default/exportedservices-default.yaml index 718b5eae5e..a260602109 100644 --- a/acceptance/tests/fixtures/bases/admin-partitions/partitionexports-default.yaml +++ b/acceptance/tests/fixtures/bases/exportedservices-default/exportedservices-default.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: default spec: diff --git a/acceptance/tests/fixtures/bases/exportedservices-default/kustomization.yaml b/acceptance/tests/fixtures/bases/exportedservices-default/kustomization.yaml new file mode 100644 index 0000000000..e540a4def1 --- /dev/null +++ b/acceptance/tests/fixtures/bases/exportedservices-default/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - exportedservices-default.yaml diff --git a/acceptance/tests/fixtures/bases/admin-partitions/partitionexports-secondary.yaml b/acceptance/tests/fixtures/bases/exportedservices-secondary/exportedservices-secondary.yaml similarity index 79% rename from acceptance/tests/fixtures/bases/admin-partitions/partitionexports-secondary.yaml rename to acceptance/tests/fixtures/bases/exportedservices-secondary/exportedservices-secondary.yaml index 2f09fe87be..a514ed50d9 100644 --- a/acceptance/tests/fixtures/bases/admin-partitions/partitionexports-secondary.yaml +++ b/acceptance/tests/fixtures/bases/exportedservices-secondary/exportedservices-secondary.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: secondary spec: diff --git a/acceptance/tests/fixtures/bases/exportedservices-secondary/kustomization.yaml b/acceptance/tests/fixtures/bases/exportedservices-secondary/kustomization.yaml new file mode 100644 index 0000000000..10af8e20c5 --- /dev/null +++ b/acceptance/tests/fixtures/bases/exportedservices-secondary/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - exportedservices-secondary.yaml diff --git a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/kustomization.yaml b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/kustomization.yaml index ccb255ba30..499fdc5bc1 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/kustomization.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/kustomization.yaml @@ -1,5 +1,5 @@ resources: - - ../../../bases/admin-partitions + - ../../../bases/exportedservices-default patchesStrategicMerge: - patch.yaml diff --git a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/patch.yaml b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/patch.yaml index 5e836da962..c98ecb6f48 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/patch.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-default/patch.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: default spec: diff --git a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/kustomization.yaml b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/kustomization.yaml index ccb255ba30..499fdc5bc1 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/kustomization.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/kustomization.yaml @@ -1,5 +1,5 @@ resources: - - ../../../bases/admin-partitions + - ../../../bases/exportedservices-default patchesStrategicMerge: - patch.yaml diff --git a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/patch.yaml b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/patch.yaml index dda2d4bfde..f826174aec 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/patch.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/default-partition-ns1/patch.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: default spec: diff --git a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/kustomization.yaml b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/kustomization.yaml index ccb255ba30..5a9c8412aa 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/kustomization.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/kustomization.yaml @@ -1,5 +1,5 @@ resources: - - ../../../bases/admin-partitions + - ../../../bases/exportedservices-secondary patchesStrategicMerge: - patch.yaml diff --git a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/patch.yaml b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/patch.yaml index 73ac31c6a8..d2fc1ab914 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/patch.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-default/patch.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: secondary spec: diff --git a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/kustomization.yaml b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/kustomization.yaml index ccb255ba30..5a9c8412aa 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/kustomization.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/kustomization.yaml @@ -1,5 +1,5 @@ resources: - - ../../../bases/admin-partitions + - ../../../bases/exportedservices-secondary patchesStrategicMerge: - patch.yaml diff --git a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/patch.yaml b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/patch.yaml index 2e1b399797..4165f2d21a 100644 --- a/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/patch.yaml +++ b/acceptance/tests/fixtures/cases/crd-partitions/secondary-partition-ns1/patch.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: secondary spec: diff --git a/acceptance/tests/fixtures/cases/crds-ent/partitionexports.yaml b/acceptance/tests/fixtures/cases/crds-ent/exportedservices.yaml similarity index 87% rename from acceptance/tests/fixtures/cases/crds-ent/partitionexports.yaml rename to acceptance/tests/fixtures/cases/crds-ent/exportedservices.yaml index cbcf65c389..4703d23493 100644 --- a/acceptance/tests/fixtures/cases/crds-ent/partitionexports.yaml +++ b/acceptance/tests/fixtures/cases/crds-ent/exportedservices.yaml @@ -1,5 +1,5 @@ apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExports +kind: ExportedServices metadata: name: default spec: diff --git a/acceptance/tests/fixtures/cases/crds-ent/kustomization.yaml b/acceptance/tests/fixtures/cases/crds-ent/kustomization.yaml index 75ca5cd845..cdc3e60cb1 100644 --- a/acceptance/tests/fixtures/cases/crds-ent/kustomization.yaml +++ b/acceptance/tests/fixtures/cases/crds-ent/kustomization.yaml @@ -1,3 +1,3 @@ resources: - ../../bases/crds-oss - - partitionexports.yaml + - exportedservices.yaml diff --git a/acceptance/tests/partitions/partitions_test.go b/acceptance/tests/partitions/partitions_test.go index a9c04a3c5e..7f2d21581b 100644 --- a/acceptance/tests/partitions/partitions_test.go +++ b/acceptance/tests/partitions/partitions_test.go @@ -96,7 +96,7 @@ func TestPartitions(t *testing.T) { serverHelmValues := map[string]string{ "global.datacenter": "dc1", - "global.image": "hashicorp/consul-enterprise:1.11.0-ent-beta3", + "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", "global.adminPartitions.enabled": "true", "global.enableConsulNamespaces": "true", @@ -192,7 +192,7 @@ func TestPartitions(t *testing.T) { // Create client cluster. clientHelmValues := map[string]string{ "global.datacenter": "dc1", - "global.image": "hashicorp/consul-enterprise:1.11.0-ent-beta3", + "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", "global.enabled": "false", "global.tls.enabled": "true", @@ -535,7 +535,7 @@ func TestPartitions(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - logger.Log(t, "creating partition exports") + logger.Log(t, "creating exported services") if c.destinationNamespace == defaultNamespace { k8s.KubectlApplyK(t, serverClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-default") k8s.KubectlApplyK(t, clientClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/secondary-partition-default") diff --git a/charts/consul/templates/controller-clusterrole.yaml b/charts/consul/templates/controller-clusterrole.yaml index 993768811c..45fa8d8458 100644 --- a/charts/consul/templates/controller-clusterrole.yaml +++ b/charts/consul/templates/controller-clusterrole.yaml @@ -17,7 +17,7 @@ rules: - serviceresolvers - proxydefaults - meshes - - partitionexports + - exportedservices - servicerouters - servicesplitters - serviceintentions @@ -38,7 +38,7 @@ rules: - serviceresolvers/status - proxydefaults/status - meshes/status - - partitionexports/status + - exportedservices/status - servicerouters/status - servicesplitters/status - serviceintentions/status diff --git a/charts/consul/templates/controller-mutatingwebhookconfiguration.yaml b/charts/consul/templates/controller-mutatingwebhookconfiguration.yaml index 7bef2e6c27..03f4ce15c4 100644 --- a/charts/consul/templates/controller-mutatingwebhookconfiguration.yaml +++ b/charts/consul/templates/controller-mutatingwebhookconfiguration.yaml @@ -200,4 +200,25 @@ webhooks: resources: - terminatinggateways sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-controller-webhook + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-exportedservices + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-exportedservices.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - exportedservices + sideEffects: None {{- end }} diff --git a/charts/consul/templates/crd-partitionexports.yaml b/charts/consul/templates/crd-exportedservices.yaml similarity index 93% rename from charts/consul/templates/crd-partitionexports.yaml rename to charts/consul/templates/crd-exportedservices.yaml index a39dcaad0a..67f67e5704 100644 --- a/charts/consul/templates/crd-partitionexports.yaml +++ b/charts/consul/templates/crd-exportedservices.yaml @@ -6,7 +6,7 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.0 creationTimestamp: null - name: partitionexports.consul.hashicorp.com + name: exportedservices.consul.hashicorp.com labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -16,10 +16,10 @@ metadata: spec: group: consul.hashicorp.com names: - kind: PartitionExports - listKind: PartitionExportsList - plural: partitionexports - singular: partitionexports + kind: ExportedServices + listKind: ExportedServicesList + plural: exportedservices + singular: exportedservices scope: Namespaced versions: - additionalPrinterColumns: @@ -38,7 +38,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: PartitionExports is the Schema for the partitionexports API + description: ExportedServices is the Schema for the exportedservices API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -53,7 +53,7 @@ spec: metadata: type: object spec: - description: PartitionExportsSpec defines the desired state of PartitionExports + description: ExportedServicesSpec defines the desired state of ExportedServices properties: services: description: Services is a list of services to be exported and the diff --git a/charts/consul/test/unit/crd-partitionexports.bats b/charts/consul/test/unit/crd-exportedservices.bats similarity index 73% rename from charts/consul/test/unit/crd-partitionexports.bats rename to charts/consul/test/unit/crd-exportedservices.bats index 35463eea29..cf1a35a587 100644 --- a/charts/consul/test/unit/crd-partitionexports.bats +++ b/charts/consul/test/unit/crd-exportedservices.bats @@ -2,17 +2,17 @@ load _helpers -@test "partitionExports/CustomerResourceDefinition: disabled by default" { +@test "exportedServices/CustomerResourceDefinition: disabled by default" { cd `chart_dir` assert_empty helm template \ - -s templates/crd-partitionexports.yaml \ + -s templates/crd-exportedservices.yaml \ . } -@test "partitionExports/CustomerResourceDefinition: enabled with controller.enabled=true" { +@test "exportedServices/CustomerResourceDefinition: enabled with controller.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -s templates/crd-partitionexports.yaml \ + -s templates/crd-exportedservices.yaml \ --set 'controller.enabled=true' \ . | tee /dev/stderr | # The generated CRDs have "---" at the top which results in two objects diff --git a/control-plane/PROJECT b/control-plane/PROJECT index 9e26de1f52..16d303458c 100644 --- a/control-plane/PROJECT +++ b/control-plane/PROJECT @@ -56,7 +56,7 @@ resources: - controller: true domain: hashicorp.com group: consul - kind: PartitionExport + kind: ExportedServices path: github.com/hashicorp/consul-k8s/api/v1alpha1 version: v1alpha1 version: "3" diff --git a/control-plane/api/common/common.go b/control-plane/api/common/common.go index a44f527472..7c761b6477 100644 --- a/control-plane/api/common/common.go +++ b/control-plane/api/common/common.go @@ -8,7 +8,7 @@ const ( ServiceRouter string = "servicerouter" ServiceSplitter string = "servicesplitter" ServiceIntentions string = "serviceintentions" - PartitionExports string = "partitionexports" + ExportedServices string = "exportedservices" IngressGateway string = "ingressgateway" TerminatingGateway string = "terminatinggateway" diff --git a/control-plane/api/v1alpha1/partitionexports_types.go b/control-plane/api/v1alpha1/exportedservices_types.go similarity index 72% rename from control-plane/api/v1alpha1/partitionexports_types.go rename to control-plane/api/v1alpha1/exportedservices_types.go index 9fa01fa333..5c1e337c2d 100644 --- a/control-plane/api/v1alpha1/partitionexports_types.go +++ b/control-plane/api/v1alpha1/exportedservices_types.go @@ -16,38 +16,38 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -const PartitionExportsKubeKind = "partitionexports" +const ExportedServicesKubeKind = "exportedservices" func init() { - SchemeBuilder.Register(&PartitionExports{}, &PartitionExportsList{}) + SchemeBuilder.Register(&ExportedServices{}, &ExportedServicesList{}) } //+kubebuilder:object:root=true //+kubebuilder:subresource:status -// PartitionExports is the Schema for the partitionexports API +// ExportedServices is the Schema for the exportedservices API // +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=".status.conditions[?(@.type==\"Synced\")].status",description="The sync status of the resource with Consul" // +kubebuilder:printcolumn:name="Last Synced",type="date",JSONPath=".status.lastSyncedTime",description="The last successful synced time of the resource with Consul" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the resource" -type PartitionExports struct { +type ExportedServices struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec PartitionExportsSpec `json:"spec,omitempty"` + Spec ExportedServicesSpec `json:"spec,omitempty"` Status `json:"status,omitempty"` } //+kubebuilder:object:root=true -// PartitionExportsList contains a list of PartitionExports -type PartitionExportsList struct { +// ExportedServicesList contains a list of ExportedServices +type ExportedServicesList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []PartitionExports `json:"items"` + Items []ExportedServices `json:"items"` } -// PartitionExportsSpec defines the desired state of PartitionExports -type PartitionExportsSpec struct { +// ExportedServicesSpec defines the desired state of ExportedServices +type ExportedServicesSpec struct { // Services is a list of services to be exported and the list of partitions // to expose them to. Services []ExportedService `json:"services,omitempty"` @@ -72,15 +72,15 @@ type ServiceConsumer struct { Partition string `json:"partition,omitempty"` } -func (in *PartitionExports) GetObjectMeta() metav1.ObjectMeta { +func (in *ExportedServices) GetObjectMeta() metav1.ObjectMeta { return in.ObjectMeta } -func (in *PartitionExports) AddFinalizer(name string) { +func (in *ExportedServices) AddFinalizer(name string) { in.ObjectMeta.Finalizers = append(in.Finalizers(), name) } -func (in *PartitionExports) RemoveFinalizer(name string) { +func (in *ExportedServices) RemoveFinalizer(name string) { var newFinalizers []string for _, oldF := range in.Finalizers() { if oldF != name { @@ -90,35 +90,35 @@ func (in *PartitionExports) RemoveFinalizer(name string) { in.ObjectMeta.Finalizers = newFinalizers } -func (in *PartitionExports) Finalizers() []string { +func (in *ExportedServices) Finalizers() []string { return in.ObjectMeta.Finalizers } -func (in *PartitionExports) ConsulKind() string { - return capi.PartitionExports +func (in *ExportedServices) ConsulKind() string { + return capi.ExportedServices } -func (in *PartitionExports) ConsulGlobalResource() bool { +func (in *ExportedServices) ConsulGlobalResource() bool { return true } -func (in *PartitionExports) ConsulMirroringNS() string { +func (in *ExportedServices) ConsulMirroringNS() string { return common.DefaultConsulNamespace } -func (in *PartitionExports) KubeKind() string { - return PartitionExportsKubeKind +func (in *ExportedServices) KubeKind() string { + return ExportedServicesKubeKind } -func (in *PartitionExports) ConsulName() string { +func (in *ExportedServices) ConsulName() string { return in.ObjectMeta.Name } -func (in *PartitionExports) KubernetesName() string { +func (in *ExportedServices) KubernetesName() string { return in.ObjectMeta.Name } -func (in *PartitionExports) SetSyncedCondition(status corev1.ConditionStatus, reason, message string) { +func (in *ExportedServices) SetSyncedCondition(status corev1.ConditionStatus, reason, message string) { in.Status.Conditions = Conditions{ { Type: ConditionSynced, @@ -130,11 +130,11 @@ func (in *PartitionExports) SetSyncedCondition(status corev1.ConditionStatus, re } } -func (in *PartitionExports) SetLastSyncedTime(time *metav1.Time) { +func (in *ExportedServices) SetLastSyncedTime(time *metav1.Time) { in.Status.LastSyncedTime = time } -func (in *PartitionExports) SyncedCondition() (status corev1.ConditionStatus, reason, message string) { +func (in *ExportedServices) SyncedCondition() (status corev1.ConditionStatus, reason, message string) { cond := in.Status.GetCondition(ConditionSynced) if cond == nil { return corev1.ConditionUnknown, "", "" @@ -142,7 +142,7 @@ func (in *PartitionExports) SyncedCondition() (status corev1.ConditionStatus, re return cond.Status, cond.Reason, cond.Message } -func (in *PartitionExports) SyncedConditionStatus() corev1.ConditionStatus { +func (in *ExportedServices) SyncedConditionStatus() corev1.ConditionStatus { cond := in.Status.GetCondition(ConditionSynced) if cond == nil { return corev1.ConditionUnknown @@ -150,12 +150,12 @@ func (in *PartitionExports) SyncedConditionStatus() corev1.ConditionStatus { return cond.Status } -func (in *PartitionExports) ToConsul(datacenter string) api.ConfigEntry { +func (in *ExportedServices) ToConsul(datacenter string) api.ConfigEntry { var services []capi.ExportedService for _, service := range in.Spec.Services { services = append(services, service.toConsul()) } - return &capi.PartitionExportsConfigEntry{ + return &capi.ExportedServicesConfigEntry{ Name: in.Name, Services: services, Meta: meta(datacenter), @@ -174,23 +174,23 @@ func (in *ExportedService) toConsul() capi.ExportedService { } } -func (in *PartitionExports) MatchesConsul(candidate api.ConfigEntry) bool { - configEntry, ok := candidate.(*capi.PartitionExportsConfigEntry) +func (in *ExportedServices) MatchesConsul(candidate api.ConfigEntry) bool { + configEntry, ok := candidate.(*capi.ExportedServicesConfigEntry) if !ok { return false } // No datacenter is passed to ToConsul as we ignore the Meta field when checking for equality. - return cmp.Equal(in.ToConsul(""), configEntry, cmpopts.IgnoreFields(capi.PartitionExportsConfigEntry{}, "Partition", "Meta", "ModifyIndex", "CreateIndex"), cmpopts.IgnoreUnexported(), cmpopts.EquateEmpty()) + return cmp.Equal(in.ToConsul(""), configEntry, cmpopts.IgnoreFields(capi.ExportedServicesConfigEntry{}, "Partition", "Meta", "ModifyIndex", "CreateIndex"), cmpopts.IgnoreUnexported(), cmpopts.EquateEmpty()) } -func (in *PartitionExports) Validate(consulMeta common.ConsulMeta) error { +func (in *ExportedServices) Validate(consulMeta common.ConsulMeta) error { var errs field.ErrorList if !consulMeta.PartitionsEnabled { return apierrors.NewForbidden( - schema.GroupResource{Group: ConsulHashicorpGroup, Resource: common.PartitionExports}, + schema.GroupResource{Group: ConsulHashicorpGroup, Resource: common.ExportedServices}, in.KubernetesName(), - errors.New("Consul Enterprise Admin Partitions must be enabled to create PartitionExports")) + errors.New("Consul Enterprise Admin Partitions must be enabled to create ExportedServices")) } if in.Name != consulMeta.Partition { errs = append(errs, field.Invalid(field.NewPath("name"), in.Name, fmt.Sprintf(`%s resource name must be the same name as the partition, "%s"`, in.KubeKind(), consulMeta.Partition))) @@ -205,7 +205,7 @@ func (in *PartitionExports) Validate(consulMeta common.ConsulMeta) error { } if len(errs) > 0 { return apierrors.NewInvalid( - schema.GroupKind{Group: ConsulHashicorpGroup, Kind: PartitionExportsKubeKind}, + schema.GroupKind{Group: ConsulHashicorpGroup, Kind: ExportedServicesKubeKind}, in.KubernetesName(), errs) } return nil @@ -218,5 +218,5 @@ func (in *ExportedService) validate(path *field.Path) *field.Error { return nil } -func (in *PartitionExports) DefaultNamespaceFields(_ common.ConsulMeta) { +func (in *ExportedServices) DefaultNamespaceFields(_ common.ConsulMeta) { } diff --git a/control-plane/api/v1alpha1/partitionexports_types_test.go b/control-plane/api/v1alpha1/exportedservices_types_test.go similarity index 61% rename from control-plane/api/v1alpha1/partitionexports_types_test.go rename to control-plane/api/v1alpha1/exportedservices_types_test.go index dc0898da66..b35f27cca2 100644 --- a/control-plane/api/v1alpha1/partitionexports_types_test.go +++ b/control-plane/api/v1alpha1/exportedservices_types_test.go @@ -12,20 +12,20 @@ import ( ) // Test MatchesConsul for cases that should return true. -func TestPartitionExports_MatchesConsul(t *testing.T) { +func TestExportedServices_MatchesConsul(t *testing.T) { cases := map[string]struct { - Ours PartitionExports + Ours ExportedServices Theirs capi.ConfigEntry Matches bool }{ "empty fields matches": { - Ours: PartitionExports{ + Ours: ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: common.DefaultConsulPartition, }, - Spec: PartitionExportsSpec{}, + Spec: ExportedServicesSpec{}, }, - Theirs: &capi.PartitionExportsConfigEntry{ + Theirs: &capi.ExportedServicesConfigEntry{ Name: common.DefaultConsulPartition, CreateIndex: 1, ModifyIndex: 2, @@ -37,11 +37,11 @@ func TestPartitionExports_MatchesConsul(t *testing.T) { Matches: true, }, "all fields set matches": { - Ours: PartitionExports{ + Ours: ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: common.DefaultConsulPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service-frontend", @@ -70,7 +70,7 @@ func TestPartitionExports_MatchesConsul(t *testing.T) { }, }, }, - Theirs: &capi.PartitionExportsConfigEntry{ + Theirs: &capi.ExportedServicesConfigEntry{ Name: common.DefaultConsulPartition, Services: []capi.ExportedService{ { @@ -108,15 +108,15 @@ func TestPartitionExports_MatchesConsul(t *testing.T) { Matches: true, }, "mismatched types does not match": { - Ours: PartitionExports{ + Ours: ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: common.DefaultConsulPartition, }, - Spec: PartitionExportsSpec{}, + Spec: ExportedServicesSpec{}, }, Theirs: &capi.ServiceConfigEntry{ Name: common.DefaultConsulPartition, - Kind: capi.PartitionExports, + Kind: capi.ExportedServices, }, Matches: false, }, @@ -128,19 +128,19 @@ func TestPartitionExports_MatchesConsul(t *testing.T) { } } -func TestPartitionExports_ToConsul(t *testing.T) { +func TestExportedServices_ToConsul(t *testing.T) { cases := map[string]struct { - Ours PartitionExports - Exp *capi.PartitionExportsConfigEntry + Ours ExportedServices + Exp *capi.ExportedServicesConfigEntry }{ "empty fields": { - Ours: PartitionExports{ + Ours: ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: common.DefaultConsulPartition, }, - Spec: PartitionExportsSpec{}, + Spec: ExportedServicesSpec{}, }, - Exp: &capi.PartitionExportsConfigEntry{ + Exp: &capi.ExportedServicesConfigEntry{ Name: common.DefaultConsulPartition, Meta: map[string]string{ common.SourceKey: common.SourceValue, @@ -149,11 +149,11 @@ func TestPartitionExports_ToConsul(t *testing.T) { }, }, "every field set": { - Ours: PartitionExports{ + Ours: ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: common.DefaultConsulPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service-frontend", @@ -182,7 +182,7 @@ func TestPartitionExports_ToConsul(t *testing.T) { }, }, }, - Exp: &capi.PartitionExportsConfigEntry{ + Exp: &capi.ExportedServicesConfigEntry{ Name: common.DefaultConsulPartition, Services: []capi.ExportedService{ { @@ -220,49 +220,49 @@ func TestPartitionExports_ToConsul(t *testing.T) { for name, c := range cases { t.Run(name, func(t *testing.T) { act := c.Ours.ToConsul("datacenter") - partitionExports, ok := act.(*capi.PartitionExportsConfigEntry) + exportedServices, ok := act.(*capi.ExportedServicesConfigEntry) require.True(t, ok, "could not cast") - require.Equal(t, c.Exp, partitionExports) + require.Equal(t, c.Exp, exportedServices) }) } } -func TestPartitionExports_AddFinalizer(t *testing.T) { - partitionExports := &PartitionExports{} - partitionExports.AddFinalizer("finalizer") - require.Equal(t, []string{"finalizer"}, partitionExports.ObjectMeta.Finalizers) +func TestExportedServices_AddFinalizer(t *testing.T) { + exportedServices := &ExportedServices{} + exportedServices.AddFinalizer("finalizer") + require.Equal(t, []string{"finalizer"}, exportedServices.ObjectMeta.Finalizers) } -func TestPartitionExports_RemoveFinalizer(t *testing.T) { - partitionExports := &PartitionExports{ +func TestExportedServices_RemoveFinalizer(t *testing.T) { + exportedServices := &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Finalizers: []string{"f1", "f2"}, }, } - partitionExports.RemoveFinalizer("f1") - require.Equal(t, []string{"f2"}, partitionExports.ObjectMeta.Finalizers) + exportedServices.RemoveFinalizer("f1") + require.Equal(t, []string{"f2"}, exportedServices.ObjectMeta.Finalizers) } -func TestPartitionExports_SetSyncedCondition(t *testing.T) { - partitionExports := &PartitionExports{} - partitionExports.SetSyncedCondition(corev1.ConditionTrue, "reason", "message") +func TestExportedServices_SetSyncedCondition(t *testing.T) { + exportedServices := &ExportedServices{} + exportedServices.SetSyncedCondition(corev1.ConditionTrue, "reason", "message") - require.Equal(t, corev1.ConditionTrue, partitionExports.Status.Conditions[0].Status) - require.Equal(t, "reason", partitionExports.Status.Conditions[0].Reason) - require.Equal(t, "message", partitionExports.Status.Conditions[0].Message) + require.Equal(t, corev1.ConditionTrue, exportedServices.Status.Conditions[0].Status) + require.Equal(t, "reason", exportedServices.Status.Conditions[0].Reason) + require.Equal(t, "message", exportedServices.Status.Conditions[0].Message) now := metav1.Now() - require.True(t, partitionExports.Status.Conditions[0].LastTransitionTime.Before(&now)) + require.True(t, exportedServices.Status.Conditions[0].LastTransitionTime.Before(&now)) } -func TestPartitionExports_SetLastSyncedTime(t *testing.T) { - partitionExports := &PartitionExports{} +func TestExportedServices_SetLastSyncedTime(t *testing.T) { + exportedServices := &ExportedServices{} syncedTime := metav1.NewTime(time.Now()) - partitionExports.SetLastSyncedTime(&syncedTime) + exportedServices.SetLastSyncedTime(&syncedTime) - require.Equal(t, &syncedTime, partitionExports.Status.LastSyncedTime) + require.Equal(t, &syncedTime, exportedServices.Status.LastSyncedTime) } -func TestPartitionExports_GetSyncedConditionStatus(t *testing.T) { +func TestExportedServices_GetSyncedConditionStatus(t *testing.T) { cases := []corev1.ConditionStatus{ corev1.ConditionUnknown, corev1.ConditionFalse, @@ -270,7 +270,7 @@ func TestPartitionExports_GetSyncedConditionStatus(t *testing.T) { } for _, status := range cases { t.Run(string(status), func(t *testing.T) { - partitionExports := &PartitionExports{ + exportedServices := &ExportedServices{ Status: Status{ Conditions: []Condition{{ Type: ConditionSynced, @@ -279,57 +279,57 @@ func TestPartitionExports_GetSyncedConditionStatus(t *testing.T) { }, } - require.Equal(t, status, partitionExports.SyncedConditionStatus()) + require.Equal(t, status, exportedServices.SyncedConditionStatus()) }) } } -func TestPartitionExports_GetConditionWhenStatusNil(t *testing.T) { - require.Nil(t, (&PartitionExports{}).GetCondition(ConditionSynced)) +func TestExportedServices_GetConditionWhenStatusNil(t *testing.T) { + require.Nil(t, (&ExportedServices{}).GetCondition(ConditionSynced)) } -func TestPartitionExports_SyncedConditionStatusWhenStatusNil(t *testing.T) { - require.Equal(t, corev1.ConditionUnknown, (&PartitionExports{}).SyncedConditionStatus()) +func TestExportedServices_SyncedConditionStatusWhenStatusNil(t *testing.T) { + require.Equal(t, corev1.ConditionUnknown, (&ExportedServices{}).SyncedConditionStatus()) } -func TestPartitionExports_SyncedConditionWhenStatusNil(t *testing.T) { - status, reason, message := (&PartitionExports{}).SyncedCondition() +func TestExportedServices_SyncedConditionWhenStatusNil(t *testing.T) { + status, reason, message := (&ExportedServices{}).SyncedCondition() require.Equal(t, corev1.ConditionUnknown, status) require.Equal(t, "", reason) require.Equal(t, "", message) } -func TestPartitionExports_ConsulKind(t *testing.T) { - require.Equal(t, capi.PartitionExports, (&PartitionExports{}).ConsulKind()) +func TestExportedServices_ConsulKind(t *testing.T) { + require.Equal(t, capi.ExportedServices, (&ExportedServices{}).ConsulKind()) } -func TestPartitionExports_KubeKind(t *testing.T) { - require.Equal(t, "partitionexports", (&PartitionExports{}).KubeKind()) +func TestExportedServices_KubeKind(t *testing.T) { + require.Equal(t, "exportedservices", (&ExportedServices{}).KubeKind()) } -func TestPartitionExports_ConsulName(t *testing.T) { - require.Equal(t, "foo", (&PartitionExports{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}).ConsulName()) +func TestExportedServices_ConsulName(t *testing.T) { + require.Equal(t, "foo", (&ExportedServices{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}).ConsulName()) } -func TestPartitionExports_KubernetesName(t *testing.T) { - require.Equal(t, "foo", (&PartitionExports{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}).KubernetesName()) +func TestExportedServices_KubernetesName(t *testing.T) { + require.Equal(t, "foo", (&ExportedServices{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}).KubernetesName()) } -func TestPartitionExports_ConsulNamespace(t *testing.T) { - require.Equal(t, common.DefaultConsulNamespace, (&PartitionExports{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}}).ConsulMirroringNS()) +func TestExportedServices_ConsulNamespace(t *testing.T) { + require.Equal(t, common.DefaultConsulNamespace, (&ExportedServices{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}}).ConsulMirroringNS()) } -func TestPartitionExports_ConsulGlobalResource(t *testing.T) { - require.True(t, (&PartitionExports{}).ConsulGlobalResource()) +func TestExportedServices_ConsulGlobalResource(t *testing.T) { + require.True(t, (&ExportedServices{}).ConsulGlobalResource()) } -func TestPartitionExports_ObjectMeta(t *testing.T) { +func TestExportedServices_ObjectMeta(t *testing.T) { meta := metav1.ObjectMeta{ Name: "name", Namespace: "namespace", } - partitionExports := &PartitionExports{ + exportedServices := &ExportedServices{ ObjectMeta: meta, } - require.Equal(t, meta, partitionExports.GetObjectMeta()) + require.Equal(t, meta, exportedServices.GetObjectMeta()) } diff --git a/control-plane/api/v1alpha1/partitionexports_webhook.go b/control-plane/api/v1alpha1/exportedservices_webhook.go similarity index 75% rename from control-plane/api/v1alpha1/partitionexports_webhook.go rename to control-plane/api/v1alpha1/exportedservices_webhook.go index 4311055289..d80062e958 100644 --- a/control-plane/api/v1alpha1/partitionexports_webhook.go +++ b/control-plane/api/v1alpha1/exportedservices_webhook.go @@ -15,7 +15,7 @@ import ( // +kubebuilder:object:generate=false -type PartitionExportsWebhook struct { +type ExportedServicesWebhook struct { client.Client ConsulClient *capi.Client Logger logr.Logger @@ -30,11 +30,11 @@ type PartitionExportsWebhook struct { // NOTE: The below line cannot be combined with any other comment. If it is // it will break the code generation. // -// +kubebuilder:webhook:verbs=create;update,path=/mutate-v1alpha1-partitionexports,mutating=true,failurePolicy=fail,groups=consul.hashicorp.com,resources=partitionexports,versions=v1alpha1,name=mutate-partitionexports.consul.hashicorp.com,sideEffects=None,admissionReviewVersions=v1beta1;v1 +// +kubebuilder:webhook:verbs=create;update,path=/mutate-v1alpha1-exportedservices,mutating=true,failurePolicy=fail,groups=consul.hashicorp.com,resources=exportedservices,versions=v1alpha1,name=mutate-exportedservices.consul.hashicorp.com,sideEffects=None,admissionReviewVersions=v1beta1;v1 -func (v *PartitionExportsWebhook) Handle(ctx context.Context, req admission.Request) admission.Response { - var exports PartitionExports - var exportsList PartitionExportsList +func (v *ExportedServicesWebhook) Handle(ctx context.Context, req admission.Request) admission.Response { + var exports ExportedServices + var exportsList ExportedServicesList err := v.decoder.Decode(req, &exports) if err != nil { return admission.Errored(http.StatusBadRequest, err) @@ -49,7 +49,7 @@ func (v *PartitionExportsWebhook) Handle(ctx context.Context, req admission.Requ if len(exportsList.Items) > 0 { return admission.Errored(http.StatusBadRequest, - fmt.Errorf("%s resource already defined - only one partitionexports entry is supported per Kubernetes cluster", + fmt.Errorf("%s resource already defined - only one exportedservices entry is supported per Kubernetes cluster", exports.KubeKind())) } } @@ -61,7 +61,7 @@ func (v *PartitionExportsWebhook) Handle(ctx context.Context, req admission.Requ return admission.Allowed(fmt.Sprintf("valid %s request", exports.KubeKind())) } -func (v *PartitionExportsWebhook) InjectDecoder(d *admission.Decoder) error { +func (v *ExportedServicesWebhook) InjectDecoder(d *admission.Decoder) error { v.decoder = d return nil } diff --git a/control-plane/api/v1alpha1/partitionexports_webhook_test.go b/control-plane/api/v1alpha1/exportedservices_webhook_test.go similarity index 79% rename from control-plane/api/v1alpha1/partitionexports_webhook_test.go rename to control-plane/api/v1alpha1/exportedservices_webhook_test.go index caacf3dfbc..9c4b79b13d 100644 --- a/control-plane/api/v1alpha1/partitionexports_webhook_test.go +++ b/control-plane/api/v1alpha1/exportedservices_webhook_test.go @@ -15,24 +15,24 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -func TestValidatePartitionExports(t *testing.T) { +func TestValidateExportedServices(t *testing.T) { otherNS := "other" otherPartition := "other" cases := map[string]struct { existingResources []runtime.Object - newResource *PartitionExports + newResource *ExportedServices consulMeta common.ConsulMeta expAllow bool expErrMessage string }{ "no duplicates, valid": { existingResources: nil, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service", @@ -48,17 +48,17 @@ func TestValidatePartitionExports(t *testing.T) { }, expAllow: true, }, - "partitionexports exists": { - existingResources: []runtime.Object{&PartitionExports{ + "exportedservices exists": { + existingResources: []runtime.Object{&ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, }}, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service", @@ -73,15 +73,15 @@ func TestValidatePartitionExports(t *testing.T) { Partition: otherPartition, }, expAllow: false, - expErrMessage: "partitionexports resource already defined - only one partitionexports entry is supported per Kubernetes cluster", + expErrMessage: "exportedservices resource already defined - only one exportedservices entry is supported per Kubernetes cluster", }, "name not partition name": { existingResources: []runtime.Object{}, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: "local", }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service", @@ -96,15 +96,15 @@ func TestValidatePartitionExports(t *testing.T) { Partition: otherPartition, }, expAllow: false, - expErrMessage: "partitionexports.consul.hashicorp.com \"local\" is invalid: name: Invalid value: \"local\": partitionexports resource name must be the same name as the partition, \"other\"", + expErrMessage: "exportedservices.consul.hashicorp.com \"local\" is invalid: name: Invalid value: \"local\": exportedservices resource name must be the same name as the partition, \"other\"", }, "partitions disabled": { existingResources: []runtime.Object{}, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service", @@ -119,15 +119,15 @@ func TestValidatePartitionExports(t *testing.T) { Partition: "", }, expAllow: false, - expErrMessage: "partitionexports.consul.hashicorp.com \"other\" is forbidden: Consul Enterprise Admin Partitions must be enabled to create PartitionExports", + expErrMessage: "exportedservices.consul.hashicorp.com \"other\" is forbidden: Consul Enterprise Admin Partitions must be enabled to create ExportedServices", }, "no services": { existingResources: []runtime.Object{}, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{}, }, }, @@ -136,15 +136,15 @@ func TestValidatePartitionExports(t *testing.T) { Partition: otherPartition, }, expAllow: false, - expErrMessage: "partitionexports.consul.hashicorp.com \"other\" is invalid: spec.services: Invalid value: []v1alpha1.ExportedService(nil): at least one service must be exported", + expErrMessage: "exportedservices.consul.hashicorp.com \"other\" is invalid: spec.services: Invalid value: []v1alpha1.ExportedService(nil): at least one service must be exported", }, "service with no consumers": { existingResources: []runtime.Object{}, - newResource: &PartitionExports{ + newResource: &ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: otherPartition, }, - Spec: PartitionExportsSpec{ + Spec: ExportedServicesSpec{ Services: []ExportedService{ { Name: "service", @@ -159,7 +159,7 @@ func TestValidatePartitionExports(t *testing.T) { Partition: otherPartition, }, expAllow: false, - expErrMessage: "partitionexports.consul.hashicorp.com \"other\" is invalid: spec.services[0]: Invalid value: []v1alpha1.ServiceConsumer(nil): service must have at least 1 consumer.", + expErrMessage: "exportedservices.consul.hashicorp.com \"other\" is invalid: spec.services[0]: Invalid value: []v1alpha1.ServiceConsumer(nil): service must have at least 1 consumer.", }, } for name, c := range cases { @@ -168,12 +168,12 @@ func TestValidatePartitionExports(t *testing.T) { marshalledRequestObject, err := json.Marshal(c.newResource) require.NoError(t, err) s := runtime.NewScheme() - s.AddKnownTypes(GroupVersion, &PartitionExports{}, &PartitionExportsList{}) + s.AddKnownTypes(GroupVersion, &ExportedServices{}, &ExportedServicesList{}) client := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(c.existingResources...).Build() decoder, err := admission.NewDecoder(s) require.NoError(t, err) - validator := &PartitionExportsWebhook{ + validator := &ExportedServicesWebhook{ Client: client, ConsulClient: nil, Logger: logrtest.TestLogger{T: t}, diff --git a/control-plane/api/v1alpha1/zz_generated.deepcopy.go b/control-plane/api/v1alpha1/zz_generated.deepcopy.go index eb7b167895..2fc836ebe8 100644 --- a/control-plane/api/v1alpha1/zz_generated.deepcopy.go +++ b/control-plane/api/v1alpha1/zz_generated.deepcopy.go @@ -1,4 +1,5 @@ //go:build !ignore_autogenerated +// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -97,6 +98,87 @@ func (in *ExportedService) DeepCopy() *ExportedService { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportedServices) DeepCopyInto(out *ExportedServices) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServices. +func (in *ExportedServices) DeepCopy() *ExportedServices { + if in == nil { + return nil + } + out := new(ExportedServices) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExportedServices) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportedServicesList) DeepCopyInto(out *ExportedServicesList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExportedServices, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesList. +func (in *ExportedServicesList) DeepCopy() *ExportedServicesList { + if in == nil { + return nil + } + out := new(ExportedServicesList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExportedServicesList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportedServicesSpec) DeepCopyInto(out *ExportedServicesSpec) { + *out = *in + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ExportedService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesSpec. +func (in *ExportedServicesSpec) DeepCopy() *ExportedServicesSpec { + if in == nil { + return nil + } + out := new(ExportedServicesSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Expose) DeepCopyInto(out *Expose) { *out = *in @@ -641,87 +723,6 @@ func (in *MeshSpec) DeepCopy() *MeshSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PartitionExports) DeepCopyInto(out *PartitionExports) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExports. -func (in *PartitionExports) DeepCopy() *PartitionExports { - if in == nil { - return nil - } - out := new(PartitionExports) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PartitionExports) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PartitionExportsList) DeepCopyInto(out *PartitionExportsList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PartitionExports, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportsList. -func (in *PartitionExportsList) DeepCopy() *PartitionExportsList { - if in == nil { - return nil - } - out := new(PartitionExportsList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PartitionExportsList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PartitionExportsSpec) DeepCopyInto(out *PartitionExportsSpec) { - *out = *in - if in.Services != nil { - in, out := &in.Services, &out.Services - *out = make([]ExportedService, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportsSpec. -func (in *PartitionExportsSpec) DeepCopy() *PartitionExportsSpec { - if in == nil { - return nil - } - out := new(PartitionExportsSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) { *out = *in diff --git a/control-plane/config/certmanager/certificate.yaml b/control-plane/config/certmanager/certificate.yaml deleted file mode 100644 index 58db114fa0..0000000000 --- a/control-plane/config/certmanager/certificate.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for -# breaking changes -apiVersion: cert-manager.io/v1alpha2 -kind: Issuer -metadata: - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1alpha2 -kind: Certificate -metadata: - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: system -spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize - dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/control-plane/config/certmanager/kustomization.yaml b/control-plane/config/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a595..0000000000 --- a/control-plane/config/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/control-plane/config/certmanager/kustomizeconfig.yaml b/control-plane/config/certmanager/kustomizeconfig.yaml deleted file mode 100644 index 90d7c313ca..0000000000 --- a/control-plane/config/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref and var substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name - -varReference: -- kind: Certificate - group: cert-manager.io - path: spec/commonName -- kind: Certificate - group: cert-manager.io - path: spec/dnsNames diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_partitionexports.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml similarity index 93% rename from control-plane/config/crd/bases/consul.hashicorp.com_partitionexports.yaml rename to control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml index 8e31c6ade8..7c9b46192b 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_partitionexports.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml @@ -6,14 +6,14 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.0 creationTimestamp: null - name: partitionexports.consul.hashicorp.com + name: exportedservices.consul.hashicorp.com spec: group: consul.hashicorp.com names: - kind: PartitionExports - listKind: PartitionExportsList - plural: partitionexports - singular: partitionexports + kind: ExportedServices + listKind: ExportedServicesList + plural: exportedservices + singular: exportedservices scope: Namespaced versions: - additionalPrinterColumns: @@ -32,7 +32,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: PartitionExports is the Schema for the partitionexports API + description: ExportedServices is the Schema for the exportedservices API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -47,7 +47,7 @@ spec: metadata: type: object spec: - description: PartitionExportsSpec defines the desired state of PartitionExports + description: ExportedServicesSpec defines the desired state of ExportedServices properties: services: description: Services is a list of services to be exported and the diff --git a/control-plane/config/crd/kustomization.yaml b/control-plane/config/crd/kustomization.yaml deleted file mode 100644 index 1c9666aac6..0000000000 --- a/control-plane/config/crd/kustomization.yaml +++ /dev/null @@ -1,45 +0,0 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default -resources: -- bases/consul.hashicorp.com_servicedefaults.yaml -- bases/consul.hashicorp.com_serviceresolvers.yaml -- bases/consul.hashicorp.com_proxydefaults.yaml -- bases/consul.hashicorp.com_servicerouters.yaml -- bases/consul.hashicorp.com_serviceintentions.yaml -- bases/consul.hashicorp.com_ingressgateways.yaml -- bases/consul.hashicorp.com_terminatinggateways.yaml -- bases/consul.hashicorp.com_meshes.yaml -- bases/consul.hashicorp.com_partitionexports.yaml -# +kubebuilder:scaffold:crdkustomizeresource - -patchesStrategicMerge: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -- patches/webhook_in_servicedefaults.yaml -- patches/webhook_in_serviceresolvers.yaml -- patches/webhook_in_proxydefaults.yaml -- patches/webhook_in_servicerouters.yaml -- patches/webhook_in_serviceintentions.yaml -- patches/webhook_in_ingressgateways.yaml -- patches/webhook_in_terminatinggateways.yaml -#- patches/webhook_in_meshes.yaml -#- patches/webhook_in_partitionexports.yaml -# +kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_servicedefaults.yaml -#- patches/cainjection_in_serviceresolvers.yaml -#- patches/cainjection_in_proxydefaults.yaml -#- patches/cainjection_in_servicerouters.yaml -#- patches/cainjection_in_serviceintentions.yaml -#- patches/cainjection_in_ingressgateways.yaml -#- patches/cainjection_in_terminatinggateways.yaml -#- patches/cainjection_in_meshes.yaml -#- patches/cainjection_in_partitionexports.yaml -# +kubebuilder:scaffold:crdkustomizecainjectionpatch - -# the following config is for teaching kustomize how to do kustomization for CRDs. -configurations: -- kustomizeconfig.yaml diff --git a/control-plane/config/crd/kustomizeconfig.yaml b/control-plane/config/crd/kustomizeconfig.yaml deleted file mode 100644 index 6f83d9a94b..0000000000 --- a/control-plane/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/control-plane/config/crd/patches/cainjection_in_ingressgateways.yaml b/control-plane/config/crd/patches/cainjection_in_ingressgateways.yaml deleted file mode 100644 index aa1074fa2b..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_ingressgateways.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: ingressgateways.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_proxydefaults.yaml b/control-plane/config/crd/patches/cainjection_in_proxydefaults.yaml deleted file mode 100644 index df0460c54c..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_proxydefaults.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: proxydefaults.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_servicedefaults.yaml b/control-plane/config/crd/patches/cainjection_in_servicedefaults.yaml deleted file mode 100644 index 3ae80de8ce..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_servicedefaults.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: servicedefaults.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_serviceintentions.yaml b/control-plane/config/crd/patches/cainjection_in_serviceintentions.yaml deleted file mode 100644 index e53864ab64..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_serviceintentions.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: serviceintentions.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_serviceresolvers.yaml b/control-plane/config/crd/patches/cainjection_in_serviceresolvers.yaml deleted file mode 100644 index 39a09eb8e1..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_serviceresolvers.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: serviceresolvers.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_servicerouters.yaml b/control-plane/config/crd/patches/cainjection_in_servicerouters.yaml deleted file mode 100644 index 798e76fd2a..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_servicerouters.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: servicerouters.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_servicesplitters.yaml b/control-plane/config/crd/patches/cainjection_in_servicesplitters.yaml deleted file mode 100644 index 288ca2cf23..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_servicesplitters.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: servicesplitters.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/cainjection_in_terminatinggateways.yaml b/control-plane/config/crd/patches/cainjection_in_terminatinggateways.yaml deleted file mode 100644 index 9423b79fbf..0000000000 --- a/control-plane/config/crd/patches/cainjection_in_terminatinggateways.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: terminatinggateways.consul.hashicorp.com diff --git a/control-plane/config/crd/patches/webhook_in_ingressgateways.yaml b/control-plane/config/crd/patches/webhook_in_ingressgateways.yaml deleted file mode 100644 index fcc6f69fa5..0000000000 --- a/control-plane/config/crd/patches/webhook_in_ingressgateways.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressgateways.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_partitionexports.yaml b/control-plane/config/crd/patches/webhook_in_partitionexports.yaml deleted file mode 100644 index 3084d0409c..0000000000 --- a/control-plane/config/crd/patches/webhook_in_partitionexports.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: partitionexports.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_proxydefaults.yaml b/control-plane/config/crd/patches/webhook_in_proxydefaults.yaml deleted file mode 100644 index 4d2d4bfff1..0000000000 --- a/control-plane/config/crd/patches/webhook_in_proxydefaults.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: proxydefaults.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_servicedefaults.yaml b/control-plane/config/crd/patches/webhook_in_servicedefaults.yaml deleted file mode 100644 index 774953f50f..0000000000 --- a/control-plane/config/crd/patches/webhook_in_servicedefaults.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: servicedefaults.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_serviceintentions.yaml b/control-plane/config/crd/patches/webhook_in_serviceintentions.yaml deleted file mode 100644 index 77fcdb48ff..0000000000 --- a/control-plane/config/crd/patches/webhook_in_serviceintentions.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: serviceintentions.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_serviceresolvers.yaml b/control-plane/config/crd/patches/webhook_in_serviceresolvers.yaml deleted file mode 100644 index b9f9b42a21..0000000000 --- a/control-plane/config/crd/patches/webhook_in_serviceresolvers.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: serviceresolvers.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_servicerouters.yaml b/control-plane/config/crd/patches/webhook_in_servicerouters.yaml deleted file mode 100644 index e4856434c8..0000000000 --- a/control-plane/config/crd/patches/webhook_in_servicerouters.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: servicerouters.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_servicesplitters.yaml b/control-plane/config/crd/patches/webhook_in_servicesplitters.yaml deleted file mode 100644 index e8f7c1371f..0000000000 --- a/control-plane/config/crd/patches/webhook_in_servicesplitters.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: servicesplitters.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/crd/patches/webhook_in_terminatinggateways.yaml b/control-plane/config/crd/patches/webhook_in_terminatinggateways.yaml deleted file mode 100644 index 05063cc954..0000000000 --- a/control-plane/config/crd/patches/webhook_in_terminatinggateways.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: terminatinggateways.consul.hashicorp.com -spec: - conversion: - strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/control-plane/config/default/kustomization.yaml b/control-plane/config/default/kustomization.yaml deleted file mode 100644 index df978482e5..0000000000 --- a/control-plane/config/default/kustomization.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# Adds namespace to all resources. -namespace: default - -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. -namePrefix: consul-controller- - -# Labels to add to all resources and selectors. -#commonLabels: -# someName: someValue - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - - # Protect the /metrics endpoint by putting it behind auth. - # If you want your controller-manager to expose the /metrics - # endpoint w/o any authn/z, please comment the following line. - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -patchesStrategicMerge: -- manager_auth_proxy_patch.yaml -- manager_webhook_patch.yaml -- webhookcainjection_patch.yaml - -# the following config is for teaching kustomize how to do var substitution -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -vars: -- fieldref: - fieldPath: metadata.namespace - name: CERTIFICATE_NAMESPACE - objref: - group: cert-manager.io - kind: Certificate - name: serving-cert - version: v1alpha2 -- fieldref: {} - name: CERTIFICATE_NAME - objref: - group: cert-manager.io - kind: Certificate - name: serving-cert - version: v1alpha2 -- fieldref: - fieldPath: metadata.namespace - name: SERVICE_NAMESPACE - objref: - kind: Service - name: webhook-service - version: v1 -- fieldref: {} - name: SERVICE_NAME - objref: - kind: Service - name: webhook-service - version: v1 -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../crd -- ../rbac -- ../manager -- ../webhook -- ../certmanager diff --git a/control-plane/config/default/manager_auth_proxy_patch.yaml b/control-plane/config/default/manager_auth_proxy_patch.yaml deleted file mode 100644 index 77e743d1c1..0000000000 --- a/control-plane/config/default/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=10" - ports: - - containerPort: 8443 - name: https - - name: manager - args: - - "--metrics-addr=127.0.0.1:8080" - - "--enable-leader-election" diff --git a/control-plane/config/default/manager_webhook_patch.yaml b/control-plane/config/default/manager_webhook_patch.yaml deleted file mode 100644 index 738de350b7..0000000000 --- a/control-plane/config/default/manager_webhook_patch.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert diff --git a/control-plane/config/default/webhookcainjection_patch.yaml b/control-plane/config/default/webhookcainjection_patch.yaml deleted file mode 100644 index 79c5b20a63..0000000000 --- a/control-plane/config/default/webhookcainjection_patch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/control-plane/config/manager/kustomization.yaml b/control-plane/config/manager/kustomization.yaml deleted file mode 100644 index 957b423a0a..0000000000 --- a/control-plane/config/manager/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -resources: -- manager.yaml -# todo: this was auto-generated -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: ashwinvenkatesh/consul-k8s - newTag: latest diff --git a/control-plane/config/manager/manager.yaml b/control-plane/config/manager/manager.yaml deleted file mode 100644 index b086533218..0000000000 --- a/control-plane/config/manager/manager.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - labels: - control-plane: controller-manager - spec: - containers: - - name: manager - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: CONSUL_HTTP_ADDR - value: http://$(HOST_IP):8500 - command: - - consul-k8s - - controller - args: - - --enable-leader-election - image: controller:latest - resources: - limits: - cpu: 100m - memory: 30Mi - requests: - cpu: 100m - memory: 20Mi - - terminationGracePeriodSeconds: 10 diff --git a/control-plane/config/rbac/auth_proxy_client_clusterrole.yaml b/control-plane/config/rbac/auth_proxy_client_clusterrole.yaml deleted file mode 100644 index 7d62534c5f..0000000000 --- a/control-plane/config/rbac/auth_proxy_client_clusterrole.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: metrics-reader -rules: -- nonResourceURLs: ["/metrics"] - verbs: ["get"] diff --git a/control-plane/config/rbac/auth_proxy_role.yaml b/control-plane/config/rbac/auth_proxy_role.yaml deleted file mode 100644 index 618f5e4177..0000000000 --- a/control-plane/config/rbac/auth_proxy_role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: proxy-role -rules: -- apiGroups: ["authentication.k8s.io"] - resources: - - tokenreviews - verbs: ["create"] -- apiGroups: ["authorization.k8s.io"] - resources: - - subjectaccessreviews - verbs: ["create"] diff --git a/control-plane/config/rbac/auth_proxy_role_binding.yaml b/control-plane/config/rbac/auth_proxy_role_binding.yaml deleted file mode 100644 index 48ed1e4b85..0000000000 --- a/control-plane/config/rbac/auth_proxy_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: proxy-role -subjects: -- kind: ServiceAccount - name: default - namespace: system diff --git a/control-plane/config/rbac/auth_proxy_service.yaml b/control-plane/config/rbac/auth_proxy_service.yaml deleted file mode 100644 index 6cf656be14..0000000000 --- a/control-plane/config/rbac/auth_proxy_service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - targetPort: https - selector: - control-plane: controller-manager diff --git a/control-plane/config/rbac/ingressgateway_editor_role.yaml b/control-plane/config/rbac/ingressgateway_editor_role.yaml deleted file mode 100644 index 424e12e33c..0000000000 --- a/control-plane/config/rbac/ingressgateway_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit ingressgateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: ingressgateway-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - ingressgateways - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - ingressgateways/status - verbs: - - get diff --git a/control-plane/config/rbac/ingressgateway_viewer_role.yaml b/control-plane/config/rbac/ingressgateway_viewer_role.yaml deleted file mode 100644 index 82ca5e79db..0000000000 --- a/control-plane/config/rbac/ingressgateway_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view ingressgateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: ingressgateway-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - ingressgateways - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - ingressgateways/status - verbs: - - get diff --git a/control-plane/config/rbac/kustomization.yaml b/control-plane/config/rbac/kustomization.yaml deleted file mode 100644 index 66c28338fe..0000000000 --- a/control-plane/config/rbac/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -resources: -- role.yaml -- role_binding.yaml -- leader_election_role.yaml -- leader_election_role_binding.yaml -# Comment the following 4 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml -- auth_proxy_client_clusterrole.yaml diff --git a/control-plane/config/rbac/leader_election_role.yaml b/control-plane/config/rbac/leader_election_role.yaml deleted file mode 100644 index 7dc16c420e..0000000000 --- a/control-plane/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - configmaps/status - verbs: - - get - - update - - patch -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/control-plane/config/rbac/leader_election_role_binding.yaml b/control-plane/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index eed16906f4..0000000000 --- a/control-plane/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: default - namespace: system diff --git a/control-plane/config/rbac/partitionexport_editor_role.yaml b/control-plane/config/rbac/partitionexport_editor_role.yaml deleted file mode 100644 index 45b9d4c5c0..0000000000 --- a/control-plane/config/rbac/partitionexport_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit partitionexports. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: partitionexport-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - partitionexports - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - partitionexports/status - verbs: - - get diff --git a/control-plane/config/rbac/partitionexport_viewer_role.yaml b/control-plane/config/rbac/partitionexport_viewer_role.yaml deleted file mode 100644 index ce62786b98..0000000000 --- a/control-plane/config/rbac/partitionexport_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view partitionexports. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: partitionexport-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - partitionexports - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - partitionexports/status - verbs: - - get diff --git a/control-plane/config/rbac/proxydefaults_editor_role.yaml b/control-plane/config/rbac/proxydefaults_editor_role.yaml deleted file mode 100644 index 42afc1a916..0000000000 --- a/control-plane/config/rbac/proxydefaults_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit proxydefaults. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: proxydefaults-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - proxydefaults - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - proxydefaults/status - verbs: - - get diff --git a/control-plane/config/rbac/proxydefaults_viewer_role.yaml b/control-plane/config/rbac/proxydefaults_viewer_role.yaml deleted file mode 100644 index b16fda3894..0000000000 --- a/control-plane/config/rbac/proxydefaults_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view proxydefaults. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: proxydefaults-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - proxydefaults - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - proxydefaults/status - verbs: - - get diff --git a/control-plane/config/rbac/role.yaml b/control-plane/config/rbac/role.yaml index f1a46e72d3..6009210f4b 100644 --- a/control-plane/config/rbac/role.yaml +++ b/control-plane/config/rbac/role.yaml @@ -9,7 +9,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - ingressgateways + - exportedservices verbs: - create - delete @@ -21,7 +21,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - ingressgateways/status + - exportedservices/status verbs: - get - patch @@ -29,7 +29,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - mesh + - ingressgateways verbs: - create - delete @@ -41,7 +41,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - mesh/status + - ingressgateways/status verbs: - get - patch @@ -49,7 +49,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - partitionexports + - mesh verbs: - create - delete @@ -61,7 +61,7 @@ rules: - apiGroups: - consul.hashicorp.com resources: - - partitionexports/status + - mesh/status verbs: - get - patch diff --git a/control-plane/config/rbac/role_binding.yaml b/control-plane/config/rbac/role_binding.yaml deleted file mode 100644 index 8f2658702c..0000000000 --- a/control-plane/config/rbac/role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: default - namespace: system diff --git a/control-plane/config/rbac/servicedefaults_editor_role.yaml b/control-plane/config/rbac/servicedefaults_editor_role.yaml deleted file mode 100644 index f5a7d27a26..0000000000 --- a/control-plane/config/rbac/servicedefaults_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit servicedefaults. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicedefaults-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicedefaults - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicedefaults/status - verbs: - - get diff --git a/control-plane/config/rbac/servicedefaults_viewer_role.yaml b/control-plane/config/rbac/servicedefaults_viewer_role.yaml deleted file mode 100644 index ac9ccc9b3b..0000000000 --- a/control-plane/config/rbac/servicedefaults_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view servicedefaults. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicedefaults-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicedefaults - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicedefaults/status - verbs: - - get diff --git a/control-plane/config/rbac/serviceintentions_editor_role.yaml b/control-plane/config/rbac/serviceintentions_editor_role.yaml deleted file mode 100644 index 83a0437d7d..0000000000 --- a/control-plane/config/rbac/serviceintentions_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit serviceintentions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: serviceintentions-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - serviceintentions - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - serviceintentions/status - verbs: - - get diff --git a/control-plane/config/rbac/serviceintentions_viewer_role.yaml b/control-plane/config/rbac/serviceintentions_viewer_role.yaml deleted file mode 100644 index 6a5f41c960..0000000000 --- a/control-plane/config/rbac/serviceintentions_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view serviceintentions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: serviceintentions-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - serviceintentions - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - serviceintentions/status - verbs: - - get diff --git a/control-plane/config/rbac/serviceresolver_editor_role.yaml b/control-plane/config/rbac/serviceresolver_editor_role.yaml deleted file mode 100644 index 5baff84934..0000000000 --- a/control-plane/config/rbac/serviceresolver_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit serviceresolvers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: serviceresolver-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - serviceresolvers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - serviceresolvers/status - verbs: - - get diff --git a/control-plane/config/rbac/serviceresolver_viewer_role.yaml b/control-plane/config/rbac/serviceresolver_viewer_role.yaml deleted file mode 100644 index ca990258fb..0000000000 --- a/control-plane/config/rbac/serviceresolver_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view serviceresolvers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: serviceresolver-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - serviceresolvers - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - serviceresolvers/status - verbs: - - get diff --git a/control-plane/config/rbac/servicerouter_editor_role.yaml b/control-plane/config/rbac/servicerouter_editor_role.yaml deleted file mode 100644 index c66e6c1ddd..0000000000 --- a/control-plane/config/rbac/servicerouter_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit servicerouters. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicerouter-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicerouters - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicerouters/status - verbs: - - get diff --git a/control-plane/config/rbac/servicerouter_viewer_role.yaml b/control-plane/config/rbac/servicerouter_viewer_role.yaml deleted file mode 100644 index c2cb68dfe8..0000000000 --- a/control-plane/config/rbac/servicerouter_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view servicerouters. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicerouter-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicerouters - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicerouters/status - verbs: - - get diff --git a/control-plane/config/rbac/servicesplitter_editor_role.yaml b/control-plane/config/rbac/servicesplitter_editor_role.yaml deleted file mode 100644 index ec08f8a114..0000000000 --- a/control-plane/config/rbac/servicesplitter_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit servicesplitters. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicesplitter-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicesplitters - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicesplitters/status - verbs: - - get diff --git a/control-plane/config/rbac/servicesplitter_viewer_role.yaml b/control-plane/config/rbac/servicesplitter_viewer_role.yaml deleted file mode 100644 index 6e9458243f..0000000000 --- a/control-plane/config/rbac/servicesplitter_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view servicesplitters. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: servicesplitter-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - servicesplitters - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - servicesplitters/status - verbs: - - get diff --git a/control-plane/config/rbac/terminatinggateway_editor_role.yaml b/control-plane/config/rbac/terminatinggateway_editor_role.yaml deleted file mode 100644 index 6d5da0b881..0000000000 --- a/control-plane/config/rbac/terminatinggateway_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit terminatinggateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: terminatinggateway-editor-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - terminatinggateways - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - terminatinggateways/status - verbs: - - get diff --git a/control-plane/config/rbac/terminatinggateway_viewer_role.yaml b/control-plane/config/rbac/terminatinggateway_viewer_role.yaml deleted file mode 100644 index 6f6c220d59..0000000000 --- a/control-plane/config/rbac/terminatinggateway_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view terminatinggateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: terminatinggateway-viewer-role -rules: -- apiGroups: - - consul.hashicorp.com - resources: - - terminatinggateways - verbs: - - get - - list - - watch -- apiGroups: - - consul.hashicorp.com - resources: - - terminatinggateways/status - verbs: - - get diff --git a/control-plane/config/samples/consul_v1alpha1_ingressgateway.yaml b/control-plane/config/samples/consul_v1alpha1_ingressgateway.yaml deleted file mode 100644 index 9a87883ed0..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_ingressgateway.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: IngressGateway -metadata: - name: ingressgateway-sample -spec: - tls: - enabled: false - listeners: - - port: 8080 - protocol: "tcp" - services: - - name: "foo" diff --git a/control-plane/config/samples/consul_v1alpha1_partitionexport.yaml b/control-plane/config/samples/consul_v1alpha1_partitionexport.yaml deleted file mode 100644 index fa34ecf043..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_partitionexport.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: PartitionExport -metadata: - name: exports -spec: - # Add fields here - foo: bar diff --git a/control-plane/config/samples/consul_v1alpha1_proxydefaults.yaml b/control-plane/config/samples/consul_v1alpha1_proxydefaults.yaml deleted file mode 100644 index 2a87f89ed7..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_proxydefaults.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ProxyDefaults -metadata: - name: proxydefaults-sample -spec: - # Add fields here - foo: bar diff --git a/control-plane/config/samples/consul_v1alpha1_servicedefaults.yaml b/control-plane/config/samples/consul_v1alpha1_servicedefaults.yaml deleted file mode 100644 index f395256b81..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_servicedefaults.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceDefaults -metadata: - name: servicedefaults-sample -spec: - protocol: "http" diff --git a/control-plane/config/samples/consul_v1alpha1_serviceintentions.yaml b/control-plane/config/samples/consul_v1alpha1_serviceintentions.yaml deleted file mode 100644 index 1c6dc83597..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_serviceintentions.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceIntentions -metadata: - name: serviceintentions-sample -spec: - # Add fields here - foo: bar diff --git a/control-plane/config/samples/consul_v1alpha1_serviceresolver.yaml b/control-plane/config/samples/consul_v1alpha1_serviceresolver.yaml deleted file mode 100644 index f1a2f29c8b..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_serviceresolver.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceResolver -metadata: - name: serviceresolver-sample -spec: - # Add fields here - foo: bar diff --git a/control-plane/config/samples/consul_v1alpha1_servicerouter.yaml b/control-plane/config/samples/consul_v1alpha1_servicerouter.yaml deleted file mode 100644 index df597031a9..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_servicerouter.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceRouter -metadata: - name: servicerouter-sample -spec: - routes: - - match: - http: - pathPrefix: "/admin" - destination: - service: admin diff --git a/control-plane/config/samples/consul_v1alpha1_servicesplitter.yaml b/control-plane/config/samples/consul_v1alpha1_servicesplitter.yaml deleted file mode 100644 index a432bd8117..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_servicesplitter.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceSplitter -metadata: - name: servicesplitter-sample -spec: - # Add fields here - foo: bar diff --git a/control-plane/config/samples/consul_v1alpha1_terminatinggateway.yaml b/control-plane/config/samples/consul_v1alpha1_terminatinggateway.yaml deleted file mode 100644 index 4708f6cb8a..0000000000 --- a/control-plane/config/samples/consul_v1alpha1_terminatinggateway.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: TerminatingGateway -metadata: - name: terminatinggateway-sample -spec: - services: - - name: name - caFile: "caFile" - certFile: "certFile" - keyFile: "keyFile" - sni: "sni" diff --git a/control-plane/config/samples/kustomization.yaml b/control-plane/config/samples/kustomization.yaml deleted file mode 100644 index c6cf924560..0000000000 --- a/control-plane/config/samples/kustomization.yaml +++ /dev/null @@ -1,3 +0,0 @@ -## This file is auto-generated, do not modify ## -resources: -- consul_v1alpha1_servicedefaults.yaml diff --git a/control-plane/config/webhook/kustomization.yaml b/control-plane/config/webhook/kustomization.yaml deleted file mode 100644 index 9cf26134e4..0000000000 --- a/control-plane/config/webhook/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -resources: -- manifests.yaml -- service.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/control-plane/config/webhook/kustomizeconfig.yaml b/control-plane/config/webhook/kustomizeconfig.yaml deleted file mode 100644 index 25e21e3c96..0000000000 --- a/control-plane/config/webhook/kustomizeconfig.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# the following config is for teaching kustomize where to look at when substituting vars. -# It requires kustomize v2.1.0 or newer to work properly. -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: MutatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/name - - kind: ValidatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/name - -namespace: -- kind: MutatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/namespace - create: true -- kind: ValidatingWebhookConfiguration - group: admissionregistration.k8s.io - path: webhooks/clientConfig/service/namespace - create: true - -varReference: -- path: metadata/annotations diff --git a/control-plane/config/webhook/manifests.yaml b/control-plane/config/webhook/manifests.yaml index 8264b31887..ae0eb15fc5 100644 --- a/control-plane/config/webhook/manifests.yaml +++ b/control-plane/config/webhook/manifests.yaml @@ -13,9 +13,9 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-v1alpha1-ingressgateway + path: /mutate-v1alpha1-exportedservices failurePolicy: Fail - name: mutate-ingressgateway.consul.hashicorp.com + name: mutate-exportedservices.consul.hashicorp.com rules: - apiGroups: - consul.hashicorp.com @@ -25,7 +25,7 @@ webhooks: - CREATE - UPDATE resources: - - ingressgateways + - exportedservices sideEffects: None - admissionReviewVersions: - v1beta1 @@ -34,9 +34,9 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-v1alpha1-mesh + path: /mutate-v1alpha1-ingressgateway failurePolicy: Fail - name: mutate-mesh.consul.hashicorp.com + name: mutate-ingressgateway.consul.hashicorp.com rules: - apiGroups: - consul.hashicorp.com @@ -46,7 +46,7 @@ webhooks: - CREATE - UPDATE resources: - - mesh + - ingressgateways sideEffects: None - admissionReviewVersions: - v1beta1 @@ -55,9 +55,9 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-v1alpha1-partitionexports + path: /mutate-v1alpha1-mesh failurePolicy: Fail - name: mutate-partitionexports.consul.hashicorp.com + name: mutate-mesh.consul.hashicorp.com rules: - apiGroups: - consul.hashicorp.com @@ -67,7 +67,7 @@ webhooks: - CREATE - UPDATE resources: - - partitionexports + - mesh sideEffects: None - admissionReviewVersions: - v1beta1 diff --git a/control-plane/config/webhook/service.yaml b/control-plane/config/webhook/service.yaml deleted file mode 100644 index 31e0f82959..0000000000 --- a/control-plane/config/webhook/service.yaml +++ /dev/null @@ -1,12 +0,0 @@ - -apiVersion: v1 -kind: Service -metadata: - name: webhook-service - namespace: system -spec: - ports: - - port: 443 - targetPort: 9443 - selector: - control-plane: controller-manager diff --git a/control-plane/controller/partitionexports_controller.go b/control-plane/controller/exportedservices_controller.go similarity index 52% rename from control-plane/controller/partitionexports_controller.go rename to control-plane/controller/exportedservices_controller.go index fd1034a81b..be0445f4a1 100644 --- a/control-plane/controller/partitionexports_controller.go +++ b/control-plane/controller/exportedservices_controller.go @@ -12,29 +12,29 @@ import ( consulv1alpha1 "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" ) -// PartitionExportsController reconciles a PartitionExports object -type PartitionExportsController struct { +// ExportedServicesController reconciles a ExportedServices object +type ExportedServicesController struct { client.Client Log logr.Logger Scheme *runtime.Scheme ConfigEntryController *ConfigEntryController } -// +kubebuilder:rbac:groups=consul.hashicorp.com,resources=partitionexports,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=consul.hashicorp.com,resources=partitionexports/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=consul.hashicorp.com,resources=exportedservices,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=consul.hashicorp.com,resources=exportedservices/status,verbs=get;update;patch -func (r *PartitionExportsController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - return r.ConfigEntryController.ReconcileEntry(ctx, r, req, &consulv1alpha1.PartitionExports{}) +func (r *ExportedServicesController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + return r.ConfigEntryController.ReconcileEntry(ctx, r, req, &consulv1alpha1.ExportedServices{}) } -func (r *PartitionExportsController) Logger(name types.NamespacedName) logr.Logger { +func (r *ExportedServicesController) Logger(name types.NamespacedName) logr.Logger { return r.Log.WithValues("request", name) } -func (r *PartitionExportsController) UpdateStatus(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { +func (r *ExportedServicesController) UpdateStatus(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { return r.Status().Update(ctx, obj, opts...) } -func (r *PartitionExportsController) SetupWithManager(mgr ctrl.Manager) error { - return setupWithManager(mgr, &consulv1alpha1.PartitionExports{}, r) +func (r *ExportedServicesController) SetupWithManager(mgr ctrl.Manager) error { + return setupWithManager(mgr, &consulv1alpha1.ExportedServices{}, r) } diff --git a/control-plane/controller/partitionexports_controller_ent_test.go b/control-plane/controller/exportedservices_controller_ent_test.go similarity index 80% rename from control-plane/controller/partitionexports_controller_ent_test.go rename to control-plane/controller/exportedservices_controller_ent_test.go index 02ed8bf31a..72acdabf2c 100644 --- a/control-plane/controller/partitionexports_controller_ent_test.go +++ b/control-plane/controller/exportedservices_controller_ent_test.go @@ -23,14 +23,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -// This tests explicitly tests PartitionExportsController instead of using the existing +// This tests explicitly tests ExportedServicesController instead of using the existing // pattern of adding tests for the controller to configentry_controller test. That is because -// unlike the other CRDs, PartitionExports are only supported in Consul Enterprise. But the +// unlike the other CRDs, ExportedServices are only supported in Consul Enterprise. But the // test pattern of the enterprise tests already covers a config-entry similar to partition-exports // ie a "global" configentry. Hence a separate file has been created to test this controller. -func TestPartitionExportsController_createsPartitionExports(tt *testing.T) { +func TestExportedServicesController_createsExportedServices(tt *testing.T) { tt.Parallel() + tt.Skip() cases := map[string]struct { Mirror bool @@ -73,12 +74,12 @@ func TestPartitionExportsController_createsPartitionExports(tt *testing.T) { tt.Run(name, func(t *testing.T) { req := require.New(t) s := runtime.NewScheme() - partitionExport := &v1alpha1.PartitionExports{ + exportedServices := &v1alpha1.ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Namespace: c.SourceKubeNS, }, - Spec: v1alpha1.PartitionExportsSpec{ + Spec: v1alpha1.ExportedServicesSpec{ Services: []v1alpha1.ExportedService{ { Name: "frontend", @@ -91,7 +92,7 @@ func TestPartitionExportsController_createsPartitionExports(tt *testing.T) { }, }, } - s.AddKnownTypes(v1alpha1.GroupVersion, partitionExport) + s.AddKnownTypes(v1alpha1.GroupVersion, exportedServices) ctx := context.Background() consul, err := testutil.NewTestServerConfigT(t, nil) @@ -103,9 +104,9 @@ func TestPartitionExportsController_createsPartitionExports(tt *testing.T) { }) req.NoError(err) - fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(partitionExport).Build() + fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(exportedServices).Build() - controller := &controller.PartitionExportsController{ + controller := &controller.ExportedServicesController{ Client: fakeClient, Log: logrtest.TestLogger{T: t}, Scheme: s, @@ -121,35 +122,36 @@ func TestPartitionExportsController_createsPartitionExports(tt *testing.T) { resp, err := controller.Reconcile(ctx, ctrl.Request{ NamespacedName: types.NamespacedName{ Namespace: c.SourceKubeNS, - Name: partitionExport.KubernetesName(), + Name: exportedServices.KubernetesName(), }, }) req.NoError(err) req.False(resp.Requeue) - cfg, _, err := consulClient.ConfigEntries().Get(capi.PartitionExports, partitionExport.ConsulName(), &capi.QueryOptions{ + cfg, _, err := consulClient.ConfigEntries().Get(capi.ExportedServices, exportedServices.ConsulName(), &capi.QueryOptions{ Namespace: common.DefaultConsulNamespace, }) req.NoError(err) - configEntry, ok := cfg.(*capi.PartitionExportsConfigEntry) + configEntry, ok := cfg.(*capi.ExportedServicesConfigEntry) req.True(ok) req.Equal(configEntry.Services[0].Name, "frontend") // Check that the status is "synced". err = fakeClient.Get(ctx, types.NamespacedName{ Namespace: c.SourceKubeNS, - Name: partitionExport.KubernetesName(), - }, partitionExport) + Name: exportedServices.KubernetesName(), + }, exportedServices) req.NoError(err) - conditionSynced := partitionExport.SyncedConditionStatus() + conditionSynced := exportedServices.SyncedConditionStatus() req.Equal(conditionSynced, corev1.ConditionTrue) }) } } -func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { +func TestExportedServicesController_updatesExportedServices(tt *testing.T) { tt.Parallel() + tt.Skip() cases := map[string]struct { Mirror bool @@ -192,13 +194,13 @@ func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { tt.Run(name, func(t *testing.T) { req := require.New(t) s := runtime.NewScheme() - partitionExport := &v1alpha1.PartitionExports{ + exportedServices := &v1alpha1.ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Namespace: c.SourceKubeNS, Finalizers: []string{controller.FinalizerName}, }, - Spec: v1alpha1.PartitionExportsSpec{ + Spec: v1alpha1.ExportedServicesSpec{ Services: []v1alpha1.ExportedService{ { Name: "frontend", @@ -211,7 +213,7 @@ func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { }, }, } - s.AddKnownTypes(v1alpha1.GroupVersion, partitionExport) + s.AddKnownTypes(v1alpha1.GroupVersion, exportedServices) ctx := context.Background() consul, err := testutil.NewTestServerConfigT(t, nil) @@ -223,9 +225,9 @@ func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { }) req.NoError(err) - fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(partitionExport).Build() + fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(exportedServices).Build() - controller := &controller.PartitionExportsController{ + controller := &controller.ExportedServicesController{ Client: fakeClient, Log: logrtest.TestLogger{T: t}, Scheme: s, @@ -240,7 +242,7 @@ func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { // We haven't run reconcile yet so ensure it's created in Consul. { - _, _, err := consulClient.ConfigEntries().Set(&capi.PartitionExportsConfigEntry{ + _, _, err := consulClient.ConfigEntries().Set(&capi.ExportedServicesConfigEntry{ Name: "default", Services: []capi.ExportedService{ { @@ -261,37 +263,38 @@ func TestPartitionExportsController_updatesPartitionExports(tt *testing.T) { // First get it so we have the latest revision number. err = fakeClient.Get(ctx, types.NamespacedName{ Namespace: c.SourceKubeNS, - Name: partitionExport.KubernetesName(), - }, partitionExport) + Name: exportedServices.KubernetesName(), + }, exportedServices) req.NoError(err) // Update the resource. - partitionExport.Spec.Services[0].Name = "backend" - err := fakeClient.Update(ctx, partitionExport) + exportedServices.Spec.Services[0].Name = "backend" + err := fakeClient.Update(ctx, exportedServices) req.NoError(err) resp, err := controller.Reconcile(ctx, ctrl.Request{ NamespacedName: types.NamespacedName{ Namespace: c.SourceKubeNS, - Name: partitionExport.KubernetesName(), + Name: exportedServices.KubernetesName(), }, }) req.NoError(err) req.False(resp.Requeue) - cfg, _, err := consulClient.ConfigEntries().Get(capi.PartitionExports, partitionExport.ConsulName(), &capi.QueryOptions{ + cfg, _, err := consulClient.ConfigEntries().Get(capi.ExportedServices, exportedServices.ConsulName(), &capi.QueryOptions{ Namespace: common.DefaultConsulNamespace, }) req.NoError(err) - entry := cfg.(*capi.PartitionExportsConfigEntry) + entry := cfg.(*capi.ExportedServicesConfigEntry) req.Equal("backend", entry.Services[0].Name) } }) } } -func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { +func TestExportedServicesController_deletesExportedServices(tt *testing.T) { tt.Parallel() + tt.Skip() cases := map[string]struct { Mirror bool @@ -334,14 +337,14 @@ func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { tt.Run(name, func(t *testing.T) { req := require.New(t) s := runtime.NewScheme() - partitionExport := &v1alpha1.PartitionExports{ + exportedServices := &v1alpha1.ExportedServices{ ObjectMeta: metav1.ObjectMeta{ Name: "default", Namespace: c.SourceKubeNS, Finalizers: []string{controller.FinalizerName}, DeletionTimestamp: &metav1.Time{Time: time.Now()}, }, - Spec: v1alpha1.PartitionExportsSpec{ + Spec: v1alpha1.ExportedServicesSpec{ Services: []v1alpha1.ExportedService{ { Name: "frontend", @@ -354,7 +357,7 @@ func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { }, }, } - s.AddKnownTypes(v1alpha1.GroupVersion, partitionExport) + s.AddKnownTypes(v1alpha1.GroupVersion, exportedServices) consul, err := testutil.NewTestServerConfigT(t, nil) req.NoError(err) @@ -365,9 +368,9 @@ func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { }) req.NoError(err) - fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(partitionExport).Build() + fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(exportedServices).Build() - controller := &controller.PartitionExportsController{ + controller := &controller.ExportedServicesController{ Client: fakeClient, Log: logrtest.TestLogger{T: t}, Scheme: s, @@ -382,7 +385,7 @@ func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { // We haven't run reconcile yet so ensure it's created in Consul. { - _, _, err := consulClient.ConfigEntries().Set(&capi.PartitionExportsConfigEntry{ + _, _, err := consulClient.ConfigEntries().Set(&capi.ExportedServicesConfigEntry{ Name: "default", Services: []capi.ExportedService{ { @@ -404,16 +407,16 @@ func TestPartitionExportsController_deletesPartitionExports(tt *testing.T) { resp, err := controller.Reconcile(context.Background(), ctrl.Request{ NamespacedName: types.NamespacedName{ Namespace: c.SourceKubeNS, - Name: partitionExport.KubernetesName(), + Name: exportedServices.KubernetesName(), }, }) req.NoError(err) req.False(resp.Requeue) - _, _, err = consulClient.ConfigEntries().Get(capi.PartitionExports, partitionExport.ConsulName(), &capi.QueryOptions{ + _, _, err = consulClient.ConfigEntries().Get(capi.ExportedServices, exportedServices.ConsulName(), &capi.QueryOptions{ Namespace: common.DefaultConsulNamespace, }) - req.EqualError(err, fmt.Sprintf(`Unexpected response code: 404 (Config entry not found for "%s" / "%s")`, capi.PartitionExports, partitionExport.ConsulName())) + req.EqualError(err, fmt.Sprintf(`Unexpected response code: 404 (Config entry not found for "%s" / "%s")`, capi.ExportedServices, exportedServices.ConsulName())) } }) } diff --git a/control-plane/go.mod b/control-plane/go.mod index 6f1d560066..2e1a81424b 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-logr/logr v0.4.0 github.com/google/go-cmp v0.5.6 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f + github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc github.com/hashicorp/consul/sdk v0.8.0 github.com/hashicorp/go-discover v0.0.0-20200812215701-c4b85f6ed31f github.com/hashicorp/go-hclog v0.16.1 diff --git a/control-plane/go.sum b/control-plane/go.sum index 179772df60..6877dd034c 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -297,8 +297,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f h1:fBBh4412td7nBzqyLkpGTH5dWycPs8p7Yg/Dy8VQjVU= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= diff --git a/control-plane/subcommand/controller/command.go b/control-plane/subcommand/controller/command.go index 38bc7cc0df..389421e830 100644 --- a/control-plane/subcommand/controller/command.go +++ b/control-plane/subcommand/controller/command.go @@ -193,13 +193,13 @@ func (c *Command) Run(args []string) int { setupLog.Error(err, "unable to create controller", "controller", common.Mesh) return 1 } - if err = (&controller.PartitionExportsController{ + if err = (&controller.ExportedServicesController{ ConfigEntryController: configEntryReconciler, Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controller").WithName(common.PartitionExports), + Log: ctrl.Log.WithName("controller").WithName(common.ExportedServices), Scheme: mgr.GetScheme(), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", common.PartitionExports) + setupLog.Error(err, "unable to create controller", "controller", common.ExportedServices) return 1 } if err = (&controller.ServiceRouterController{ @@ -282,11 +282,11 @@ func (c *Command) Run(args []string) int { ConsulClient: consulClient, Logger: ctrl.Log.WithName("webhooks").WithName(common.Mesh), }}) - mgr.GetWebhookServer().Register("/mutate-v1alpha1-partitionexports", - &webhook.Admission{Handler: &v1alpha1.PartitionExportsWebhook{ + mgr.GetWebhookServer().Register("/mutate-v1alpha1-exportedservices", + &webhook.Admission{Handler: &v1alpha1.ExportedServicesWebhook{ Client: mgr.GetClient(), ConsulClient: consulClient, - Logger: ctrl.Log.WithName("webhooks").WithName(common.PartitionExports), + Logger: ctrl.Log.WithName("webhooks").WithName(common.ExportedServices), ConsulMeta: consulMeta, }}) mgr.GetWebhookServer().Register("/mutate-v1alpha1-servicerouter", diff --git a/control-plane/subcommand/partition-init/command.go b/control-plane/subcommand/partition-init/command.go index 4b75f9634f..8846d42efc 100644 --- a/control-plane/subcommand/partition-init/command.go +++ b/control-plane/subcommand/partition-init/command.go @@ -153,7 +153,7 @@ func (c *Command) Run(args []string) int { c.log.Error("Error reading Partition from Consul", "name", c.flagPartitionName, "error", err.Error()) } else if partition == nil { // Retry Admin Partition creation until it succeeds, or we reach the command timeout. - _, _, err = consulClient.Partitions().Create(c.ctx, &api.AdminPartition{ + _, _, err = consulClient.Partitions().Create(c.ctx, &api.Partition{ Name: c.flagPartitionName, Description: "Created by Helm installation", }, nil) diff --git a/control-plane/subcommand/partition-init/command_ent_test.go b/control-plane/subcommand/partition-init/command_ent_test.go index 8ed91cec14..22bb9b8651 100644 --- a/control-plane/subcommand/partition-init/command_ent_test.go +++ b/control-plane/subcommand/partition-init/command_ent_test.go @@ -94,7 +94,7 @@ func TestRun_PartitionExists(t *testing.T) { require.NoError(t, err) // Create the Admin Partition before the test runs. - _, _, err = consul.Partitions().Create(context.Background(), &api.AdminPartition{Name: partitionName, Description: "Created before test"}, nil) + _, _, err = consul.Partitions().Create(context.Background(), &api.Partition{Name: partitionName, Description: "Created before test"}, nil) require.NoError(t, err) ui := cli.NewMockUi() diff --git a/control-plane/subcommand/server-acl-init/command.go b/control-plane/subcommand/server-acl-init/command.go index 5c12dd1523..a5daefc8f5 100644 --- a/control-plane/subcommand/server-acl-init/command.go +++ b/control-plane/subcommand/server-acl-init/command.go @@ -793,6 +793,12 @@ type Config struct { // createAnonymousPolicy returns whether we should create a policy for the // anonymous ACL token, i.e. queries without ACL tokens. func (c *Command) createAnonymousPolicy(isPrimary bool) bool { + // Don't try to create the anonymous policy in non-default partitions because + // non-default partitions will use the anonymous policy from the default + // partition. + if c.flagEnablePartitions && c.flagPartitionName != "default" { + return false + } // If isPrimary is not set then we're in a secondary DC. // In this case we assume that the primary datacenter has already created // the anonymous policy and attached it to the anonymous token. From ce6b2a7df372ed7d4aac044300ebeec133cee507 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 8 Dec 2021 12:46:59 -0500 Subject: [PATCH 43/70] Add support for tproxy for partitions test (#901) * Add support for tproxy for partitions test --- acceptance/framework/k8s/deploy.go | 1 + acceptance/go.mod | 4 +- acceptance/go.sum | 8 +- .../controller/controller_namespaces_test.go | 2 +- .../tests/partitions/partitions_test.go | 137 ++++++++++++++---- 5 files changed, 119 insertions(+), 33 deletions(-) diff --git a/acceptance/framework/k8s/deploy.go b/acceptance/framework/k8s/deploy.go index 6616e6f45c..2cf5e8876a 100644 --- a/acceptance/framework/k8s/deploy.go +++ b/acceptance/framework/k8s/deploy.go @@ -134,6 +134,7 @@ func CheckStaticServerConnectionFailing(t *testing.T, options *k8s.KubectlOption CheckStaticServerConnection(t, options, false, []string{ "curl: (52) Empty reply from server", "curl: (7) Failed to connect", + "curl: (56) Recv failure: Connection reset by peer", }, curlArgs...) } diff --git a/acceptance/go.mod b/acceptance/go.mod index 62efc96a62..f91df929e2 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/gruntwork-io/terratest v0.31.2 - github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 + github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638 github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc github.com/hashicorp/consul/sdk v0.8.0 github.com/hashicorp/vault/api v1.2.0 @@ -70,6 +70,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/oklog/run v1.0.0 // indirect + github.com/onsi/ginkgo v1.16.4 // indirect + github.com/onsi/gomega v1.15.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 3340d47075..9b20650867 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -383,11 +383,12 @@ github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arn github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51 h1:Km6RYuAsJVVu3gipkTWF1SVYuvSJrksBtT89rO4hcdA= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211118191758-929940b5ab51/go.mod h1:+Ay3RL0eZdI0wgT193r+EJTOk9cSn1WUlvBvk6Lfnmo= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638 h1:z68s6H6O3RjxDmNvou/2/3UBrsJkrMcNzI0IQN5scAM= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638/go.mod h1:7ZeaiADGbvJDuoWAT8UKj6KCcLsFUk+34OkUGMVtdXg= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -1291,7 +1292,6 @@ sigs.k8s.io/controller-runtime v0.10.2/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkG sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/acceptance/tests/controller/controller_namespaces_test.go b/acceptance/tests/controller/controller_namespaces_test.go index e303246bfe..483fc96106 100644 --- a/acceptance/tests/controller/controller_namespaces_test.go +++ b/acceptance/tests/controller/controller_namespaces_test.go @@ -74,7 +74,7 @@ func TestControllerNamespaces(t *testing.T) { ctx := suite.Environment().DefaultContext(t) helmValues := map[string]string{ - "global.image": "ashwinvenkatesh/consul@sha256:4be07b9c90fc590827ad72328da332c2003a14d237df317a0c977817f6fdaf0b", + "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", "global.enableConsulNamespaces": "true", "global.adminPartitions.enabled": "true", diff --git a/acceptance/tests/partitions/partitions_test.go b/acceptance/tests/partitions/partitions_test.go index 7f2d21581b..001a2f431c 100644 --- a/acceptance/tests/partitions/partitions_test.go +++ b/acceptance/tests/partitions/partitions_test.go @@ -37,7 +37,7 @@ func TestPartitions(t *testing.T) { } if cfg.EnableTransparentProxy { - t.Skipf("skipping this test because -enable-transparent-proxy is true") + t.Skipf("skipping this test as Transparent Proxy behavior is flaky") } const defaultPartition = "default" @@ -110,7 +110,6 @@ func TestPartitions(t *testing.T) { // When mirroringK8S is set, this setting is ignored. "connectInject.consulNamespaces.consulDestinationNamespace": c.destinationNamespace, "connectInject.consulNamespaces.mirroringK8S": strconv.FormatBool(c.mirrorK8S), - "connectInject.transparentProxy.defaultEnabled": "false", "global.acls.manageSystemACLs": strconv.FormatBool(c.secure), @@ -118,6 +117,8 @@ func TestPartitions(t *testing.T) { "meshGateway.replicas": "1", "controller.enabled": "true", + + "dns.enabled": "true", } if cfg.UseKind { @@ -127,6 +128,10 @@ func TestPartitions(t *testing.T) { serverHelmValues["meshGateway.service.nodePort"] = "30100" } + if cfg.EnableTransparentProxy { + serverHelmValues["dns.enableRedirection"] = "true" + } + releaseName := helpers.RandomName() // Install the consul cluster with servers in the default kubernetes context. @@ -205,7 +210,6 @@ func TestPartitions(t *testing.T) { // When mirroringK8S is set, this setting is ignored. "connectInject.consulNamespaces.consulDestinationNamespace": c.destinationNamespace, "connectInject.consulNamespaces.mirroringK8S": strconv.FormatBool(c.mirrorK8S), - "connectInject.transparentProxy.defaultEnabled": "false", "global.acls.manageSystemACLs": strconv.FormatBool(c.secure), @@ -228,6 +232,8 @@ func TestPartitions(t *testing.T) { "client.enabled": "true", "client.exposeGossipPorts": "true", "client.join[0]": partitionSvcIP, + + "dns.enabled": "true", } if c.secure { @@ -247,6 +253,10 @@ func TestPartitions(t *testing.T) { clientHelmValues["meshGateway.service.nodePort"] = "30100" } + if cfg.EnableTransparentProxy { + clientHelmValues["dns.enableRedirection"] = "true" + } + // Install the consul cluster without servers in the client cluster kubernetes context. clientConsulCluster := consul.NewHelmCluster(t, clientHelmValues, clientClusterContext, cfg, releaseName) clientConsulCluster.Create(t) @@ -364,17 +374,25 @@ func TestPartitions(t *testing.T) { logger.Log(t, "test in-partition networking") logger.Log(t, "creating static-server and static-client deployments in server cluster") k8s.DeployKustomize(t, serverClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + if c.destinationNamespace == defaultNamespace { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + } else { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + } } logger.Log(t, "creating static-server and static-client deployments in client cluster") k8s.DeployKustomize(t, clientClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + if c.destinationNamespace == defaultNamespace { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + } else { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + } } // Check that both static-server and static-client have been injected and now have 2 containers in server cluster. for _, labelSelector := range []string{"app=static-server", "app=static-client"} { @@ -422,8 +440,13 @@ func TestPartitions(t *testing.T) { if c.secure { logger.Log(t, "checking that the connection is not successful because there's no intention") - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, "http://localhost:1234") - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, "http://localhost:1234") + if cfg.EnableTransparentProxy { + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + } else { + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, "http://localhost:1234") + } intention := &api.ServiceIntentionsConfigEntry{ Kind: api.ServiceIntentions, @@ -450,11 +473,22 @@ func TestPartitions(t *testing.T) { require.NoError(t, err) _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + _, err := consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: defaultPartition}) + require.NoError(t, err) + _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: secondaryPartition}) + require.NoError(t, err) + }) } logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, "http://localhost:1234") - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, "http://localhost:1234") + if cfg.EnableTransparentProxy { + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + } else { + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, "http://localhost:1234") + } // Test that kubernetes readiness status is synced to Consul. // Create the file so that the readiness probe of the static-server pod fails. @@ -468,25 +502,38 @@ func TestPartitions(t *testing.T) { // there will be no healthy proxy host to connect to. That's why we can't assert that we receive an empty reply // from server, which is the case when a connection is unsuccessful due to intentions in other tests. logger.Log(t, "checking that connection is unsuccessful") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + if cfg.EnableTransparentProxy { + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + } else { + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + } }) // This section of the tests run the cross-partition networking tests. t.Run("cross-partition", func(t *testing.T) { logger.Log(t, "test cross-partition networking") logger.Log(t, "creating static-server and static-client deployments in server cluster") k8s.DeployKustomize(t, serverClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-partition") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-partition") + if c.destinationNamespace == defaultNamespace { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-partition") + } else { + k8s.DeployKustomize(t, serverClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-partition") + } } logger.Log(t, "creating static-server and static-client deployments in client cluster") k8s.DeployKustomize(t, clientClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-default-partition") + if cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-default-partition") + if c.destinationNamespace == defaultNamespace { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-default-partition") + } else { + k8s.DeployKustomize(t, clientClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-default-partition") + } } // Check that both static-server and static-client have been injected and now have 2 containers in server cluster. for _, labelSelector := range []string{"app=static-server", "app=static-client"} { @@ -554,8 +601,18 @@ func TestPartitions(t *testing.T) { if c.secure { logger.Log(t, "checking that the connection is not successful because there's no intention") - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, "http://localhost:1234") - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, "http://localhost:1234") + if cfg.EnableTransparentProxy { + if !c.mirrorK8S { + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) + } else { + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) + } + } else { + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, "http://localhost:1234") + } intention := &api.ServiceIntentionsConfigEntry{ Name: staticServerName, @@ -584,11 +641,27 @@ func TestPartitions(t *testing.T) { intention.Sources[0].Partition = defaultPartition _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + _, err := consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: defaultPartition}) + require.NoError(t, err) + _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: secondaryPartition}) + require.NoError(t, err) + }) } logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, "http://localhost:1234") - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, "http://localhost:1234") + if cfg.EnableTransparentProxy { + if !c.mirrorK8S { + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) + } else { + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) + } + } else { + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, "http://localhost:1234") + } // Test that kubernetes readiness status is synced to Consul. // Create the file so that the readiness probe of the static-server pod fails. @@ -602,8 +675,18 @@ func TestPartitions(t *testing.T) { // there will be no healthy proxy host to connect to. That's why we can't assert that we receive an empty reply // from server, which is the case when a connection is unsuccessful due to intentions in other tests. logger.Log(t, "checking that connection is unsuccessful") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + if cfg.EnableTransparentProxy { + if !c.mirrorK8S { + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) + } else { + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server.ns1 port 80: Connection refused"}, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) + } + } else { + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "http://localhost:1234") + } }) }) } From b7f933172ea3a51e187169ff9b048dc4a2d8e307 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 8 Dec 2021 13:05:23 -0500 Subject: [PATCH 44/70] Update service resolver/splitter/router with partitions (#908) * Update service resolver/splitter/router with partitions --- CHANGELOG.md | 1 + acceptance/go.sum | 6 +- .../templates/crd-serviceresolvers.yaml | 10 +- .../consul/templates/crd-servicerouters.yaml | 5 + .../templates/crd-servicesplitters.yaml | 11 +- .../api/v1alpha1/serviceresolver_types.go | 21 +++- .../v1alpha1/serviceresolver_types_test.go | 66 ++++++++++- .../api/v1alpha1/servicerouter_types.go | 19 +++- .../api/v1alpha1/servicerouter_types_test.go | 104 +++++++++++++++++- .../api/v1alpha1/servicesplitter_types.go | 21 +++- .../v1alpha1/servicesplitter_types_test.go | 95 +++++++++++++++- ...consul.hashicorp.com_serviceresolvers.yaml | 10 +- .../consul.hashicorp.com_servicerouters.yaml | 5 + ...consul.hashicorp.com_servicesplitters.yaml | 11 +- 14 files changed, 356 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aa0c5ad14..46639b8283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ IMPROVEMENTS: * Helm Chart * Fail an installation/upgrade if WAN federation and Admin Partitions are both enabled. [[GH-892](https://github.com/hashicorp/consul-k8s/issues/892)] * Add support for setting `ingressClassName` for UI. [[GH-909](https://github.com/hashicorp/consul-k8s/pull/909)] + * Add partition support to Service Resolver, Service Router and Service Splitter CRDs. [[GH-908](https://github.com/hashicorp/consul-k8s/issues/908)] BUG FIXES: * Control Plane: diff --git a/acceptance/go.sum b/acceptance/go.sum index 9b20650867..3459220dc4 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -383,15 +383,17 @@ github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arn github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= -github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= -github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638 h1:z68s6H6O3RjxDmNvou/2/3UBrsJkrMcNzI0IQN5scAM= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638/go.mod h1:7ZeaiADGbvJDuoWAT8UKj6KCcLsFUk+34OkUGMVtdXg= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/charts/consul/templates/crd-serviceresolvers.yaml b/charts/consul/templates/crd-serviceresolvers.yaml index 998bc0e6e0..2bf85cbf0a 100644 --- a/charts/consul/templates/crd-serviceresolvers.yaml +++ b/charts/consul/templates/crd-serviceresolvers.yaml @@ -186,8 +186,14 @@ spec: from instead of the current one. type: string namespace: - description: Namespace is the namespace to resolve the service - from instead of the current one. + description: Namespace is the Consul namespace to resolve the + service from instead of the current namespace. If empty the + current namespace is assumed. + type: string + partition: + description: Partition is the Consul partition to resolve the + service from instead of the current partition. If empty the + current partition is assumed. type: string service: description: Service is a service to resolve instead of the current diff --git a/charts/consul/templates/crd-servicerouters.yaml b/charts/consul/templates/crd-servicerouters.yaml index ac8905ca2c..ac0f515b8e 100644 --- a/charts/consul/templates/crd-servicerouters.yaml +++ b/charts/consul/templates/crd-servicerouters.yaml @@ -76,6 +76,11 @@ spec: the request when a retryable result occurs format: int32 type: integer + partition: + description: Partition is the Consul partition to resolve + the service from instead of the current partition. If + empty the current partition is assumed. + type: string prefixRewrite: description: PrefixRewrite defines how to rewrite the HTTP request path before proxying it to its final destination. diff --git a/charts/consul/templates/crd-servicesplitters.yaml b/charts/consul/templates/crd-servicesplitters.yaml index f7bb3e5246..e91b16db6c 100644 --- a/charts/consul/templates/crd-servicesplitters.yaml +++ b/charts/consul/templates/crd-servicesplitters.yaml @@ -62,9 +62,14 @@ spec: items: properties: namespace: - description: The namespace to resolve the service from instead - of the current namespace. If empty the current namespace is - assumed. + description: Namespace is the Consul namespace to resolve the + service from instead of the current namespace. If empty the + current namespace is assumed. + type: string + partition: + description: Partition is the Consul partition to resolve the + service from instead of the current partition. If empty the + current partition is assumed. type: string requestHeaders: description: Allow HTTP header manipulation to be configured. diff --git a/control-plane/api/v1alpha1/serviceresolver_types.go b/control-plane/api/v1alpha1/serviceresolver_types.go index f0ea92d300..8def0f2fa4 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types.go +++ b/control-plane/api/v1alpha1/serviceresolver_types.go @@ -81,9 +81,12 @@ type ServiceResolverRedirect struct { // of one defined as that service's DefaultSubset If empty the default // subset is used. ServiceSubset string `json:"serviceSubset,omitempty"` - // Namespace is the namespace to resolve the service from instead of the - // current one. + // Namespace is the Consul namespace to resolve the service from instead of + // the current namespace. If empty the current namespace is assumed. Namespace string `json:"namespace,omitempty"` + // Partition is the Consul partition to resolve the service from instead of + // the current partition. If empty the current partition is assumed. + Partition string `json:"partition,omitempty"` // Datacenter is the datacenter to resolve the service from instead of the // current one. Datacenter string `json:"datacenter,omitempty"` @@ -301,7 +304,7 @@ func (in *ServiceResolver) Validate(consulMeta common.ConsulMeta) error { errs = append(errs, in.Spec.LoadBalancer.validate(path.Child("loadBalancer"))...) - errs = append(errs, in.validateNamespaces(consulMeta.NamespacesEnabled)...) + errs = append(errs, in.validateEnterprise(consulMeta)...) if len(errs) > 0 { return apierrors.NewInvalid( @@ -435,10 +438,10 @@ func (in *CookieConfig) validate(path *field.Path) *field.Error { return nil } -func (in *ServiceResolver) validateNamespaces(namespacesEnabled bool) field.ErrorList { +func (in *ServiceResolver) validateEnterprise(consulMeta common.ConsulMeta) field.ErrorList { var errs field.ErrorList path := field.NewPath("spec") - if !namespacesEnabled { + if !consulMeta.NamespacesEnabled { if in.Spec.Redirect != nil { if in.Spec.Redirect.Namespace != "" { errs = append(errs, field.Invalid(path.Child("redirect").Child("namespace"), in.Spec.Redirect.Namespace, `Consul Enterprise namespaces must be enabled to set redirect.namespace`)) @@ -449,7 +452,13 @@ func (in *ServiceResolver) validateNamespaces(namespacesEnabled bool) field.Erro errs = append(errs, field.Invalid(path.Child("failover").Key(k).Child("namespace"), v.Namespace, `Consul Enterprise namespaces must be enabled to set failover.namespace`)) } } - + } + if !consulMeta.PartitionsEnabled { + if in.Spec.Redirect != nil { + if in.Spec.Redirect.Partition != "" { + errs = append(errs, field.Invalid(path.Child("redirect").Child("partition"), in.Spec.Redirect.Partition, `Consul Enterprise partitions must be enabled to set redirect.partition`)) + } + } } return errs } diff --git a/control-plane/api/v1alpha1/serviceresolver_types_test.go b/control-plane/api/v1alpha1/serviceresolver_types_test.go index 979c1c983c..44b838cc50 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types_test.go +++ b/control-plane/api/v1alpha1/serviceresolver_types_test.go @@ -455,6 +455,7 @@ func TestServiceResolver_Validate(t *testing.T) { cases := map[string]struct { input *ServiceResolver namespacesEnabled bool + partitionsEnabled bool expectedErrMsgs []string }{ "namespaces enabled: valid": { @@ -476,6 +477,7 @@ func TestServiceResolver_Validate(t *testing.T) { }, }, namespacesEnabled: true, + partitionsEnabled: false, expectedErrMsgs: nil, }, "namespaces disabled: valid": { @@ -495,6 +497,50 @@ func TestServiceResolver_Validate(t *testing.T) { }, }, namespacesEnabled: false, + partitionsEnabled: false, + expectedErrMsgs: nil, + }, + "partitions enabled: valid": { + input: &ServiceResolver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceResolverSpec{ + Redirect: &ServiceResolverRedirect{ + Service: "bar", + Namespace: "namespace-a", + Partition: "other", + }, + Failover: map[string]ServiceResolverFailover{ + "failA": { + Service: "baz", + Namespace: "namespace-b", + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: true, + expectedErrMsgs: nil, + }, + "partitions disabled: valid": { + input: &ServiceResolver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceResolverSpec{ + Redirect: &ServiceResolverRedirect{ + Service: "bar", + }, + Failover: map[string]ServiceResolverFailover{ + "failA": { + Service: "baz", + }, + }, + }, + }, + namespacesEnabled: false, + partitionsEnabled: false, expectedErrMsgs: nil, }, "failover service, servicesubset, namespace, datacenters empty": { @@ -662,6 +708,24 @@ func TestServiceResolver_Validate(t *testing.T) { "serviceresolver.consul.hashicorp.com \"foo\" is invalid: spec.redirect.namespace: Invalid value: \"namespace-a\": Consul Enterprise namespaces must be enabled to set redirect.namespace", }, }, + "partitions disabled: redirect partition specified": { + input: &ServiceResolver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceResolverSpec{ + Redirect: &ServiceResolverRedirect{ + Namespace: "namespace-a", + Partition: "other", + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: false, + expectedErrMsgs: []string{ + "serviceresolver.consul.hashicorp.com \"foo\" is invalid: spec.redirect.partition: Invalid value: \"other\": Consul Enterprise partitions must be enabled to set redirect.partition", + }, + }, "namespaces disabled: single failover namespace specified": { input: &ServiceResolver{ ObjectMeta: metav1.ObjectMeta{ @@ -705,7 +769,7 @@ func TestServiceResolver_Validate(t *testing.T) { } for name, testCase := range cases { t.Run(name, func(t *testing.T) { - err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled}) + err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled, PartitionsEnabled: testCase.partitionsEnabled}) if len(testCase.expectedErrMsgs) != 0 { require.Error(t, err) for _, s := range testCase.expectedErrMsgs { diff --git a/control-plane/api/v1alpha1/servicerouter_types.go b/control-plane/api/v1alpha1/servicerouter_types.go index 4aa42e1624..dbe9c15895 100644 --- a/control-plane/api/v1alpha1/servicerouter_types.go +++ b/control-plane/api/v1alpha1/servicerouter_types.go @@ -128,6 +128,9 @@ type ServiceRouteDestination struct { // Namespace is the Consul namespace to resolve the service from instead of // the current namespace. If empty the current namespace is assumed. Namespace string `json:"namespace,omitempty"` + // Partition is the Consul partition to resolve the service from instead of + // the current partition. If empty the current partition is assumed. + Partition string `json:"partition,omitempty"` // PrefixRewrite defines how to rewrite the HTTP request path before proxying // it to its final destination. // This requires that either match.http.pathPrefix or match.http.pathExact @@ -254,7 +257,7 @@ func (in *ServiceRouter) Validate(consulMeta common.ConsulMeta) error { errs = append(errs, r.validate(path.Child("routes").Index(i))...) } - errs = append(errs, in.validateNamespaces(consulMeta.NamespacesEnabled)...) + errs = append(errs, in.validateEnterprise(consulMeta)...) if len(errs) > 0 { return apierrors.NewInvalid( @@ -328,6 +331,7 @@ func (in *ServiceRouteDestination) toConsul() *capi.ServiceRouteDestination { Service: in.Service, ServiceSubset: in.ServiceSubset, Namespace: in.Namespace, + Partition: in.Partition, PrefixRewrite: in.PrefixRewrite, RequestTimeout: in.RequestTimeout.Duration, NumRetries: in.NumRetries, @@ -338,10 +342,10 @@ func (in *ServiceRouteDestination) toConsul() *capi.ServiceRouteDestination { } } -func (in *ServiceRouter) validateNamespaces(namespacesEnabled bool) field.ErrorList { +func (in *ServiceRouter) validateEnterprise(consulMeta common.ConsulMeta) field.ErrorList { var errs field.ErrorList path := field.NewPath("spec") - if !namespacesEnabled { + if !consulMeta.NamespacesEnabled { for i, r := range in.Spec.Routes { if r.Destination != nil { if r.Destination.Namespace != "" { @@ -350,6 +354,15 @@ func (in *ServiceRouter) validateNamespaces(namespacesEnabled bool) field.ErrorL } } } + if !consulMeta.PartitionsEnabled { + for i, r := range in.Spec.Routes { + if r.Destination != nil { + if r.Destination.Partition != "" { + errs = append(errs, field.Invalid(path.Child("routes").Index(i).Child("destination").Child("partition"), r.Destination.Partition, `Consul Enterprise partitions must be enabled to set destination.partition`)) + } + } + } + } return errs } diff --git a/control-plane/api/v1alpha1/servicerouter_types_test.go b/control-plane/api/v1alpha1/servicerouter_types_test.go index 5d984ddf8f..eb0568db81 100644 --- a/control-plane/api/v1alpha1/servicerouter_types_test.go +++ b/control-plane/api/v1alpha1/servicerouter_types_test.go @@ -521,6 +521,7 @@ func TestServiceRouter_Validate(t *testing.T) { cases := map[string]struct { input *ServiceRouter namespacesEnabled bool + partitionsEnabled bool expectedErrMsgs []string }{ "namespaces enabled: valid": { @@ -570,6 +571,56 @@ func TestServiceRouter_Validate(t *testing.T) { namespacesEnabled: false, expectedErrMsgs: nil, }, + "partitions enabled: valid": { + input: &ServiceRouter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceRouterSpec{ + Routes: []ServiceRoute{ + { + Match: &ServiceRouteMatch{ + HTTP: &ServiceRouteHTTPMatch{ + PathPrefix: "/admin", + }, + }, + Destination: &ServiceRouteDestination{ + Service: "destA", + Namespace: "namespace-a", + Partition: "other", + }, + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: true, + expectedErrMsgs: nil, + }, + "partitions disabled: valid": { + input: &ServiceRouter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceRouterSpec{ + Routes: []ServiceRoute{ + { + Match: &ServiceRouteMatch{ + HTTP: &ServiceRouteHTTPMatch{ + PathPrefix: "/admin", + }, + }, + Destination: &ServiceRouteDestination{ + Service: "destA", + }, + }, + }, + }, + }, + namespacesEnabled: false, + partitionsEnabled: false, + expectedErrMsgs: nil, + }, "http match queryParam": { input: &ServiceRouter{ ObjectMeta: metav1.ObjectMeta{ @@ -712,10 +763,61 @@ func TestServiceRouter_Validate(t *testing.T) { "spec.routes[1].destination.namespace: Invalid value: \"namespace-b\": Consul Enterprise namespaces must be enabled to set destination.namespace", }, }, + "partitions disabled: single destination partition specified": { + input: &ServiceRouter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceRouterSpec{ + Routes: []ServiceRoute{ + { + Destination: &ServiceRouteDestination{ + Namespace: "namespace-a", + Partition: "partition-a", + }, + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: false, + expectedErrMsgs: []string{ + "servicerouter.consul.hashicorp.com \"foo\" is invalid: spec.routes[0].destination.partition: Invalid value: \"partition-a\": Consul Enterprise partitions must be enabled to set destination.partition", + }, + }, + "partitions disabled: multiple destination partitions specified": { + input: &ServiceRouter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceRouterSpec{ + Routes: []ServiceRoute{ + { + Destination: &ServiceRouteDestination{ + Namespace: "namespace-a", + Partition: "partition-a", + }, + }, + { + Destination: &ServiceRouteDestination{ + Namespace: "namespace-b", + Partition: "partition-b", + }, + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: false, + expectedErrMsgs: []string{ + "spec.routes[0].destination.partition: Invalid value: \"partition-a\": Consul Enterprise partitions must be enabled to set destination.partition", + "spec.routes[1].destination.partition: Invalid value: \"partition-b\": Consul Enterprise partitions must be enabled to set destination.partition", + }, + }, } for name, testCase := range cases { t.Run(name, func(t *testing.T) { - err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled}) + err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled, PartitionsEnabled: testCase.partitionsEnabled}) if len(testCase.expectedErrMsgs) != 0 { require.Error(t, err) for _, s := range testCase.expectedErrMsgs { diff --git a/control-plane/api/v1alpha1/servicesplitter_types.go b/control-plane/api/v1alpha1/servicesplitter_types.go index ea41ed6b1a..900cc1c545 100644 --- a/control-plane/api/v1alpha1/servicesplitter_types.go +++ b/control-plane/api/v1alpha1/servicesplitter_types.go @@ -61,9 +61,12 @@ type ServiceSplit struct { // ServiceSubset is a named subset of the given service to resolve instead of one defined // as that service's DefaultSubset. If empty the default subset is used. ServiceSubset string `json:"serviceSubset,omitempty"` - // The namespace to resolve the service from instead of the current namespace. - // If empty the current namespace is assumed. + // Namespace is the Consul namespace to resolve the service from instead of + // the current namespace. If empty the current namespace is assumed. Namespace string `json:"namespace,omitempty"` + // Partition is the Consul partition to resolve the service from instead of + // the current partition. If empty the current partition is assumed. + Partition string `json:"partition,omitempty"` // Allow HTTP header manipulation to be configured. RequestHeaders *HTTPHeaderModifiers `json:"requestHeaders,omitempty"` ResponseHeaders *HTTPHeaderModifiers `json:"responseHeaders,omitempty"` @@ -168,7 +171,7 @@ func (in *ServiceSplitter) MatchesConsul(candidate capi.ConfigEntry) bool { func (in *ServiceSplitter) Validate(consulMeta common.ConsulMeta) error { errs := in.Spec.Splits.validate(field.NewPath("spec").Child("splits")) - errs = append(errs, in.validateNamespaces(consulMeta.NamespacesEnabled)...) + errs = append(errs, in.validateEnterprise(consulMeta)...) if len(errs) > 0 { return apierrors.NewInvalid( @@ -198,21 +201,29 @@ func (in ServiceSplit) toConsul() capi.ServiceSplit { Service: in.Service, ServiceSubset: in.ServiceSubset, Namespace: in.Namespace, + Partition: in.Partition, RequestHeaders: in.RequestHeaders.toConsul(), ResponseHeaders: in.ResponseHeaders.toConsul(), } } -func (in *ServiceSplitter) validateNamespaces(namespacesEnabled bool) field.ErrorList { +func (in *ServiceSplitter) validateEnterprise(consulMeta common.ConsulMeta) field.ErrorList { var errs field.ErrorList path := field.NewPath("spec") - if !namespacesEnabled { + if !consulMeta.NamespacesEnabled { for i, s := range in.Spec.Splits { if s.Namespace != "" { errs = append(errs, field.Invalid(path.Child("splits").Index(i).Child("namespace"), s.Namespace, `Consul Enterprise namespaces must be enabled to set split.namespace`)) } } } + if !consulMeta.PartitionsEnabled { + for i, s := range in.Spec.Splits { + if s.Partition != "" { + errs = append(errs, field.Invalid(path.Child("splits").Index(i).Child("partition"), s.Partition, `Consul Enterprise partitions must be enabled to set split.partition`)) + } + } + } return errs } diff --git a/control-plane/api/v1alpha1/servicesplitter_types_test.go b/control-plane/api/v1alpha1/servicesplitter_types_test.go index e37d29e9db..48e9eeac54 100644 --- a/control-plane/api/v1alpha1/servicesplitter_types_test.go +++ b/control-plane/api/v1alpha1/servicesplitter_types_test.go @@ -387,6 +387,7 @@ func TestServiceSplitter_Validate(t *testing.T) { cases := map[string]struct { input *ServiceSplitter namespacesEnabled bool + partitionsEnabled bool expectedErrMsgs []string }{ "namespaces enabled: valid": { @@ -429,6 +430,50 @@ func TestServiceSplitter_Validate(t *testing.T) { namespacesEnabled: false, expectedErrMsgs: nil, }, + "partitions enabled: valid": { + input: &ServiceSplitter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceSplitterSpec{ + Splits: []ServiceSplit{ + { + Weight: 99.99, + Namespace: "namespace-a", + Partition: "partition-a", + }, + { + Weight: 0.01, + Namespace: "namespace-b", + Partition: "partition-b", + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: true, + expectedErrMsgs: nil, + }, + "partitions disabled: valid": { + input: &ServiceSplitter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceSplitterSpec{ + Splits: []ServiceSplit{ + { + Weight: 99.99, + }, + { + Weight: 0.01, + }, + }, + }, + }, + namespacesEnabled: false, + partitionsEnabled: false, + expectedErrMsgs: nil, + }, "splits with 0 weight: valid": { input: &ServiceSplitter{ ObjectMeta: metav1.ObjectMeta{ @@ -541,10 +586,58 @@ func TestServiceSplitter_Validate(t *testing.T) { "spec.splits[1].namespace: Invalid value: \"namespace-b\": Consul Enterprise namespaces must be enabled to set split.namespace", }, }, + "partitions disabled: single split partition specified": { + input: &ServiceSplitter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceSplitterSpec{ + Splits: []ServiceSplit{ + { + Namespace: "namespace-a", + Partition: "partition-a", + Weight: 100, + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: false, + expectedErrMsgs: []string{ + "servicesplitter.consul.hashicorp.com \"foo\" is invalid: spec.splits[0].partition: Invalid value: \"partition-a\": Consul Enterprise partitions must be enabled to set split.partition", + }, + }, + "partitions disabled: multiple split partitions specified": { + input: &ServiceSplitter{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceSplitterSpec{ + Splits: []ServiceSplit{ + { + Namespace: "namespace-a", + Partition: "partition-a", + Weight: 50, + }, + { + Namespace: "namespace-b", + Partition: "partition-b", + Weight: 50, + }, + }, + }, + }, + namespacesEnabled: true, + partitionsEnabled: false, + expectedErrMsgs: []string{ + "spec.splits[0].partition: Invalid value: \"partition-a\": Consul Enterprise partitions must be enabled to set split.partition", + "spec.splits[1].partition: Invalid value: \"partition-b\": Consul Enterprise partitions must be enabled to set split.partition", + }, + }, } for name, testCase := range cases { t.Run(name, func(t *testing.T) { - err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled}) + err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: testCase.namespacesEnabled, PartitionsEnabled: testCase.partitionsEnabled}) if len(testCase.expectedErrMsgs) != 0 { require.Error(t, err) for _, s := range testCase.expectedErrMsgs { diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml index 0be581e8b1..87285e8563 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml @@ -180,8 +180,14 @@ spec: from instead of the current one. type: string namespace: - description: Namespace is the namespace to resolve the service - from instead of the current one. + description: Namespace is the Consul namespace to resolve the + service from instead of the current namespace. If empty the + current namespace is assumed. + type: string + partition: + description: Partition is the Consul partition to resolve the + service from instead of the current partition. If empty the + current partition is assumed. type: string service: description: Service is a service to resolve instead of the current diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml index 17c7c75790..ec74f9b63d 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml @@ -70,6 +70,11 @@ spec: the request when a retryable result occurs format: int32 type: integer + partition: + description: Partition is the Consul partition to resolve + the service from instead of the current partition. If + empty the current partition is assumed. + type: string prefixRewrite: description: PrefixRewrite defines how to rewrite the HTTP request path before proxying it to its final destination. diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml index de3d2d43fd..fbbac1010e 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml @@ -56,9 +56,14 @@ spec: items: properties: namespace: - description: The namespace to resolve the service from instead - of the current namespace. If empty the current namespace is - assumed. + description: Namespace is the Consul namespace to resolve the + service from instead of the current namespace. If empty the + current namespace is assumed. + type: string + partition: + description: Partition is the Consul partition to resolve the + service from instead of the current partition. If empty the + current partition is assumed. type: string requestHeaders: description: Allow HTTP header manipulation to be configured. From 71a6bb62604ca860116627c34bf135c605dac10a Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 8 Dec 2021 10:42:31 -0800 Subject: [PATCH 45/70] Retry testing the merged metrics (#914) --- acceptance/tests/metrics/metrics_test.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/acceptance/tests/metrics/metrics_test.go b/acceptance/tests/metrics/metrics_test.go index 25e480c8d3..0ad3ce22c4 100644 --- a/acceptance/tests/metrics/metrics_test.go +++ b/acceptance/tests/metrics/metrics_test.go @@ -3,7 +3,9 @@ package metrics import ( "context" "fmt" + "github.com/hashicorp/consul/sdk/testutil/retry" "testing" + "time" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" @@ -121,12 +123,17 @@ func TestAppMetrics(t *testing.T) { require.NoError(t, err) require.Len(t, podList.Items, 1) podIP := podList.Items[0].Status.PodIP - metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+staticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:20200/metrics", podIP)) - require.NoError(t, err) - // This assertion represents the metrics from the envoy sidecar. - require.Contains(t, metricsOutput, `envoy_cluster_assignment_stale{local_cluster="server",consul_source_service="server"`) - // This assertion represents the metrics from the application. - require.Contains(t, metricsOutput, `service_started_total 1`) + + // Retry because sometimes the merged metrics server takes a couple hundred milliseconds + // to start. + retry.RunWith(&retry.Counter{Count: 3, Wait: 1 * time.Second}, t, func(r *retry.R) { + metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+staticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:20200/metrics", podIP)) + require.NoError(r, err) + // This assertion represents the metrics from the envoy sidecar. + require.Contains(r, metricsOutput, `envoy_cluster_assignment_stale{local_cluster="server",consul_source_service="server"`) + // This assertion represents the metrics from the application. + require.Contains(r, metricsOutput, `service_started_total 1`) + }) } func assertGatewayMetricsEnabled(t *testing.T, ctx environment.TestContext, ns, label, metricsAssertion string) { From 4143aff573163b110972a245e0dafdb20fb8e797 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 8 Dec 2021 13:57:41 -0500 Subject: [PATCH 46/70] 1.11.0 rc (#913) * support 1.11.0-rc --- .circleci/config.yml | 4 ++-- acceptance/tests/controller/controller_namespaces_test.go | 2 +- acceptance/tests/partitions/partitions_test.go | 4 ++-- .../controller/exportedservices_controller_ent_test.go | 3 --- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f84aed3235..925adf6b24 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,8 +9,8 @@ executors: - image: docker.mirror.hashicorp.services/circleci/golang:1.17 environment: TEST_RESULTS: /tmp/test-results # path to where test results are saved - CONSUL_VERSION: 1.11.0-beta3 # Consul's OSS version to use in tests - CONSUL_ENT_VERSION: 1.11.0+ent-beta3 # Consul's enterprise version to use in tests + CONSUL_VERSION: 1.11.0-rc # Consul's OSS version to use in tests + CONSUL_ENT_VERSION: 1.11.0+ent-rc # Consul's enterprise version to use in tests control-plane-path : &control-plane-path control-plane cli-path : &cli-path cli diff --git a/acceptance/tests/controller/controller_namespaces_test.go b/acceptance/tests/controller/controller_namespaces_test.go index 483fc96106..b272247db4 100644 --- a/acceptance/tests/controller/controller_namespaces_test.go +++ b/acceptance/tests/controller/controller_namespaces_test.go @@ -74,7 +74,7 @@ func TestControllerNamespaces(t *testing.T) { ctx := suite.Environment().DefaultContext(t) helmValues := map[string]string{ - "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", + "global.image": "hashicorp/consul-enterprise:1.11.0-ent-rc", "global.enableConsulNamespaces": "true", "global.adminPartitions.enabled": "true", diff --git a/acceptance/tests/partitions/partitions_test.go b/acceptance/tests/partitions/partitions_test.go index 001a2f431c..357e2f6d85 100644 --- a/acceptance/tests/partitions/partitions_test.go +++ b/acceptance/tests/partitions/partitions_test.go @@ -96,7 +96,7 @@ func TestPartitions(t *testing.T) { serverHelmValues := map[string]string{ "global.datacenter": "dc1", - "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", + "global.image": "hashicorp/consul-enterprise:1.11.0-ent-rc", "global.adminPartitions.enabled": "true", "global.enableConsulNamespaces": "true", @@ -197,7 +197,7 @@ func TestPartitions(t *testing.T) { // Create client cluster. clientHelmValues := map[string]string{ "global.datacenter": "dc1", - "global.image": "ashwinvenkatesh/consul@sha256:dce7a25b9e15271d8102a0f14fae71af0b9c789bafd8cbe4a7d0f8c34abe0296", + "global.image": "hashicorp/consul-enterprise:1.11.0-ent-rc", "global.enabled": "false", "global.tls.enabled": "true", diff --git a/control-plane/controller/exportedservices_controller_ent_test.go b/control-plane/controller/exportedservices_controller_ent_test.go index 72acdabf2c..ec8f771586 100644 --- a/control-plane/controller/exportedservices_controller_ent_test.go +++ b/control-plane/controller/exportedservices_controller_ent_test.go @@ -31,7 +31,6 @@ import ( func TestExportedServicesController_createsExportedServices(tt *testing.T) { tt.Parallel() - tt.Skip() cases := map[string]struct { Mirror bool @@ -151,7 +150,6 @@ func TestExportedServicesController_createsExportedServices(tt *testing.T) { func TestExportedServicesController_updatesExportedServices(tt *testing.T) { tt.Parallel() - tt.Skip() cases := map[string]struct { Mirror bool @@ -294,7 +292,6 @@ func TestExportedServicesController_updatesExportedServices(tt *testing.T) { func TestExportedServicesController_deletesExportedServices(tt *testing.T) { tt.Parallel() - tt.Skip() cases := map[string]struct { Mirror bool From f84fef0a71ca1d6d50c0553922ce9b512ef5b0f5 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 8 Dec 2021 14:51:53 -0500 Subject: [PATCH 47/70] Update version to 0.38.0 (#915) --- charts/consul/Chart.yaml | 4 ++-- charts/consul/values.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml index 740f90d1fd..0057b0780b 100644 --- a/charts/consul/Chart.yaml +++ b/charts/consul/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: consul -version: 0.37.0 +version: 0.38.0 appVersion: 1.10.4 kubeVersion: ">=1.17.0-0" description: Official HashiCorp Consul Chart @@ -15,7 +15,7 @@ annotations: - name: consul image: hashicorp/consul:1.10.4 - name: consul-k8s-control-plane - image: hashicorp/consul-k8s-control-plane:0.37.0 + image: hashicorp/consul-k8s-control-plane:0.38.0 - name: envoy image: envoyproxy/envoy-alpine:v1.18.4 artifacthub.io/license: MPL-2.0 diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index e95e7043ee..7cf9156fbf 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -105,7 +105,7 @@ global: # image that is used for functionality such as catalog sync. # This can be overridden per component. # @default: hashicorp/consul-k8s-control-plane: - imageK8S: "hashicorp/consul-k8s-control-plane:0.37.0" + imageK8S: "hashicorp/consul-k8s-control-plane:0.38.0" # The name of the datacenter that the agents should # register as. This can't be changed once the Consul cluster is up and running From dd1e1b0abdcb96372b5dd428fbcf426016f57c12 Mon Sep 17 00:00:00 2001 From: hc-github-team-consul-ecosystem <82990057+hc-github-team-consul-ecosystem@users.noreply.github.com> Date: Wed, 8 Dec 2021 19:55:43 +0000 Subject: [PATCH 48/70] Release v0.38.0 --- CHANGELOG.md | 2 +- cli/version/version.go | 4 ++-- control-plane/version/version.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46639b8283..cbf669cb96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## UNRELEASED +## 0.38.0 (December 08, 2021) BREAKING CHANGES: * Control Plane diff --git a/cli/version/version.go b/cli/version/version.go index 52fb3c2b9c..c5b55dddda 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -14,12 +14,12 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "0.37.0" + Version = "0.38.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. - VersionPrerelease = "dev" + VersionPrerelease = "" ) // GetHumanVersion composes the parts of the version in a way that's suitable diff --git a/control-plane/version/version.go b/control-plane/version/version.go index 52fb3c2b9c..c5b55dddda 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -14,12 +14,12 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "0.37.0" + Version = "0.38.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. - VersionPrerelease = "dev" + VersionPrerelease = "" ) // GetHumanVersion composes the parts of the version in a way that's suitable From aee48f05524f5ec1695a3913959ae33945c93023 Mon Sep 17 00:00:00 2001 From: hc-github-team-consul-ecosystem <82990057+hc-github-team-consul-ecosystem@users.noreply.github.com> Date: Wed, 8 Dec 2021 20:19:00 +0000 Subject: [PATCH 49/70] Putting source back into Dev Mode --- CHANGELOG.md | 2 ++ cli/version/version.go | 2 +- control-plane/version/version.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf669cb96..473ce5ed73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## UNRELEASED + ## 0.38.0 (December 08, 2021) BREAKING CHANGES: diff --git a/cli/version/version.go b/cli/version/version.go index c5b55dddda..44f7aca672 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -19,7 +19,7 @@ var ( // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. - VersionPrerelease = "" + VersionPrerelease = "dev" ) // GetHumanVersion composes the parts of the version in a way that's suitable diff --git a/control-plane/version/version.go b/control-plane/version/version.go index c5b55dddda..44f7aca672 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -19,7 +19,7 @@ var ( // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. - VersionPrerelease = "" + VersionPrerelease = "dev" ) // GetHumanVersion composes the parts of the version in a way that's suitable From 45d065b9e81becadfc0f2337e1c4e13f8e07a380 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 8 Dec 2021 22:04:06 -0600 Subject: [PATCH 50/70] add psp support when its configured --- acceptance/framework/vault/vault_cluster.go | 3 + acceptance/go.mod | 88 --------------------- 2 files changed, 3 insertions(+), 88 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index b0f444f85e..bab5fbb753 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -56,6 +56,9 @@ func NewVaultCluster(t *testing.T, ctx environment.TestContext, cfg *config.Test KubectlOptions: kopts, Logger: logger, } + if cfg.EnablePodSecurityPolicies { + vaultHelmOpts.SetValues["global.psp.enable"] = "true" + } helm.AddRepo(t, vaultHelmOpts, "hashicorp", "https://helm.releases.hashicorp.com") // Ignoring the error from `helm repo update` as it could fail due to stale cache or unreachable servers and we're // asserting a chart version on Install which would fail in an obvious way should this not succeed. diff --git a/acceptance/go.mod b/acceptance/go.mod index f91df929e2..a6b5a6b25b 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -14,91 +14,3 @@ require ( k8s.io/apimachinery v0.22.2 k8s.io/client-go v0.22.2 ) - -require ( - cloud.google.com/go v0.54.0 // indirect - github.com/armon/go-metrics v0.3.9 // indirect - github.com/armon/go-radix v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.30.27 // indirect - github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect - github.com/cenkalti/backoff/v3 v3.0.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/evanphx/json-patch v4.11.0+incompatible // indirect - github.com/fatih/color v1.12.0 // indirect - github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect - github.com/go-logr/logr v0.4.0 // indirect - github.com/go-sql-driver/mysql v1.5.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.1 // indirect - github.com/google/go-cmp v0.5.6 // indirect - github.com/google/gofuzz v1.1.0 // indirect - github.com/google/uuid v1.1.2 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect - github.com/gruntwork-io/gruntwork-cli v0.7.0 // 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-immutable-radix v1.3.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.0.1 // 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/parseutil v0.1.1 // indirect - 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.2.0 // indirect - github.com/hashicorp/golang-lru v0.5.3 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/serf v0.9.6 // indirect - github.com/hashicorp/vault/sdk v0.2.1 // indirect - github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect - github.com/imdario/mergo v0.3.12 // indirect - github.com/jmespath/go-jmespath v0.3.0 // indirect - github.com/json-iterator/go v1.1.11 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-isatty v0.0.13 // 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/mapstructure v1.4.2 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect - github.com/moby/spdystream v0.2.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/onsi/ginkgo v1.16.4 // indirect - github.com/onsi/gomega v1.15.0 // indirect - github.com/pierrec/lz4 v2.5.2+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/pquerna/otp v1.2.0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/ryanuber/go-glob v1.0.0 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/urfave/cli v1.22.2 // indirect - go.uber.org/atomic v1.7.0 // indirect - golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect - golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect - golang.org/x/text v0.3.6 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect - google.golang.org/grpc v1.38.0 // indirect - google.golang.org/protobuf v1.26.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - k8s.io/klog/v2 v2.9.0 // indirect - k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect - k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect -) From 363186b9e87199bb48e404775f263da0ff4128ee Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 8 Dec 2021 22:09:32 -0600 Subject: [PATCH 51/70] go mod tidy vs 1.17 --- acceptance/go.mod | 86 +++++++++++++++++ acceptance/go.sum | 233 +--------------------------------------------- 2 files changed, 90 insertions(+), 229 deletions(-) diff --git a/acceptance/go.mod b/acceptance/go.mod index a6b5a6b25b..db655d76b3 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -14,3 +14,89 @@ require ( k8s.io/apimachinery v0.22.2 k8s.io/client-go v0.22.2 ) + +require ( + cloud.google.com/go v0.54.0 // indirect + github.com/armon/go-metrics v0.3.9 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/aws/aws-sdk-go v1.30.27 // indirect + github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/evanphx/json-patch v4.11.0+incompatible // indirect + github.com/fatih/color v1.12.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect + github.com/go-logr/logr v0.4.0 // indirect + github.com/go-sql-driver/mysql v1.5.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/gruntwork-io/gruntwork-cli v0.7.0 // 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-immutable-radix v1.3.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.0.1 // 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/parseutil v0.1.1 // indirect + 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.2.0 // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/serf v0.9.6 // indirect + github.com/hashicorp/vault/sdk v0.2.1 // indirect + github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/jmespath/go-jmespath v0.3.0 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.13 // 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/mapstructure v1.4.2 // indirect + github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pquerna/otp v1.2.0 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/urfave/cli v1.22.2 // indirect + go.uber.org/atomic v1.7.0 // indirect + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect + golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect + golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect + google.golang.org/grpc v1.38.0 // indirect + google.golang.org/protobuf v1.26.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/klog/v2 v2.9.0 // indirect + k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect + k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect +) diff --git a/acceptance/go.sum b/acceptance/go.sum index 3459220dc4..c082349208 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -17,7 +17,6 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -27,11 +26,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= 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/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= @@ -46,7 +42,6 @@ github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMl github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.0/go.mod h1:QRTvSZQpxqm8mSErhnbI+tANIBAKP7B+UIE2z4ypUO0= github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4= github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= @@ -59,7 +54,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= 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/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= @@ -75,19 +69,14 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -102,29 +91,19 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27 h1:9gPjZWVDSoQrBO2AvqrWObS6KAZByfEJxQoCYo4ZfK0= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -134,11 +113,7 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -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/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -150,37 +125,26 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -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= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= -github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -207,10 +171,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= @@ -221,7 +183,6 @@ github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 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/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -232,7 +193,6 @@ github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -245,41 +205,33 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8= github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -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.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -288,7 +240,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -311,10 +262,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -330,14 +279,11 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= -github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= @@ -349,7 +295,6 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= @@ -357,42 +302,32 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arnQQLM4RH+CYs= github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638 h1:z68s6H6O3RjxDmNvou/2/3UBrsJkrMcNzI0IQN5scAM= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638/go.mod h1:7ZeaiADGbvJDuoWAT8UKj6KCcLsFUk+34OkUGMVtdXg= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.10.1-0.20211116182834-e6956893fb6f/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc h1:tUgL1cinAFDtidyKqgsJzlxLkEi9atLmN6j8kgCr17Q= github.com/hashicorp/consul/api v1.10.1-0.20211206193229-9b44861ce4bc/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= @@ -403,12 +338,10 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 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-discover v0.0.0-20200812215701-c4b85f6ed31f/go.mod h1:D4eo8/CN92vm9/9UDG+ldX1/fMFa4kpl8qzyTolus8o= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= 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-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -418,7 +351,6 @@ github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -429,7 +361,6 @@ github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= 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-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -448,7 +379,6 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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.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.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= @@ -456,16 +386,12 @@ github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG 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/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= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= @@ -476,32 +402,21 @@ github.com/hashicorp/vault/api v1.2.0/go.mod h1:dAjw0T5shMnrfH7Q/Mst+LrcTKvStZBV github.com/hashicorp/vault/sdk v0.1.14-0.20200519221530-14615acda45f/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10= github.com/hashicorp/vault/sdk v0.2.1 h1:S4O6Iv/dyKlE9AUTXGa7VOvZmsCvg36toPKgV4f2P4M= github.com/hashicorp/vault/sdk v0.2.1/go.mod h1:WfUiO1vYzfBkz1TmoE4ZGU7HD0T0Cl/rZwaxjBkgN4U= -github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= -github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -512,16 +427,13 @@ github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMW github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -532,15 +444,11 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= 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/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -555,13 +463,10 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= @@ -570,7 +475,6 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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= @@ -578,8 +482,6 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI 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/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -592,7 +494,6 @@ github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8 github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -604,40 +505,33 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P 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= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= -github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -645,9 +539,7 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -671,40 +563,25 @@ github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -714,35 +591,21 @@ 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/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= -github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -751,8 +614,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn 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/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -763,18 +624,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -782,54 +637,26 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= -github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -841,7 +668,6 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/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= @@ -885,7 +711,6 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -895,7 +720,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -914,19 +738,15 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -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-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-20201021035429-f5854403a974/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -942,14 +762,12 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -964,7 +782,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -979,12 +796,10 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-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= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -996,27 +811,19 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= @@ -1039,7 +846,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1052,7 +858,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1068,8 +873,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1088,10 +891,8 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1100,7 +901,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= @@ -1140,8 +940,6 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1151,7 +949,6 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -1162,9 +959,6 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1197,7 +991,6 @@ gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 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= @@ -1210,7 +1003,6 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1223,7 +1015,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1231,53 +1022,42 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= -k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= -k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk= k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= -k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= -k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM= k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc= k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= -k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug= k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -1289,15 +1069,10 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.10.2/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 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 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= From 65a91a9c44e9f4d0e199729342114dee9b9db98f Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Thu, 9 Dec 2021 13:36:52 -0500 Subject: [PATCH 52/70] anony token --- .circleci/config.yml | 2 +- charts/consul/values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 925adf6b24..1304e1f1cb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,7 +70,7 @@ commands: type: string consul-k8s-image: type: string - default: "docker.mirror.hashicorp.services/hashicorpdev/consul-k8s-control-plane:latest" + default: "ashwinvenkatesh/consul-k8s@sha256:5724b0bc0b28ac7b2dbea3d2b03c5360425be1d4dcb9cec31c99465e2fac70e4" go-path: type: string default: "/home/circleci/.go_workspace" diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 7cf9156fbf..57ec69261f 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -85,7 +85,7 @@ global: # image: "hashicorp/consul-enterprise:1.10.0-ent" # ``` # @default: hashicorp/consul: - image: "hashicorp/consul:1.10.4" + image: "ashwinvenkatesh/consul@sha256:a2638301c2386131f186c3ec30afc2073c8c74aeaadff63dae0089f5402bd0f0" # Array of objects containing image pull secret names that will be applied to each service account. # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. From 9c4bee4aa21aaf6f4004df6ebab6a802cb4faf5c Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Thu, 9 Dec 2021 13:43:38 -0500 Subject: [PATCH 53/70] Revert erronous commit This reverts commit 65a91a9c44e9f4d0e199729342114dee9b9db98f. --- .circleci/config.yml | 2 +- charts/consul/values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1304e1f1cb..925adf6b24 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,7 +70,7 @@ commands: type: string consul-k8s-image: type: string - default: "ashwinvenkatesh/consul-k8s@sha256:5724b0bc0b28ac7b2dbea3d2b03c5360425be1d4dcb9cec31c99465e2fac70e4" + default: "docker.mirror.hashicorp.services/hashicorpdev/consul-k8s-control-plane:latest" go-path: type: string default: "/home/circleci/.go_workspace" diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 57ec69261f..7cf9156fbf 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -85,7 +85,7 @@ global: # image: "hashicorp/consul-enterprise:1.10.0-ent" # ``` # @default: hashicorp/consul: - image: "ashwinvenkatesh/consul@sha256:a2638301c2386131f186c3ec30afc2073c8c74aeaadff63dae0089f5402bd0f0" + image: "hashicorp/consul:1.10.4" # Array of objects containing image pull secret names that will be applied to each service account. # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. From e35500648d12359be57eca028543db3515469b0c Mon Sep 17 00:00:00 2001 From: Saad Date: Mon, 15 Nov 2021 10:31:11 -0800 Subject: [PATCH 54/70] Made an initial try at the consul-k8s upgrade command. Running into issues with the connect-injector webhook not starting on an install? --- cli/cmd/install/install.go | 16 +- cli/cmd/install/presets.go | 53 ++-- cli/cmd/upgrade/upgrade.go | 449 ++++++++++++++++++++++++++++++++ cli/cmd/upgrade/upgrade_test.go | 35 +++ 4 files changed, 524 insertions(+), 29 deletions(-) create mode 100644 cli/cmd/upgrade/upgrade.go create mode 100644 cli/cmd/upgrade/upgrade_test.go diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index 44b1bca41f..ef52c63eee 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -82,7 +82,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range presets { + for name := range Presets { presetList = append(presetList, name) } @@ -313,7 +313,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = mergeMaps(convert(globalNameConsul), vals) + vals = MergeMaps(Convert(GlobalNameConsul), vals) // Dry Run should exit here, no need to actual locate/download the charts. if c.flagDryRun { @@ -454,15 +454,15 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := presets[c.flagPreset].(map[string]interface{}) - vals = mergeMaps(presetMap, vals) + presetMap := Presets[c.flagPreset].(map[string]interface{}) + vals = MergeMaps(presetMap, vals) } return vals, err } -// mergeMaps is a helper function used in Run. Merges two maps giving b precedent. +// MergeMaps is a helper function used in Run. Merges two maps giving b precedent. // @source: https://github.com/helm/helm/blob/main/pkg/cli/values/options.go -func mergeMaps(a, b map[string]interface{}) map[string]interface{} { +func MergeMaps(a, b map[string]interface{}) map[string]interface{} { out := make(map[string]interface{}, len(a)) for k, v := range a { out[k] = v @@ -471,7 +471,7 @@ func mergeMaps(a, b map[string]interface{}) map[string]interface{} { if v, ok := v.(map[string]interface{}); ok { if bv, ok := out[k]; ok { if bv, ok := bv.(map[string]interface{}); ok { - out[k] = mergeMaps(bv, v) + out[k] = MergeMaps(bv, v) continue } } @@ -492,7 +492,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { diff --git a/cli/cmd/install/presets.go b/cli/cmd/install/presets.go index f901d1e930..0305e19366 100644 --- a/cli/cmd/install/presets.go +++ b/cli/cmd/install/presets.go @@ -7,36 +7,47 @@ const ( PresetSecure = "secure" ) -// presets is a map of pre-configured helm values. -var presets = map[string]interface{}{ - PresetDemo: convert(demo), - PresetSecure: convert(secure), +// Presets is a map of pre-configured helm values. +var Presets = map[string]interface{}{ + PresetDemo: Convert(demo), + PresetSecure: Convert(secure), } var demo = ` global: name: consul - metrics: - enabled: true - enableAgentMetrics: true connectInject: enabled: true - metrics: - defaultEnabled: true - defaultEnableMerging: true - enableGatewayMetrics: true server: replicas: 1 -controller: - enabled: true -ui: - enabled: true - service: - enabled: true -prometheus: - enabled: true + bootstrapExpect: 1 ` +// TODO: I don't know why the following hangs for me. +//var demo = ` +//global: +// name: consul +// metrics: +// enabled: true +// enableAgentMetrics: true +//connectInject: +// enabled: true +// metrics: +// defaultEnabled: true +// defaultEnableMerging: true +// enableGatewayMetrics: true +//server: +// replicas: 1 +//controller: +// enabled: true +//ui: +// enabled: true +// service: +// enabled: true +//prometheus: +// enabled: true +//` + var secure = ` global: name: consul @@ -55,13 +66,13 @@ controller: enabled: true ` -var globalNameConsul = ` +var GlobalNameConsul = ` global: name: consul ` // convert is a helper function that converts a YAML string to a map. -func convert(s string) map[string]interface{} { +func Convert(s string) map[string]interface{} { var m map[string]interface{} _ = yaml.Unmarshal([]byte(s), &m) return m diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go new file mode 100644 index 0000000000..b324a24ebf --- /dev/null +++ b/cli/cmd/upgrade/upgrade.go @@ -0,0 +1,449 @@ +package upgrade + +import ( + "errors" + "fmt" + "os" + "strings" + "sync" + "time" + + consulChart "github.com/hashicorp/consul-k8s/charts" + "helm.sh/helm/v3/pkg/chart/loader" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/values" + "helm.sh/helm/v3/pkg/getter" + + "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + helmCLI "helm.sh/helm/v3/pkg/cli" + + "github.com/hashicorp/consul-k8s/cli/cmd/install" + + "github.com/hashicorp/consul-k8s/cli/cmd/common" + "github.com/hashicorp/consul-k8s/cli/cmd/common/flag" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/yaml" +) + +const ( + flagNamePreset = "preset" + defaultPreset = "" + + flagNameConfigFile = "config-file" + flagNameSetStringValues = "set-string" + flagNameSetValues = "set" + flagNameFileValues = "set-file" + + flagNameDryRun = "dry-run" + defaultDryRun = false + + flagNameAutoApprove = "auto-approve" + defaultAutoApprove = false + + flagNameNamespace = "namespace" + + flagNameTimeout = "timeout" + defaultTimeout = "10m" + + flagNameVerbose = "verbose" + defaultVerbose = false + + flagNameWait = "wait" + defaultWait = true +) + +type Command struct { + *common.BaseCommand + + kubernetes kubernetes.Interface + + set *flag.Sets + + flagPreset string + flagNamespace string + flagDryRun bool + flagAutoApprove bool + flagValueFiles []string + flagSetStringValues []string + flagSetValues []string + flagFileValues []string + flagTimeout string + timeoutDuration time.Duration + flagVerbose bool + flagWait bool + + flagKubeConfig string + flagKubeContext string + + once sync.Once + help string +} + +func (c *Command) init() { + // Store all the possible preset values in 'presetList'. Printed in the help message. + var presetList []string + for name := range install.Presets { + presetList = append(presetList, name) + } + + c.set = flag.NewSets() + f := c.set.NewSet("Command Options") + f.BoolVar(&flag.BoolVar{ + Name: flagNameAutoApprove, + Target: &c.flagAutoApprove, + Default: defaultAutoApprove, + Usage: "Skip confirmation prompt.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameDryRun, + Target: &c.flagDryRun, + Default: defaultDryRun, + Usage: "Run pre-install checks and display summary of installation.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameConfigFile, + Aliases: []string{"f"}, + Target: &c.flagValueFiles, + Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNameNamespace, + Target: &c.flagNamespace, + Default: common.DefaultReleaseNamespace, + Usage: "Namespace for the Consul installation.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNamePreset, + Target: &c.flagPreset, + Default: defaultPreset, + Usage: fmt.Sprintf("Use an installation preset, one of %s. Defaults to none", strings.Join(presetList, ", ")), + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameSetValues, + Target: &c.flagSetValues, + Usage: "Set a value to customize. Can be specified multiple times. Supports Consul Helm chart values.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameFileValues, + Target: &c.flagFileValues, + Usage: "Set a value to customize via a file. The contents of the file will be set as the value. Can be " + + "specified multiple times. Supports Consul Helm chart values.", + }) + f.StringSliceVar(&flag.StringSliceVar{ + Name: flagNameSetStringValues, + Target: &c.flagSetStringValues, + Usage: "Set a string value to customize. Can be specified multiple times. Supports Consul Helm chart values.", + }) + f.StringVar(&flag.StringVar{ + Name: flagNameTimeout, + Target: &c.flagTimeout, + Default: defaultTimeout, + Usage: "Timeout to wait for installation to be ready.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameVerbose, + Aliases: []string{"v"}, + Target: &c.flagVerbose, + Default: defaultVerbose, + Usage: "Output verbose logs from the install command with the status of resources being installed.", + }) + f.BoolVar(&flag.BoolVar{ + Name: flagNameWait, + Target: &c.flagWait, + Default: defaultWait, + Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", + }) + + f = c.set.NewSet("Global Options") + f.StringVar(&flag.StringVar{ + Name: "kubeconfig", + Aliases: []string{"c"}, + Target: &c.flagKubeConfig, + Default: "", + Usage: "Path to kubeconfig file.", + }) + f.StringVar(&flag.StringVar{ + Name: "context", + Target: &c.flagKubeContext, + Default: "", + Usage: "Kubernetes context to use.", + }) + + c.help = c.set.Help() + + // c.Init() calls the embedded BaseCommand's initialization function. + c.Init() +} + +func (c *Command) Run(args []string) int { + c.once.Do(c.init) + + // The logger is initialized in main with the name cli. Here, we reset the name to install so log lines would be prefixed with install. + c.Log.ResetNamed("upgrade") + + defer common.CloseWithError(c.BaseCommand) + + if err := c.validateFlags(args); err != nil { + c.UI.Output(err.Error()) + return 1 + } + + // helmCLI.New() will create a settings object which is used by the Helm Go SDK calls. + settings := helmCLI.New() + + // Any overrides by our kubeconfig and kubecontext flags is done here. The Kube client that + // is created will use this command's flags first, then the HELM_KUBECONTEXT environment variable, + // then call out to genericclioptions.ConfigFlag + if c.flagKubeConfig != "" { + settings.KubeConfig = c.flagKubeConfig + } + if c.flagKubeContext != "" { + settings.KubeContext = c.flagKubeContext + } + + // Setup logger to stream Helm library logs + var uiLogger = func(s string, args ...interface{}) { + logMsg := fmt.Sprintf(s, args...) + + if c.flagVerbose { + // Only output all logs when verbose is enabled + c.UI.Output(logMsg, terminal.WithLibraryStyle()) + } else { + // When verbose is not enabled, output all logs except not ready messages for resources + if !strings.Contains(logMsg, "not ready") { + c.UI.Output(logMsg, terminal.WithLibraryStyle()) + } + } + } + + // Set up the kubernetes client to use for non Helm SDK calls to the Kubernetes API + // The Helm SDK will use settings.RESTClientGetter for its calls as well, so this will + // use a consistent method to target the right cluster for both Helm SDK and non Helm SDK calls. + if c.kubernetes == nil { + restConfig, err := settings.RESTClientGetter().ToRESTConfig() + if err != nil { + c.UI.Output("Retrieving Kubernetes auth: %v", err, terminal.WithErrorStyle()) + return 1 + } + c.kubernetes, err = kubernetes.NewForConfig(restConfig) + if err != nil { + c.UI.Output("Initializing Kubernetes client: %v", err, terminal.WithErrorStyle()) + return 1 + } + } + + c.UI.Output("Pre-Upgrade Checks", terminal.WithHeaderStyle()) + + // Note the logic here, common's CheckForInstallations function returns an error if + // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) + return 1 + } else { + c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) + c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + } + + // Handle preset, value files, and set values logic. + vals, err := c.mergeValuesFlagsWithPrecedence(settings) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + valuesYaml, err := yaml.Marshal(vals) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Print out the upgrade summary. + // TODO: Fix this, it's just incorrect. + if !c.flagAutoApprove { + c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) + c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + + if len(vals) == 0 { + c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) + } else { + c.UI.Output("Overrides:"+"\n"+string(valuesYaml), terminal.WithInfoStyle()) + } + } + + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + + if !c.flagAutoApprove && !c.flagDryRun { + confirmation, err := c.UI.Input(&terminal.Input{ + Prompt: "Proceed with upgrade? (y/N)", + Style: terminal.InfoStyle, + Secret: false, + }) + + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + if common.Abort(confirmation) { + c.UI.Output("Upgrade aborted. To learn how to customize your upgrade, run:\nconsul-k8s upgrade --help", terminal.WithInfoStyle()) + return 1 + } + } + + if !c.flagDryRun { + c.UI.Output("Running Upgrade", terminal.WithHeaderStyle()) + } else { + c.UI.Output("Performing Dry Upgrade", terminal.WithHeaderStyle()) + } + + // Setup action configuration for Helm Go SDK function calls. + actionConfig := new(action.Configuration) + actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Setup the upgrade action. + // TODO: So many things to add here. + upgrade := action.NewUpgrade(actionConfig) + upgrade.Namespace = c.flagNamespace + upgrade.DryRun = c.flagDryRun + upgrade.Wait = c.flagWait + upgrade.Timeout = c.timeoutDuration + + // Read the embedded chart files into []*loader.BufferedFile. + chartFiles, err := common.ReadChartFiles(consulChart.ConsulHelmChart, common.TopLevelChartDirName) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Create a *chart.Chart object from the files to run the installation from. + chart, err := loader.LoadFiles(chartFiles) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + c.UI.Output("Downloaded charts", terminal.WithSuccessStyle()) + + // Run the install. + re, err := upgrade.Run(common.DefaultReleaseName, chart, vals) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + // Dry Run should exit here, printing the release's config. + if c.flagDryRun { + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) + + configYaml, err := yaml.Marshal(re.Config) + if err != nil { + c.UI.Output(err.Error(), terminal.WithErrorStyle()) + return 1 + } + + if len(re.Config) == 0 { + c.UI.Output("Config: "+string(configYaml), terminal.WithInfoStyle()) + } else { + c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) + } + + return 0 + } + + c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + + return 0 +} + +// TODO: Make sure the following function is consistent. +// TODO: Move these functions to common? +// validateFlags is a helper function that performs sanity checks on the user's provided flags. +func (c *Command) validateFlags(args []string) error { + if err := c.set.Parse(args); err != nil { + return err + } + if len(c.set.Args()) > 0 { + return errors.New("should have no non-flag arguments") + } + if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { + return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) + } + if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) + } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } + duration, err := time.ParseDuration(c.flagTimeout) + if err != nil { + return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) + } + c.timeoutDuration = duration + if len(c.flagValueFiles) != 0 { + for _, filename := range c.flagValueFiles { + if _, err := os.Stat(filename); err != nil && os.IsNotExist(err) { + return fmt.Errorf("File '%s' does not exist.", filename) + } + } + } + + if c.flagDryRun { + c.UI.Output("Performing dry run installation.", terminal.WithInfoStyle()) + } + return nil +} + +// TODO: Make sure the following function is consistent. +// TODO: Move these functions to common? +// validLabel is a helper function that checks if a string follows RFC 1123 labels. +func validLabel(s string) bool { + for i, c := range s { + alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') + // If the character is not the last or first, it can be a dash. + if i != 0 && i != (len(s)-1) { + alphanum = alphanum || (c == '-') + } + if !alphanum { + return false + } + } + return true +} + +// TODO: Move these functions to common? +// mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the +// installation based on the following precedence order from lowest to highest: +// 1. -preset +// 2. -f values-file +// 3. -set +// 4. -set-string +// 5. -set-file +// For example, -set-file will override a value provided via -set. +// Within each of these groups the rightmost flag value has the highest precedence. +func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) (map[string]interface{}, error) { + p := getter.All(settings) + v := &values.Options{ + ValueFiles: c.flagValueFiles, + StringValues: c.flagSetStringValues, + Values: c.flagSetValues, + FileValues: c.flagFileValues, + } + vals, err := v.MergeValues(p) + if err != nil { + return nil, fmt.Errorf("error merging values: %s", err) + } + if c.flagPreset != defaultPreset { + // Note the ordering of the function call, presets have lower precedence than set vals. + presetMap := install.Presets[c.flagPreset].(map[string]interface{}) + vals = install.MergeMaps(presetMap, vals) + } + return vals, err +} diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go new file mode 100644 index 0000000000..52c06e127d --- /dev/null +++ b/cli/cmd/upgrade/upgrade_test.go @@ -0,0 +1,35 @@ +package upgrade + +import ( + "os" + "testing" + + "github.com/hashicorp/consul-k8s/cli/cmd/common" + "github.com/hashicorp/go-hclog" +) + +/* Just using this to play around with the Go debugger. */ +func TestDebugger(t *testing.T) { + c := getInitializedCommand(t) + c.Run([]string{"-dry-run"}) +} + +// getInitializedCommand sets up a command struct for tests. +func getInitializedCommand(t *testing.T) *Command { + t.Helper() + log := hclog.New(&hclog.LoggerOptions{ + Name: "cli", + Level: hclog.Info, + Output: os.Stdout, + }) + + baseCommand := &common.BaseCommand{ + Log: log, + } + + c := &Command{ + BaseCommand: baseCommand, + } + c.init() + return c +} From d575746af2387844162de31e2607210cf7cdc061 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 10:14:20 -0800 Subject: [PATCH 55/70] Upgrade commit --- cli/cmd/upgrade/upgrade.go | 11 +++++++++++ cli/commands.go | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index b324a24ebf..99407416c4 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -238,6 +238,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { @@ -447,3 +448,13 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } return vals, err } + +func (c *Command) Help() string { + c.once.Do(c.init) + s := "Usage: consul-k8s upgrade [flags]" + "\n" + "Upgrade Consul from an existing installation." + "\n" + return s + "\n" + c.help +} + +func (c *Command) Synopsis() string { + return "Upgrade Consul on Kubernetes." +} diff --git a/cli/commands.go b/cli/commands.go index 50da5806d4..17726ac5aa 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/consul-k8s/cli/cmd/install" "github.com/hashicorp/consul-k8s/cli/cmd/status" "github.com/hashicorp/consul-k8s/cli/cmd/uninstall" + "github.com/hashicorp/consul-k8s/cli/cmd/upgrade" cmdversion "github.com/hashicorp/consul-k8s/cli/cmd/version" "github.com/hashicorp/consul-k8s/cli/version" "github.com/hashicorp/go-hclog" @@ -36,6 +37,11 @@ func initializeCommands(ctx context.Context, log hclog.Logger) (*common.BaseComm BaseCommand: baseCommand, }, nil }, + "upgrade": func() (cli.Command, error) { + return &upgrade.Command{ + BaseCommand: baseCommand, + }, nil + }, "version": func() (cli.Command, error) { return &cmdversion.Command{ BaseCommand: baseCommand, From 8215641c01b865edbf88b6de727a5b7216e6926a Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 23:55:46 -0800 Subject: [PATCH 56/70] First pass at upgrade was successful. --- cli/cmd/upgrade/upgrade.go | 35 ++++++++++++--------------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 99407416c4..b115f60e83 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -61,7 +61,6 @@ type Command struct { set *flag.Sets flagPreset string - flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -107,12 +106,6 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) - f.StringVar(&flag.StringVar{ - Name: flagNameNamespace, - Target: &c.flagNamespace, - Default: common.DefaultReleaseNamespace, - Usage: "Namespace for the Consul installation.", - }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -237,6 +230,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) @@ -245,6 +239,8 @@ func (c *Command) Run(args []string) int { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + + foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -264,7 +260,7 @@ func (c *Command) Run(args []string) int { if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -273,10 +269,11 @@ func (c *Command) Run(args []string) int { } } - // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // TODO: Fix this! + //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + //// aren't double prefixed with "consul-consul-...". + //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -303,7 +300,7 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 @@ -312,7 +309,7 @@ func (c *Command) Run(args []string) int { // Setup the upgrade action. // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = c.flagNamespace + upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -341,8 +338,6 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) - configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -354,11 +349,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) return 0 } - c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) return 0 } @@ -379,10 +374,6 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } - if !validLabel(c.flagNamespace) { - return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ - "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) - } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 52c06e127d..ffb220efc7 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-dry-run"}) + c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) } // getInitializedCommand sets up a command struct for tests. From 8ce3d2ca020097718fcf842dbeb21f46ee17f478 Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Tue, 23 Nov 2021 14:20:03 -0800 Subject: [PATCH 57/70] notes from sync with Saad on what's left --- cli/cmd/upgrade/upgrade.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index b115f60e83..49a11800fc 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,6 +51,9 @@ const ( flagNameWait = "wait" defaultWait = true + // action/upgrade + // --install, --reset-values vs --reuse-values, + // atomic ) type Command struct { @@ -256,7 +259,7 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this, it's just incorrect. + // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -269,7 +272,7 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! + // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources //// aren't double prefixed with "consul-consul-...". @@ -307,7 +310,7 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. + // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun From ca1465360ca7d56c0adddd5d3203a0857007dcd9 Mon Sep 17 00:00:00 2001 From: Saad Date: Mon, 15 Nov 2021 10:31:11 -0800 Subject: [PATCH 58/70] Made an initial try at the consul-k8s upgrade command. Running into issues with the connect-injector webhook not starting on an install? --- cli/cmd/upgrade/upgrade.go | 42 ++++++++++++++++++--------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 49a11800fc..a86f1a49f3 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,9 +51,6 @@ const ( flagNameWait = "wait" defaultWait = true - // action/upgrade - // --install, --reset-values vs --reuse-values, - // atomic ) type Command struct { @@ -64,6 +61,7 @@ type Command struct { set *flag.Sets flagPreset string + flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -109,6 +107,12 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) + f.StringVar(&flag.StringVar{ + Name: flagNameNamespace, + Target: &c.flagNamespace, + Default: common.DefaultReleaseNamespace, + Usage: "Namespace for the Consul installation.", + }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -233,17 +237,13 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. - foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { - // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) - - foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -259,11 +259,10 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -272,11 +271,10 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. - //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - //// aren't double prefixed with "consul-consul-...". - //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -303,16 +301,16 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 } // Setup the upgrade action. - // TODO: So many things to add here. (Could add upgrade.<> features) + // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = foundNamespace + upgrade.Namespace = c.flagNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -341,6 +339,8 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) + configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -352,11 +352,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) + return 0 } - c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) return 0 } @@ -377,6 +377,10 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index ffb220efc7..52c06e127d 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) + c.Run([]string{"-dry-run"}) } // getInitializedCommand sets up a command struct for tests. From 3da54cd98ccb3100dc28f68ccf6fac1557574cc0 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 10:14:20 -0800 Subject: [PATCH 59/70] Upgrade commit --- cli/cmd/upgrade/upgrade.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index a86f1a49f3..93ebb1cac9 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -238,6 +238,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { + // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) return 1 } else { From 2920d3ec51cd1ca6606f7fe3a820c856e1900425 Mon Sep 17 00:00:00 2001 From: Saad Date: Wed, 17 Nov 2021 23:55:46 -0800 Subject: [PATCH 60/70] First pass at upgrade was successful. --- cli/cmd/upgrade/upgrade.go | 35 ++++++++++++--------------------- cli/cmd/upgrade/upgrade_test.go | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 93ebb1cac9..9ec724f604 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -61,7 +61,6 @@ type Command struct { set *flag.Sets flagPreset string - flagNamespace string flagDryRun bool flagAutoApprove bool flagValueFiles []string @@ -107,12 +106,6 @@ func (c *Command) init() { Target: &c.flagValueFiles, Usage: "Path to a file to customize the installation, such as Consul Helm chart values file. Can be specified multiple times.", }) - f.StringVar(&flag.StringVar{ - Name: flagNameNamespace, - Target: &c.flagNamespace, - Default: common.DefaultReleaseNamespace, - Usage: "Namespace for the Consul installation.", - }) f.StringVar(&flag.StringVar{ Name: flagNamePreset, Target: &c.flagPreset, @@ -237,6 +230,7 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. + foundNamespace := "" if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { // TODO: Don't just error, install. c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) @@ -245,6 +239,8 @@ func (c *Command) Run(args []string) int { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) c.UI.Output("Name: %s", name, terminal.WithInfoStyle()) c.UI.Output("Namespace: %s", ns, terminal.WithInfoStyle()) + + foundNamespace = ns } // Handle preset, value files, and set values logic. @@ -263,7 +259,7 @@ func (c *Command) Run(args []string) int { if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) - c.UI.Output("Namespace: %s", c.flagNamespace, terminal.WithInfoStyle()) + c.UI.Output("Namespace: %s", foundNamespace, terminal.WithInfoStyle()) if len(vals) == 0 { c.UI.Output("Overrides: "+string(valuesYaml), terminal.WithInfoStyle()) @@ -272,10 +268,11 @@ func (c *Command) Run(args []string) int { } } - // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // TODO: Fix this! + //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + //// aren't double prefixed with "consul-consul-...". + //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -302,7 +299,7 @@ func (c *Command) Run(args []string) int { // Setup action configuration for Helm Go SDK function calls. actionConfig := new(action.Configuration) - actionConfig, err = common.InitActionConfig(actionConfig, c.flagNamespace, settings, uiLogger) + actionConfig, err = common.InitActionConfig(actionConfig, foundNamespace, settings, uiLogger) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) return 1 @@ -311,7 +308,7 @@ func (c *Command) Run(args []string) int { // Setup the upgrade action. // TODO: So many things to add here. upgrade := action.NewUpgrade(actionConfig) - upgrade.Namespace = c.flagNamespace + upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun upgrade.Wait = c.flagWait upgrade.Timeout = c.timeoutDuration @@ -340,8 +337,6 @@ func (c *Command) Run(args []string) int { // Dry Run should exit here, printing the release's config. if c.flagDryRun { - c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithInfoStyle()) - configYaml, err := yaml.Marshal(re.Config) if err != nil { c.UI.Output(err.Error(), terminal.WithErrorStyle()) @@ -353,11 +348,11 @@ func (c *Command) Run(args []string) int { } else { c.UI.Output("Config:"+"\n"+string(configYaml), terminal.WithInfoStyle()) } - + c.UI.Output("Dry run complete - upgrade can proceed.", terminal.WithSuccessStyle()) return 0 } - c.UI.Output("Upgraded Consul into namespace %q", c.flagNamespace, terminal.WithSuccessStyle()) + c.UI.Output("Upgraded Consul into namespace %q", foundNamespace, terminal.WithSuccessStyle()) return 0 } @@ -378,10 +373,6 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } - if !validLabel(c.flagNamespace) { - return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ - "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) - } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 52c06e127d..ffb220efc7 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( /* Just using this to play around with the Go debugger. */ func TestDebugger(t *testing.T) { c := getInitializedCommand(t) - c.Run([]string{"-dry-run"}) + c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) } // getInitializedCommand sets up a command struct for tests. From 355be3c3e1fc1ae0e9a5e2868e96f7c4a82ce7b3 Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Tue, 23 Nov 2021 14:20:03 -0800 Subject: [PATCH 61/70] notes from sync with Saad on what's left --- cli/cmd/upgrade/upgrade.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 9ec724f604..49a11800fc 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -51,6 +51,9 @@ const ( flagNameWait = "wait" defaultWait = true + // action/upgrade + // --install, --reset-values vs --reuse-values, + // atomic ) type Command struct { @@ -256,6 +259,7 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. + // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -268,7 +272,7 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! + // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources //// aren't double prefixed with "consul-consul-...". @@ -306,7 +310,7 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. + // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun From 56db25700dbd668850dafa33ee3c34222db45973 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 1 Dec 2021 14:49:35 -0500 Subject: [PATCH 62/70] Some basic cleanup --- cli/cmd/upgrade/upgrade.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 49a11800fc..e356eb34a2 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -174,8 +174,6 @@ func (c *Command) init() { func (c *Command) Run(args []string) int { c.once.Do(c.init) - - // The logger is initialized in main with the name cli. Here, we reset the name to install so log lines would be prefixed with install. c.Log.ResetNamed("upgrade") defer common.CloseWithError(c.BaseCommand) @@ -259,7 +257,6 @@ func (c *Command) Run(args []string) int { } // Print out the upgrade summary. - // TODO: Fix this to show the diff between existing and proposed install rather than overrides. if !c.flagAutoApprove { c.UI.Output("Consul Upgrade Summary", terminal.WithHeaderStyle()) c.UI.Output("Installation name: %s", common.DefaultReleaseName, terminal.WithInfoStyle()) @@ -272,11 +269,10 @@ func (c *Command) Run(args []string) int { } } - // TODO: Fix this! We are just going to comment this in, because we do want to set global.name to consul if not set already. - //// Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting - //// the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources - //// aren't double prefixed with "consul-consul-...". - //vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting + // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources + // aren't double prefixed with "consul-consul-...". + vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -310,7 +306,6 @@ func (c *Command) Run(args []string) int { } // Setup the upgrade action. - // TODO: So many things to add here. (Could add upgrade.<> features) upgrade := action.NewUpgrade(actionConfig) upgrade.Namespace = foundNamespace upgrade.DryRun = c.flagDryRun @@ -362,8 +357,7 @@ func (c *Command) Run(args []string) int { } // TODO: Make sure the following function is consistent. -// TODO: Move these functions to common? -// validateFlags is a helper function that performs sanity checks on the user's provided flags. +// validateFlags checks that the user's provided flags are valid. func (c *Command) validateFlags(args []string) error { if err := c.set.Parse(args); err != nil { return err @@ -372,7 +366,7 @@ func (c *Command) validateFlags(args []string) error { return errors.New("should have no non-flag arguments") } if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { - return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) + return fmt.Errorf("cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) @@ -385,7 +379,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 { for _, filename := range c.flagValueFiles { if _, err := os.Stat(filename); err != nil && os.IsNotExist(err) { - return fmt.Errorf("File '%s' does not exist.", filename) + return fmt.Errorf("file '%s' does not exist", filename) } } } @@ -397,8 +391,7 @@ func (c *Command) validateFlags(args []string) error { } // TODO: Make sure the following function is consistent. -// TODO: Move these functions to common? -// validLabel is a helper function that checks if a string follows RFC 1123 labels. +// validLabel checks if a string follows RFC 1123 labels. func validLabel(s string) bool { for i, c := range s { alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') @@ -413,7 +406,6 @@ func validLabel(s string) bool { return true } -// TODO: Move these functions to common? // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset From f5ccd785706b492cf01de71d61984042377a2ab7 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Wed, 1 Dec 2021 15:08:30 -0500 Subject: [PATCH 63/70] Remove TestDebugger --- cli/cmd/upgrade/upgrade_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index ffb220efc7..3f68dd0548 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -8,12 +8,6 @@ import ( "github.com/hashicorp/go-hclog" ) -/* Just using this to play around with the Go debugger. */ -func TestDebugger(t *testing.T) { - c := getInitializedCommand(t) - c.Run([]string{"-set=\"connectInject.enabled=false\"", "-auto-approve"}) -} - // getInitializedCommand sets up a command struct for tests. func getInitializedCommand(t *testing.T) *Command { t.Helper() From 61cf6788bd16818d8120e22a33a72d5a7826bc7a Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 2 Dec 2021 14:37:35 -0500 Subject: [PATCH 64/70] Remove validateLabels (unused) --- cli/cmd/upgrade/upgrade.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index e356eb34a2..3830f4f134 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -390,22 +390,6 @@ func (c *Command) validateFlags(args []string) error { return nil } -// TODO: Make sure the following function is consistent. -// validLabel checks if a string follows RFC 1123 labels. -func validLabel(s string) bool { - for i, c := range s { - alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') - // If the character is not the last or first, it can be a dash. - if i != 0 && i != (len(s)-1) { - alphanum = alphanum || (c == '-') - } - if !alphanum { - return false - } - } - return true -} - // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset From 7a409af7eab7ea69e4cad9de4610c505a3c22812 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 2 Dec 2021 14:56:45 -0500 Subject: [PATCH 65/70] Add the namespace and install flags --- cli/cmd/upgrade/upgrade.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 3830f4f134..8b494d4a10 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -41,7 +41,8 @@ const ( flagNameAutoApprove = "auto-approve" defaultAutoApprove = false - flagNameNamespace = "namespace" + flagNamespace = "namespace" + defaultNamespace = "consul" flagNameTimeout = "timeout" defaultTimeout = "10m" @@ -51,9 +52,9 @@ const ( flagNameWait = "wait" defaultWait = true - // action/upgrade - // --install, --reset-values vs --reuse-values, - // atomic + + flagInstall = "install" + defaultInstall = false ) type Command struct { @@ -66,6 +67,7 @@ type Command struct { flagPreset string flagDryRun bool flagAutoApprove bool + flagNamespace string flagValueFiles []string flagSetStringValues []string flagSetValues []string @@ -74,6 +76,7 @@ type Command struct { timeoutDuration time.Duration flagVerbose bool flagWait bool + flagInstall bool flagKubeConfig string flagKubeContext string @@ -97,6 +100,12 @@ func (c *Command) init() { Default: defaultAutoApprove, Usage: "Skip confirmation prompt.", }) + f.StringVar(&flag.StringVar{ + Name: flagNamespace, + Target: &c.flagNamespace, + Default: defaultNamespace, + Usage: "Namespace where Consul is installed. Defaults to 'consul'.", + }) f.BoolVar(&flag.BoolVar{ Name: flagNameDryRun, Target: &c.flagDryRun, @@ -150,6 +159,12 @@ func (c *Command) init() { Default: defaultWait, Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", }) + f.BoolVar(&flag.BoolVar{ + Name: flagInstall, + Target: &c.flagInstall, + Default: defaultInstall, + Usage: "Fall back to installing Consul if not already installed. Defaults to false.", + }) f = c.set.NewSet("Global Options") f.StringVar(&flag.StringVar{ From 1c660a6d50b01bbcc56e3be21243f5c03c55c50c Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 12:01:56 -0500 Subject: [PATCH 66/70] Add flag test and remove install option --- cli/cmd/upgrade/upgrade.go | 34 ++++++++++++++++---------- cli/cmd/upgrade/upgrade_test.go | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index 8b494d4a10..c19d5ceee3 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -52,9 +52,6 @@ const ( flagNameWait = "wait" defaultWait = true - - flagInstall = "install" - defaultInstall = false ) type Command struct { @@ -159,12 +156,6 @@ func (c *Command) init() { Default: defaultWait, Usage: "Determines whether to wait for resources in installation to be ready before exiting command.", }) - f.BoolVar(&flag.BoolVar{ - Name: flagInstall, - Target: &c.flagInstall, - Default: defaultInstall, - Usage: "Fall back to installing Consul if not already installed. Defaults to false.", - }) f = c.set.NewSet("Global Options") f.StringVar(&flag.StringVar{ @@ -246,10 +237,9 @@ func (c *Command) Run(args []string) int { // Note the logic here, common's CheckForInstallations function returns an error if // the release is not found. In `upgrade` we should indeed error if a user doesn't currently have a release. - foundNamespace := "" + var foundNamespace string if name, ns, err := common.CheckForInstallations(settings, uiLogger); err != nil { - // TODO: Don't just error, install. - c.UI.Output(fmt.Sprintf("could not find existing Consul installation - run `consul-k8s install`")) + c.UI.Output("could not find existing Consul installation - run `consul-k8s install`") return 1 } else { c.UI.Output("Existing installation found.", terminal.WithSuccessStyle()) @@ -371,7 +361,6 @@ func (c *Command) Run(args []string) int { return 0 } -// TODO: Make sure the following function is consistent. // validateFlags checks that the user's provided flags are valid. func (c *Command) validateFlags(args []string) error { if err := c.set.Parse(args); err != nil { @@ -386,6 +375,10 @@ func (c *Command) validateFlags(args []string) error { if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } + if !validLabel(c.flagNamespace) { + return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ + "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) + } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) @@ -405,6 +398,21 @@ func (c *Command) validateFlags(args []string) error { return nil } +// validLabel is a helper function that checks if a string follows RFC 1123 labels. +func validLabel(s string) bool { + for i, c := range s { + alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') + // If the character is not the last or first, it can be a dash. + if i != 0 && i != (len(s)-1) { + alphanum = alphanum || (c == '-') + } + if !alphanum { + return false + } + } + return true +} + // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset diff --git a/cli/cmd/upgrade/upgrade_test.go b/cli/cmd/upgrade/upgrade_test.go index 3f68dd0548..cd47928f9f 100644 --- a/cli/cmd/upgrade/upgrade_test.go +++ b/cli/cmd/upgrade/upgrade_test.go @@ -8,6 +8,49 @@ import ( "github.com/hashicorp/go-hclog" ) +// TestValidateFlags tests the validate flags function. +func TestValidateFlags(t *testing.T) { + // The following cases should all error, if they fail to this test fails. + testCases := []struct { + description string + input []string + }{ + { + "Should disallow non-flag arguments.", + []string{"foo", "-auto-approve"}, + }, + { + "Should disallow specifying both values file AND presets.", + []string{"-f='f.txt'", "-preset=demo"}, + }, + { + "Should error on invalid presets.", + []string{"-preset=foo"}, + }, + { + "Should error on invalid timeout.", + []string{"-timeout=invalid-timeout"}, + }, + { + "Should error on an invalid namespace.", + []string{"-namespace=\" nsWithSpace\""}, + }, + { + "Should have errored on a non-existant file.", + []string{"-f=\"does_not_exist.txt\""}, + }, + } + + for _, testCase := range testCases { + c := getInitializedCommand(t) + t.Run(testCase.description, func(t *testing.T) { + if err := c.validateFlags(testCase.input); err == nil { + t.Errorf("Test case should have failed.") + } + }) + } +} + // getInitializedCommand sets up a command struct for tests. func getInitializedCommand(t *testing.T) *Command { t.Helper() From a0e2426081e643e880eca053ef0e2054bb960dda Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 12:28:11 -0500 Subject: [PATCH 67/70] Move presets into a config package --- cli/cmd/install/install.go | 9 +++++---- cli/cmd/upgrade/upgrade.go | 10 +++++----- cli/{cmd/install => config}/presets.go | 9 +++++---- 3 files changed, 15 insertions(+), 13 deletions(-) rename cli/{cmd/install => config}/presets.go (90%) diff --git a/cli/cmd/install/install.go b/cli/cmd/install/install.go index ef52c63eee..7fc038a5e0 100644 --- a/cli/cmd/install/install.go +++ b/cli/cmd/install/install.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/consul-k8s/cli/cmd/common" "github.com/hashicorp/consul-k8s/cli/cmd/common/flag" "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + "github.com/hashicorp/consul-k8s/cli/config" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" helmCLI "helm.sh/helm/v3/pkg/cli" @@ -82,7 +83,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range Presets { + for name := range config.Presets { presetList = append(presetList, name) } @@ -313,7 +314,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = MergeMaps(Convert(GlobalNameConsul), vals) + vals = MergeMaps(config.Convert(config.GlobalNameConsul), vals) // Dry Run should exit here, no need to actual locate/download the charts. if c.flagDryRun { @@ -454,7 +455,7 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := Presets[c.flagPreset].(map[string]interface{}) + presetMap := config.Presets[c.flagPreset].(map[string]interface{}) vals = MergeMaps(presetMap, vals) } return vals, err @@ -492,7 +493,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("Cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := config.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index c19d5ceee3..e85f8b87d9 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -16,6 +16,7 @@ import ( "helm.sh/helm/v3/pkg/getter" "github.com/hashicorp/consul-k8s/cli/cmd/common/terminal" + "github.com/hashicorp/consul-k8s/cli/config" helmCLI "helm.sh/helm/v3/pkg/cli" "github.com/hashicorp/consul-k8s/cli/cmd/install" @@ -73,7 +74,6 @@ type Command struct { timeoutDuration time.Duration flagVerbose bool flagWait bool - flagInstall bool flagKubeConfig string flagKubeContext string @@ -85,7 +85,7 @@ type Command struct { func (c *Command) init() { // Store all the possible preset values in 'presetList'. Printed in the help message. var presetList []string - for name := range install.Presets { + for name := range config.Presets { presetList = append(presetList, name) } @@ -277,7 +277,7 @@ func (c *Command) Run(args []string) int { // Without informing the user, default global.name to consul if it hasn't been set already. We don't allow setting // the release name, and since that is hardcoded to "consul", setting global.name to "consul" makes it so resources // aren't double prefixed with "consul-consul-...". - vals = install.MergeMaps(install.Convert(install.GlobalNameConsul), vals) + vals = install.MergeMaps(config.Convert(config.GlobalNameConsul), vals) if !c.flagAutoApprove && !c.flagDryRun { confirmation, err := c.UI.Input(&terminal.Input{ @@ -372,7 +372,7 @@ func (c *Command) validateFlags(args []string) error { if len(c.flagValueFiles) != 0 && c.flagPreset != defaultPreset { return fmt.Errorf("cannot set both -%s and -%s", flagNameConfigFile, flagNamePreset) } - if _, ok := install.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { + if _, ok := config.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } if !validLabel(c.flagNamespace) { @@ -436,7 +436,7 @@ func (c *Command) mergeValuesFlagsWithPrecedence(settings *helmCLI.EnvSettings) } if c.flagPreset != defaultPreset { // Note the ordering of the function call, presets have lower precedence than set vals. - presetMap := install.Presets[c.flagPreset].(map[string]interface{}) + presetMap := config.Presets[c.flagPreset].(map[string]interface{}) vals = install.MergeMaps(presetMap, vals) } return vals, err diff --git a/cli/cmd/install/presets.go b/cli/config/presets.go similarity index 90% rename from cli/cmd/install/presets.go rename to cli/config/presets.go index 0305e19366..557cb24363 100644 --- a/cli/cmd/install/presets.go +++ b/cli/config/presets.go @@ -1,4 +1,4 @@ -package install +package config import "sigs.k8s.io/yaml" @@ -13,7 +13,7 @@ var Presets = map[string]interface{}{ PresetSecure: Convert(secure), } -var demo = ` +const demo = ` global: name: consul connectInject: @@ -24,6 +24,7 @@ server: ` // TODO: I don't know why the following hangs for me. +// TODO: This was hanging for Saad. I will look into it. //var demo = ` //global: // name: consul @@ -48,7 +49,7 @@ server: // enabled: true //` -var secure = ` +const secure = ` global: name: consul gossipEncryption: @@ -66,7 +67,7 @@ controller: enabled: true ` -var GlobalNameConsul = ` +const GlobalNameConsul = ` global: name: consul ` From ca1c6c00d6619073cbeba76982c7c6e837716722 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 3 Dec 2021 14:00:59 -0500 Subject: [PATCH 68/70] Add Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 473ce5ed73..62cc681dbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,10 @@ FEATURES: * Helm * Rename `PartitionExports` CRD to `ExportedServices`. [[GH-902](https://github.com/hashicorp/consul-k8s/pull/902)] +FEATURES: +* CLI + * Add `upgrade` command to modify Consul installation on Kubernetes. [[GH-898](https://github.com/hashicorp/consul-k8s/pull/898)] + IMPROVEMENTS: * CLI * Pre-check in the `install` command to verify the correct license secret exists when using an enterprise Consul image. [[GH-875](https://github.com/hashicorp/consul-k8s/pull/875)] From c05744f10dc4def1cf18919c77cae6965958b33e Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 13 Dec 2021 12:47:51 -0500 Subject: [PATCH 69/70] Mark CHANGELOG update as BETA --- CHANGELOG.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bb47cc47b..02bd5de687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,11 +29,7 @@ FEATURES: FEATURES: * CLI - * Add `upgrade` command to modify Consul installation on Kubernetes. [[GH-898](https://github.com/hashicorp/consul-k8s/pull/898)] - -FEATURES: -* CLI - * Add `upgrade` command to modify Consul installation on Kubernetes. [[GH-898](https://github.com/hashicorp/consul-k8s/pull/898)] + * **BETA** Add `upgrade` command to modify Consul installation on Kubernetes. [[GH-898](https://github.com/hashicorp/consul-k8s/pull/898)] IMPROVEMENTS: * CLI From e09f2e2ac3366af6bacb338c76d6b656873953f0 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 13 Dec 2021 12:52:19 -0500 Subject: [PATCH 70/70] Remove namespace from upgrade --- cli/cmd/upgrade/upgrade.go | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/cli/cmd/upgrade/upgrade.go b/cli/cmd/upgrade/upgrade.go index e85f8b87d9..f659961291 100644 --- a/cli/cmd/upgrade/upgrade.go +++ b/cli/cmd/upgrade/upgrade.go @@ -97,12 +97,6 @@ func (c *Command) init() { Default: defaultAutoApprove, Usage: "Skip confirmation prompt.", }) - f.StringVar(&flag.StringVar{ - Name: flagNamespace, - Target: &c.flagNamespace, - Default: defaultNamespace, - Usage: "Namespace where Consul is installed. Defaults to 'consul'.", - }) f.BoolVar(&flag.BoolVar{ Name: flagNameDryRun, Target: &c.flagDryRun, @@ -375,10 +369,6 @@ func (c *Command) validateFlags(args []string) error { if _, ok := config.Presets[c.flagPreset]; c.flagPreset != defaultPreset && !ok { return fmt.Errorf("'%s' is not a valid preset", c.flagPreset) } - if !validLabel(c.flagNamespace) { - return fmt.Errorf("'%s' is an invalid namespace. Namespaces follow the RFC 1123 label convention and must "+ - "consist of a lower case alphanumeric character or '-' and must start/end with an alphanumeric", c.flagNamespace) - } duration, err := time.ParseDuration(c.flagTimeout) if err != nil { return fmt.Errorf("unable to parse -%s: %s", flagNameTimeout, err) @@ -398,21 +388,6 @@ func (c *Command) validateFlags(args []string) error { return nil } -// validLabel is a helper function that checks if a string follows RFC 1123 labels. -func validLabel(s string) bool { - for i, c := range s { - alphanum := ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') - // If the character is not the last or first, it can be a dash. - if i != 0 && i != (len(s)-1) { - alphanum = alphanum || (c == '-') - } - if !alphanum { - return false - } - } - return true -} - // mergeValuesFlagsWithPrecedence is responsible for merging all the values to determine the values file for the // installation based on the following precedence order from lowest to highest: // 1. -preset