diff --git a/acceptance/framework/vault/helpers.go b/acceptance/framework/vault/helpers.go index ec17e0b5e9..850f8efbed 100644 --- a/acceptance/framework/vault/helpers.go +++ b/acceptance/framework/vault/helpers.go @@ -6,63 +6,11 @@ import ( "fmt" "testing" - "github.com/hashicorp/consul-k8s/acceptance/framework/config" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" - "github.com/hashicorp/go-uuid" vapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/require" ) -const ( - gossipPolicy = ` -path "consul/data/secret/gossip" { - capabilities = ["read"] -}` - - tokenPolicyTemplate = ` -path "consul/data/secret/%s" { - capabilities = ["read"] -}` - - enterpriseLicensePolicy = ` -path "consul/data/secret/license" { - capabilities = ["read"] -}` - - // 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. - connectCAPolicyTemplate = ` -path "/sys/mounts" { - capabilities = [ "read" ] -} - -path "/sys/mounts/connect_root" { - capabilities = [ "create", "read", "update", "delete", "list" ] -} - -path "/sys/mounts/%s/connect_inter" { - capabilities = [ "create", "read", "update", "delete", "list" ] -} - -path "/connect_root/*" { - capabilities = [ "create", "read", "update", "delete", "list" ] -} - -path "/%s/connect_inter/*" { - capabilities = [ "create", "read", "update", "delete", "list" ] -} -` - caPolicy = ` -path "pki/cert/ca" { - capabilities = ["read"] -}` - - snapshotAgentPolicy = ` -path "consul/data/secret/snapshot-agent-config" { - capabilities = ["read"] -}` -) - // 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: @@ -80,177 +28,185 @@ func GenerateGossipSecret() (string, error) { return base64.StdEncoding.EncodeToString(key), nil } -// ConfigureGossipVaultSecret generates a gossip encryption key, -// stores it in Vault as a secret and configures a policy to access it. -func ConfigureGossipVaultSecret(t *testing.T, vaultClient *vapi.Client) string { - // Create the Vault Policy for the gossip key. - logger.Log(t, "Creating gossip policy") - err := vaultClient.Sys().PutPolicy("gossip", gossipPolicy) - require.NoError(t, err) - - // Generate the gossip secret. - gossipKey, err := GenerateGossipSecret() - require.NoError(t, err) - - // Create the gossip secret. - logger.Log(t, "Creating the gossip secret") +// ConfigurePKICerts configures roles in Vault so +// that controller webhook TLS certificates can be issued by Vault. +func ConfigurePKICerts(t *testing.T, + vaultClient *vapi.Client, baseUrl, allowedSubdomain, roleName, ns, datacenter, + maxTTL string) string { + allowedDomains := fmt.Sprintf("%s.consul,%s,%s.%s,%s.%s.svc", datacenter, + allowedSubdomain, allowedSubdomain, ns, allowedSubdomain, ns) params := map[string]interface{}{ - "data": map[string]interface{}{ - "gossip": gossipKey, - }, + "allowed_domains": allowedDomains, + "allow_bare_domains": "true", + "allow_localhost": "true", + "allow_subdomains": "true", + "generate_lease": "true", + "max_ttl": maxTTL, } - _, err = vaultClient.Logical().Write("consul/data/secret/gossip", params) + + _, err := vaultClient.Logical().Write( + fmt.Sprintf("%s/roles/%s", baseUrl, roleName), params) require.NoError(t, err) - return gossipKey -} + certificateIssuePath := fmt.Sprintf("%s/issue/%s", baseUrl, roleName) + policy := fmt.Sprintf(` + path %q { + capabilities = ["create", "update"] + }`, certificateIssuePath) -// ConfigureEnterpriseLicenseVaultSecret stores it in Vault as a secret and configures a policy to access it. -func ConfigureEnterpriseLicenseVaultSecret(t *testing.T, vaultClient *vapi.Client, cfg *config.TestConfig) { - // Create the enterprise license secret. - logger.Log(t, "Creating the Enterprise License secret") - params := map[string]interface{}{ - "data": map[string]interface{}{ - "license": cfg.EnterpriseLicense, - }, - } - _, err := vaultClient.Logical().Write("consul/data/secret/license", params) + // Create the server policy. + err = vaultClient.Sys().PutPolicy(roleName, policy) require.NoError(t, err) - err = vaultClient.Sys().PutPolicy("license", enterpriseLicensePolicy) - require.NoError(t, err) + return certificateIssuePath } -// ConfigureSnapshotAgentSecret stores it in Vault as a secret and configures a policy to access it. -func ConfigureSnapshotAgentSecret(t *testing.T, vaultClient *vapi.Client, cfg *config.TestConfig, config string) { - logger.Log(t, "Creating the Snapshot Agent Config secret in Vault") - params := map[string]interface{}{ - "data": map[string]interface{}{ - "config": config, - }, +// ConfigurePKI generates a CA in Vault at a given path with a given policyName. +func ConfigurePKI(t *testing.T, vaultClient *vapi.Client, baseUrl, policyName, commonName string, skipPKIMount bool) { + if !skipPKIMount { + // Mount the PKI Secrets engine at the baseUrl. + mountErr := vaultClient.Sys().Mount(baseUrl, &vapi.MountInput{ + Type: "pki", + Config: vapi.MountConfigInput{}, + }) + require.NoError(t, mountErr) + // Create root CA to issue Consul server certificates and the `consul-server` PKI role. + // See https://learn.hashicorp.com/tutorials/consul/vault-pki-consul-secure-tls. + // Generate the root CA. + params := map[string]interface{}{ + "common_name": commonName, + "ttl": "24h", + } + _, mountErr = vaultClient.Logical().Write(fmt.Sprintf("%s/root/generate/internal", baseUrl), params) + require.NoError(t, mountErr) } - _, err := vaultClient.Logical().Write("consul/data/secret/snapshot-agent-config", params) - require.NoError(t, err) - err = vaultClient.Sys().PutPolicy("snapshot-agent-config", snapshotAgentPolicy) + policy := fmt.Sprintf(`path "%s/cert/ca" { + capabilities = ["read"] + }`, baseUrl) + err := vaultClient.Sys().PutPolicy(policyName, policy) require.NoError(t, err) } +type KubernetesAuthRoleConfiguration struct { + ServiceAccountName string + KubernetesNamespace string + PolicyNames string + AuthMethodPath string + RoleName string +} + // ConfigureKubernetesAuthRole configures a role in Vault for the component for the Kubernetes auth method // that will be used by the test Helm chart installation. -func ConfigureKubernetesAuthRole(t *testing.T, vaultClient *vapi.Client, consulReleaseName, ns, authPath, component, policies string) { - componentServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, component) - +func (config *KubernetesAuthRoleConfiguration) ConfigureK8SAuthRole(t *testing.T, vaultClient *vapi.Client) { // Create the Auth Roles for the component. // 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.Logf(t, "Creating the %q", componentServiceAccountName) + logger.Logf(t, "Creating the Vault Auth Role for %q", config.ServiceAccountName) params := map[string]interface{}{ - "bound_service_account_names": componentServiceAccountName, - "bound_service_account_namespaces": ns, - "policies": policies, + "bound_service_account_names": config.ServiceAccountName, + "bound_service_account_namespaces": config.KubernetesNamespace, + "policies": config.PolicyNames, "ttl": "24h", } - _, err := vaultClient.Logical().Write(fmt.Sprintf("auth/%s/role/%s", authPath, component), params) + _, err := vaultClient.Logical().Write(fmt.Sprintf("auth/%s/role/%s", config.AuthMethodPath, config.RoleName), params) require.NoError(t, err) } -// ConfigureConsulCAKubernetesAuthRole configures a role in Vault that allows all service accounts -// within the installation namespace access to the Consul server CA. -func ConfigureConsulCAKubernetesAuthRole(t *testing.T, vaultClient *vapi.Client, ns, authPath string) { - // 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(fmt.Sprintf("auth/%s/role/consul-ca", authPath), params) - require.NoError(t, err) +type PKIAndAuthRoleConfiguration struct { + ServiceAccountName string + BaseURL string + PolicyName string + RoleName string + CommonName string + CAPath string + CertPath string + KubernetesNamespace string + DataCenter string + MaxTTL string + AuthMethodPath string + AllowedSubdomain string + SkipPKIMount bool } -// ConfigurePKICA generates a CA in Vault. -func ConfigurePKICA(t *testing.T, vaultClient *vapi.Client) { - // Create root CA to issue Consul server certificates and the `consul-server` PKI role. - // See https://learn.hashicorp.com/tutorials/consul/vault-pki-consul-secure-tls. - // Generate the root CA. - params := map[string]interface{}{ - "common_name": "Consul CA", - "ttl": "24h", +func (config *PKIAndAuthRoleConfiguration) ConfigurePKIAndAuthRole(t *testing.T, vaultClient *vapi.Client) { + config.CAPath = fmt.Sprintf("%s/cert/ca", config.BaseURL) + // Configure role with read access to /cert/ca + ConfigurePKI(t, vaultClient, config.BaseURL, config.PolicyName, + config.CommonName, config.SkipPKIMount) + // Configure role with create and update access to issue certs at + // /issue/ + config.CertPath = ConfigurePKICerts(t, vaultClient, config.BaseURL, + config.AllowedSubdomain, config.PolicyName, config.KubernetesNamespace, + config.DataCenter, config.MaxTTL) + // Configure AuthMethodRole that will map the service account name + // to the Vault role + authMethodRoleConfig := &KubernetesAuthRoleConfiguration{ + ServiceAccountName: config.ServiceAccountName, + KubernetesNamespace: config.KubernetesNamespace, + AuthMethodPath: config.AuthMethodPath, + RoleName: config.RoleName, + PolicyNames: config.PolicyName, } - _, err := vaultClient.Logical().Write("pki/root/generate/internal", params) - require.NoError(t, err) - - err = vaultClient.Sys().PutPolicy("consul-ca", caPolicy) - require.NoError(t, err) + authMethodRoleConfig.ConfigureK8SAuthRole(t, vaultClient) } -// ConfigurePKICertificates configures roles in Vault so that Consul server TLS certificates -// can be issued by Vault. -func ConfigurePKICertificates(t *testing.T, vaultClient *vapi.Client, consulReleaseName, ns, datacenter string, maxTTL string) string { - consulServerDNSName := consulReleaseName + "-consul-server" - allowedDomains := fmt.Sprintf("%s.consul,%s,%s.%s,%s.%s.svc", datacenter, consulServerDNSName, consulServerDNSName, ns, consulServerDNSName, ns) - params := map[string]interface{}{ - "allowed_domains": allowedDomains, - "allow_bare_domains": "true", - "allow_localhost": "true", - "allow_subdomains": "true", - "generate_lease": "true", - "max_ttl": maxTTL, - } - - pkiRoleName := fmt.Sprintf("server-cert-%s", datacenter) - - _, err := vaultClient.Logical().Write(fmt.Sprintf("pki/roles/%s", pkiRoleName), params) - require.NoError(t, err) - - certificateIssuePath := fmt.Sprintf("pki/issue/%s", pkiRoleName) - serverTLSPolicy := fmt.Sprintf(` -path %q { - capabilities = ["create", "update"] -}`, certificateIssuePath) - - // Create the server policy. - err = vaultClient.Sys().PutPolicy(pkiRoleName, serverTLSPolicy) - require.NoError(t, err) - - return certificateIssuePath +type KV2Secret struct { + Path string + Key string + PolicyName string + Value string } -// ConfigureACLTokenVaultSecret generates a token secret ID for a given name, -// stores it in Vault as a secret and configures a policy to access it. -func ConfigureACLTokenVaultSecret(t *testing.T, vaultClient *vapi.Client, tokenName string) string { - // Create the Vault Policy for the token. - logger.Logf(t, "Creating %s token policy", tokenName) - policyName := fmt.Sprintf("%s-token", tokenName) - tokenPolicy := fmt.Sprintf(tokenPolicyTemplate, tokenName) - err := vaultClient.Sys().PutPolicy(policyName, tokenPolicy) - require.NoError(t, err) - - // Generate the token secret. - token, err := uuid.GenerateUUID() +// SaveSecretAndAddReadPolicy will create a read policy for the PolicyName +// on the KV2Secret and then will save the secret in the KV2 store. +func (config *KV2Secret) SaveSecretAndAddReadPolicy(t *testing.T, vaultClient *vapi.Client) { + policy := fmt.Sprintf(` + path "%s" { + capabilities = ["read"] + }`, config.Path) + // Create the Vault Policy for the secret. + logger.Log(t, "Creating policy") + err := vaultClient.Sys().PutPolicy(config.PolicyName, policy) require.NoError(t, err) - // Create the replication token secret. - logger.Logf(t, "Creating the %s token secret", tokenName) + // Save secret. + logger.Logf(t, "Creating the %s secret", config.Path) params := map[string]interface{}{ "data": map[string]interface{}{ - "token": token, + config.Key: config.Value, }, } - _, err = vaultClient.Logical().Write(fmt.Sprintf("consul/data/secret/%s", tokenName), params) + _, err = vaultClient.Logical().Write(config.Path, params) require.NoError(t, err) - - return token } -// CreateConnectCAPolicy creates the Vault Policy for the connect-ca in a given datacenter. -func CreateConnectCAPolicy(t *testing.T, vaultClient *vapi.Client, datacenter string) { +// CreateConnectCARootAndIntermediatePKIPolicy creates the Vault Policy for the connect-ca in a given datacenter. +func CreateConnectCARootAndIntermediatePKIPolicy(t *testing.T, vaultClient *vapi.Client, policyName, rootPath, intermediatePath string) { + // 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. err := vaultClient.Sys().PutPolicy( - fmt.Sprintf("connect-ca-%s", datacenter), - fmt.Sprintf(connectCAPolicyTemplate, datacenter, datacenter)) + policyName, + fmt.Sprintf(` +path "/sys/mounts" { + capabilities = [ "read" ] +} +path "/sys/mounts/%s" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} +path "/sys/mounts/%s" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} +path "/%s/*" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} +path "/%s/*" { + capabilities = [ "create", "read", "update", "delete", "list" ] +} +`, + rootPath, intermediatePath, rootPath, intermediatePath)) require.NoError(t, err) } diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index af2e4cb5f0..aadbbf8fee 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -147,13 +147,6 @@ func (v *VaultCluster) bootstrap(t *testing.T, vaultNamespace string) { }) 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) - namespace := v.helmOptions.KubectlOptions.Namespace vaultServerServiceAccountName := fmt.Sprintf("%s-vault", v.releaseName) v.ConfigureAuthMethod(t, v.vaultClient, "kubernetes", "https://kubernetes.default.svc", vaultServerServiceAccountName, namespace) diff --git a/acceptance/go.mod b/acceptance/go.mod index 82affda09e..c6282e61a1 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/consul-k8s/control-plane v0.0.0-20211207212234-aea9efea5638 github.com/hashicorp/consul/api v1.12.0 github.com/hashicorp/consul/sdk v0.9.0 - github.com/hashicorp/go-uuid v1.0.2 + github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/vault/api v1.2.0 github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/acceptance/go.sum b/acceptance/go.sum index 1953df0322..a09cfa21fc 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -442,6 +442,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/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= diff --git a/acceptance/tests/connect/connect_helper.go b/acceptance/tests/connect/connect_helper.go index d69fef0cb5..473c2ab562 100644 --- a/acceptance/tests/connect/connect_helper.go +++ b/acceptance/tests/connect/connect_helper.go @@ -18,7 +18,7 @@ import ( ) const ( - staticClientName = "static-client" + StaticClientName = "static-client" staticServerName = "static-server" ) @@ -98,7 +98,7 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { require.NoError(r, err) for _, token := range tokens { require.NotContains(r, token.Description, staticServerName) - require.NotContains(r, token.Description, staticClientName) + require.NotContains(r, token.Description, StaticClientName) } }) }) @@ -130,9 +130,9 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T) { logger.Log(t, "checking that the connection is not successful because there's no intention") if c.Cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } } @@ -145,7 +145,7 @@ func (c *ConnectHelper) CreateIntention(t *testing.T) { Name: staticServerName, Sources: []*api.SourceIntention{ { - Name: staticClientName, + Name: StaticClientName, Action: api.IntentionActionAllow, }, }, @@ -159,9 +159,9 @@ func (c *ConnectHelper) TestConnectionSuccess(t *testing.T) { logger.Log(t, "checking that connection is successful") if c.Cfg.EnableTransparentProxy { // todo: add an assertion that the traffic is going through the proxy - k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } } @@ -185,13 +185,13 @@ func (c *ConnectHelper) TestConnectionFailureWhenUnhealthy(t *testing.T) { // other tests. logger.Log(t, "checking that connection is unsuccessful") if c.Cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), staticClientName, false, []string{ + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), StaticClientName, false, []string{ "curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server port 80: Connection refused", }, "", "http://static-server") } else { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), staticClientName, false, []string{ + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), StaticClientName, false, []string{ "curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", }, "", "http://localhost:1234") diff --git a/acceptance/tests/connect/connect_inject_namespaces_test.go b/acceptance/tests/connect/connect_inject_namespaces_test.go index a052c6c18f..22fcc19c7a 100644 --- a/acceptance/tests/connect/connect_inject_namespaces_test.go +++ b/acceptance/tests/connect/connect_inject_namespaces_test.go @@ -19,7 +19,7 @@ import ( ) const staticServerNamespace = "ns1" -const staticClientNamespace = "ns2" +const StaticClientNamespace = "ns2" // Test that Connect works with Consul Enterprise namespaces. // These tests currently only test non-secure and secure without auto-encrypt installations @@ -92,26 +92,26 @@ func TestConnectInjectNamespaces(t *testing.T) { staticClientOpts := &terratestk8s.KubectlOptions{ ContextName: ctx.KubectlOptions(t).ContextName, ConfigPath: ctx.KubectlOptions(t).ConfigPath, - Namespace: staticClientNamespace, + Namespace: StaticClientNamespace, } - logger.Logf(t, "creating namespaces %s and %s", staticServerNamespace, staticClientNamespace) + logger.Logf(t, "creating namespaces %s and %s", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticServerNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) - k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { // Note: this deletion will take longer in cases when the static-client deployment // hasn't yet fully terminated. - k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) }) consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) serverQueryOpts := &api.QueryOptions{Namespace: staticServerNamespace} - clientQueryOpts := &api.QueryOptions{Namespace: staticClientNamespace} + clientQueryOpts := &api.QueryOptions{Namespace: StaticClientNamespace} if !c.mirrorK8S { serverQueryOpts = &api.QueryOptions{Namespace: c.destinationNamespace} @@ -135,7 +135,7 @@ func TestConnectInjectNamespaces(t *testing.T) { tokens, _, err = consulClient.ACL().TokenList(clientQueryOpts) require.NoError(r, err) for _, token := range tokens { - require.NotContains(r, token.Description, staticClientName) + require.NotContains(r, token.Description, StaticClientName) } }) } @@ -170,16 +170,16 @@ func TestConnectInjectNamespaces(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - services, _, err = consulClient.Catalog().Service(staticClientName, "", clientQueryOpts) + services, _, err = consulClient.Catalog().Service(StaticClientName, "", clientQueryOpts) require.NoError(t, err) require.Len(t, services, 1) if c.secure { logger.Log(t, "checking that the connection is not successful because there's no intention") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionFailing(t, staticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionFailing(t, staticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) } else { - k8s.CheckStaticServerConnectionFailing(t, staticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, staticClientOpts, StaticClientName, "http://localhost:1234") } intention := &api.ServiceIntentionsConfigEntry{ @@ -188,8 +188,8 @@ func TestConnectInjectNamespaces(t *testing.T) { Namespace: staticServerNamespace, Sources: []*api.SourceIntention{ { - Name: staticClientName, - Namespace: staticClientNamespace, + Name: StaticClientName, + Namespace: StaticClientNamespace, Action: api.IntentionActionAllow, }, }, @@ -209,9 +209,9 @@ func TestConnectInjectNamespaces(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, staticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionSuccessful(t, staticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) } else { - k8s.CheckStaticServerConnectionSuccessful(t, staticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, staticClientOpts, StaticClientName, "http://localhost:1234") } // Test that kubernetes readiness status is synced to Consul. @@ -226,9 +226,9 @@ func TestConnectInjectNamespaces(t *testing.T) { // 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") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, staticClientOpts, staticClientName, 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, staticClientOpts, StaticClientName, 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, staticClientOpts, staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, staticClientOpts, StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") } }) } @@ -298,23 +298,23 @@ func TestConnectInjectNamespaces_CleanupController(t *testing.T) { consulCluster.Create(t) - logger.Logf(t, "creating namespace %s", staticClientNamespace) - k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticClientNamespace) + logger.Logf(t, "creating namespace %s", StaticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { - k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) }) logger.Log(t, "creating static-client deployment") staticClientOpts := &terratestk8s.KubectlOptions{ ContextName: ctx.KubectlOptions(t).ContextName, ConfigPath: ctx.KubectlOptions(t).ConfigPath, - Namespace: staticClientNamespace, + Namespace: StaticClientNamespace, } k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") logger.Log(t, "waiting for static-client to be registered with Consul") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) - expectedConsulNS := staticClientNamespace + expectedConsulNS := StaticClientNamespace if !c.mirrorK8S { expectedConsulNS = c.destinationNamespace } @@ -330,14 +330,14 @@ func TestConnectInjectNamespaces_CleanupController(t *testing.T) { } }) - pods, err := ctx.KubernetesClient(t).CoreV1().Pods(staticClientNamespace).List(context.Background(), metav1.ListOptions{LabelSelector: "app=static-client"}) + pods, err := ctx.KubernetesClient(t).CoreV1().Pods(StaticClientNamespace).List(context.Background(), metav1.ListOptions{LabelSelector: "app=static-client"}) require.NoError(t, err) require.Len(t, pods.Items, 1) podName := pods.Items[0].Name logger.Logf(t, "force killing the static-client pod %q", podName) var gracePeriod int64 = 0 - err = ctx.KubernetesClient(t).CoreV1().Pods(staticClientNamespace).Delete(context.Background(), podName, metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}) + err = ctx.KubernetesClient(t).CoreV1().Pods(StaticClientNamespace).Delete(context.Background(), podName, metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}) require.NoError(t, err) logger.Log(t, "ensuring pod is deregistered") diff --git a/acceptance/tests/connect/connect_inject_test.go b/acceptance/tests/connect/connect_inject_test.go index 663d1e9263..73ae61c352 100644 --- a/acceptance/tests/connect/connect_inject_test.go +++ b/acceptance/tests/connect/connect_inject_test.go @@ -244,9 +244,9 @@ func TestConnectInject_RestartConsulClients(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } logger.Log(t, "restarting Consul client daemonset") @@ -255,9 +255,9 @@ func TestConnectInject_RestartConsulClients(t *testing.T) { logger.Log(t, "checking that connection is still successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } } @@ -316,7 +316,7 @@ func TestConnectInject_MultiportServices(t *testing.T) { for _, token := range tokens { require.NotContains(r, token.Description, multiport) require.NotContains(r, token.Description, multiportAdmin) - require.NotContains(r, token.Description, staticClientName) + require.NotContains(r, token.Description, StaticClientName) require.NotContains(r, token.Description, staticServerName) } }) @@ -345,8 +345,8 @@ func TestConnectInject_MultiportServices(t *testing.T) { if c.secure { logger.Log(t, "checking that the connection is not successful because there's no intention") - k8s.CheckStaticServerConnectionFailing(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") - k8s.CheckStaticServerConnectionFailing(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:2234") + k8s.CheckStaticServerConnectionFailing(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:2234") logger.Log(t, fmt.Sprintf("creating intention for %s", multiport)) _, _, err := consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ @@ -354,7 +354,7 @@ func TestConnectInject_MultiportServices(t *testing.T) { Name: multiport, Sources: []*api.SourceIntention{ { - Name: staticClientName, + Name: StaticClientName, Action: api.IntentionActionAllow, }, }, @@ -366,7 +366,7 @@ func TestConnectInject_MultiportServices(t *testing.T) { Name: multiportAdmin, Sources: []*api.SourceIntention{ { - Name: staticClientName, + Name: StaticClientName, Action: api.IntentionActionAllow, }, }, @@ -375,10 +375,10 @@ func TestConnectInject_MultiportServices(t *testing.T) { } // Check connection from static-client to multiport. - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") // Check connection from static-client to multiport-admin. - k8s.CheckStaticServerConnectionSuccessfulWithMessage(t, ctx.KubectlOptions(t), staticClientName, "hello world from 9090 admin", "http://localhost:2234") + k8s.CheckStaticServerConnectionSuccessfulWithMessage(t, ctx.KubectlOptions(t), StaticClientName, "hello world from 9090 admin", "http://localhost:2234") // Now that we've checked inbound connections to a multi port pod, check outbound connection from multi port // pod to static-server. @@ -423,8 +423,8 @@ func TestConnectInject_MultiportServices(t *testing.T) { // We are expecting a "connection reset by peer" error because in a case of health checks, // 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. - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, ctx.KubectlOptions(t), staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, ctx.KubectlOptions(t), staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:2234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, ctx.KubectlOptions(t), StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, ctx.KubectlOptions(t), StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:2234") }) } } diff --git a/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go b/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go index d26b383da0..d1e5757f91 100644 --- a/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go +++ b/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go @@ -129,7 +129,7 @@ func TestIngressGatewaySingleNamespace(t *testing.T) { // via the bounce pod. It should fail to connect with the // static-server pod because of intentions. logger.Log(t, "testing intentions prevent ingress") - k8s.CheckStaticServerConnectionFailing(t, nsK8SOptions, staticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) + k8s.CheckStaticServerConnectionFailing(t, nsK8SOptions, StaticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) // Now we create the allow intention. logger.Log(t, "creating ingress-gateway => static-server intention") @@ -151,7 +151,7 @@ func TestIngressGatewaySingleNamespace(t *testing.T) { // Test that we can make a call to the ingress gateway // via the static-client pod. It should route to the static-server pod. logger.Log(t, "trying calls to ingress gateway") - k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, staticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) + k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, StaticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) }) } } @@ -255,7 +255,7 @@ func TestIngressGatewayNamespaceMirroring(t *testing.T) { // via the bounce pod. It should fail to connect with the // static-server pod because of intentions. logger.Log(t, "testing intentions prevent ingress") - k8s.CheckStaticServerConnectionFailing(t, nsK8SOptions, staticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) + k8s.CheckStaticServerConnectionFailing(t, nsK8SOptions, StaticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) // Now we create the allow intention. logger.Log(t, "creating ingress-gateway => static-server intention") @@ -277,7 +277,7 @@ func TestIngressGatewayNamespaceMirroring(t *testing.T) { // Test that we can make a call to the ingress gateway // via the static-client pod. It should route to the static-server pod. logger.Log(t, "trying calls to ingress gateway") - k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, staticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) + k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, StaticClientName, "-H", "Host: static-server.ingress.consul", ingressGatewayService) }) } } diff --git a/acceptance/tests/ingress-gateway/ingress_gateway_test.go b/acceptance/tests/ingress-gateway/ingress_gateway_test.go index 8bbf540b94..a913d2c024 100644 --- a/acceptance/tests/ingress-gateway/ingress_gateway_test.go +++ b/acceptance/tests/ingress-gateway/ingress_gateway_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" ) -const staticClientName = "static-client" +const StaticClientName = "static-client" // Test that ingress gateways work in a default installation and a secure installation. func TestIngressGateway(t *testing.T) { @@ -96,7 +96,7 @@ func TestIngressGateway(t *testing.T) { // static-server pod because of intentions. logger.Log(t, "testing intentions prevent ingress") k8s.CheckStaticServerConnectionFailing(t, k8sOptions, - staticClientName, "-H", "Host: static-server.ingress.consul", + StaticClientName, "-H", "Host: static-server.ingress.consul", fmt.Sprintf("http://%s-consul-%s:8080/", releaseName, igName)) // Now we create the allow intention. @@ -118,7 +118,7 @@ func TestIngressGateway(t *testing.T) { // via the static-client pod. It should route to the static-server pod. logger.Log(t, "trying calls to ingress gateway") k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, - staticClientName, "-H", "Host: static-server.ingress.consul", + StaticClientName, "-H", "Host: static-server.ingress.consul", fmt.Sprintf("http://%s-consul-%s:8080/", releaseName, igName)) }) } diff --git a/acceptance/tests/mesh-gateway/mesh_gateway_test.go b/acceptance/tests/mesh-gateway/mesh_gateway_test.go index deb8cc2e90..557f5befc1 100644 --- a/acceptance/tests/mesh-gateway/mesh_gateway_test.go +++ b/acceptance/tests/mesh-gateway/mesh_gateway_test.go @@ -15,7 +15,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const staticClientName = "static-client" +const StaticClientName = "static-client" // Test that Connect and wan federation over mesh gateways work in a default installation // i.e. without ACLs because TLS is required for WAN federation over mesh gateways. @@ -128,7 +128,7 @@ func TestMeshGatewayDefault(t *testing.T) { k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, primaryContext.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, primaryContext.KubectlOptions(t), StaticClientName, "http://localhost:1234") } // Test that Connect and wan federation over mesh gateways work in a secure installation, @@ -287,7 +287,7 @@ func TestMeshGatewaySecure(t *testing.T) { Name: "static-server", Sources: []*api.SourceIntention{ { - Name: staticClientName, + Name: StaticClientName, Action: api.IntentionActionAllow, }, }, @@ -295,7 +295,7 @@ func TestMeshGatewaySecure(t *testing.T) { require.NoError(t, err) logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, primaryContext.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, primaryContext.KubectlOptions(t), StaticClientName, "http://localhost:1234") }) } } diff --git a/acceptance/tests/metrics/metrics_test.go b/acceptance/tests/metrics/metrics_test.go index 0ad3ce22c4..16bc101125 100644 --- a/acceptance/tests/metrics/metrics_test.go +++ b/acceptance/tests/metrics/metrics_test.go @@ -3,10 +3,11 @@ package metrics import ( "context" "fmt" - "github.com/hashicorp/consul/sdk/testutil/retry" "testing" "time" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" @@ -16,7 +17,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const staticClientName = "static-client" +const StaticClientName = "static-client" // Test that prometheus metrics, when enabled, are accessible from the // endpoints that have been exposed on the server, client and gateways. @@ -67,12 +68,12 @@ func TestComponentMetrics(t *testing.T) { k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") // Server Metrics - metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+staticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:8500/v1/agent/metrics?format=prometheus", fmt.Sprintf("%s-consul-server.%s.svc", releaseName, ns))) + metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+StaticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:8500/v1/agent/metrics?format=prometheus", fmt.Sprintf("%s-consul-server.%s.svc", releaseName, ns))) require.NoError(t, err) require.Contains(t, metricsOutput, `consul_acl_ResolveToken{quantile="0.5"}`) // Client Metrics - metricsOutput, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+staticClientName, "--", "sh", "-c", "curl --silent --show-error http://$HOST_IP:8500/v1/agent/metrics?format=prometheus") + metricsOutput, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+StaticClientName, "--", "sh", "-c", "curl --silent --show-error http://$HOST_IP:8500/v1/agent/metrics?format=prometheus") require.NoError(t, err) require.Contains(t, metricsOutput, `consul_acl_ResolveToken{quantile="0.5"}`) @@ -127,7 +128,7 @@ func TestAppMetrics(t *testing.T) { // 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)) + 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"`) @@ -141,7 +142,7 @@ func assertGatewayMetricsEnabled(t *testing.T, ctx environment.TestContext, ns, require.NoError(t, err) for _, pod := range pods.Items { podIP := pod.Status.PodIP - metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+staticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:20200/metrics", 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) require.Contains(t, metricsOutput, metricsAssertion) } diff --git a/acceptance/tests/partitions/partitions_connect_test.go b/acceptance/tests/partitions/partitions_connect_test.go index a12a72b430..369da09c26 100644 --- a/acceptance/tests/partitions/partitions_connect_test.go +++ b/acceptance/tests/partitions/partitions_connect_test.go @@ -18,10 +18,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const staticClientName = "static-client" +const StaticClientName = "static-client" const staticServerName = "static-server" const staticServerNamespace = "ns1" -const staticClientNamespace = "ns2" +const StaticClientNamespace = "ns2" // Test that Connect works in a default and ACLsAndAutoEncryptEnabled installations for X-Partition and in-partition networking. func TestPartitions_Connect(t *testing.T) { @@ -216,7 +216,7 @@ func TestPartitions_Connect(t *testing.T) { serverClusterStaticClientOpts := &terratestk8s.KubectlOptions{ ContextName: serverClusterContext.KubectlOptions(t).ContextName, ConfigPath: serverClusterContext.KubectlOptions(t).ConfigPath, - Namespace: staticClientNamespace, + Namespace: StaticClientNamespace, } clientClusterStaticServerOpts := &terratestk8s.KubectlOptions{ ContextName: clientClusterContext.KubectlOptions(t).ContextName, @@ -226,30 +226,30 @@ func TestPartitions_Connect(t *testing.T) { clientClusterStaticClientOpts := &terratestk8s.KubectlOptions{ ContextName: clientClusterContext.KubectlOptions(t).ContextName, ConfigPath: clientClusterContext.KubectlOptions(t).ConfigPath, - Namespace: staticClientNamespace, + Namespace: StaticClientNamespace, } - logger.Logf(t, "creating namespaces %s and %s in servers cluster", staticServerNamespace, staticClientNamespace) + logger.Logf(t, "creating namespaces %s and %s in servers cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, serverClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - k8s.RunKubectl(t, serverClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) + k8s.RunKubectl(t, serverClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { - k8s.RunKubectl(t, serverClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, staticClientNamespace) + k8s.RunKubectl(t, serverClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) - logger.Logf(t, "creating namespaces %s and %s in clients cluster", staticServerNamespace, staticClientNamespace) + logger.Logf(t, "creating namespaces %s and %s in clients cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, clientClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - k8s.RunKubectl(t, clientClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) + k8s.RunKubectl(t, clientClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { - k8s.RunKubectl(t, clientClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, staticClientNamespace) + k8s.RunKubectl(t, clientClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) consulClient, _ := serverConsulCluster.SetupConsulClient(t, c.ACLsAndAutoEncryptEnabled) serverQueryServerOpts := &api.QueryOptions{Namespace: staticServerNamespace, Partition: defaultPartition} - clientQueryServerOpts := &api.QueryOptions{Namespace: staticClientNamespace, Partition: defaultPartition} + clientQueryServerOpts := &api.QueryOptions{Namespace: StaticClientNamespace, Partition: defaultPartition} serverQueryClientOpts := &api.QueryOptions{Namespace: staticServerNamespace, Partition: secondaryPartition} - clientQueryClientOpts := &api.QueryOptions{Namespace: staticClientNamespace, Partition: secondaryPartition} + clientQueryClientOpts := &api.QueryOptions{Namespace: StaticClientNamespace, Partition: secondaryPartition} if !c.mirrorK8S { serverQueryServerOpts = &api.QueryOptions{Namespace: c.destinationNamespace, Partition: defaultPartition} @@ -275,7 +275,7 @@ func TestPartitions_Connect(t *testing.T) { tokens, _, err = consulClient.ACL().TokenList(clientQueryServerOpts) require.NoError(r, err) for _, token := range tokens { - require.NotContains(r, token.Description, staticClientName) + require.NotContains(r, token.Description, StaticClientName) } tokens, _, err = consulClient.ACL().TokenList(serverQueryClientOpts) require.NoError(r, err) @@ -286,7 +286,7 @@ func TestPartitions_Connect(t *testing.T) { tokens, _, err = consulClient.ACL().TokenList(clientQueryClientOpts) require.NoError(r, err) for _, token := range tokens { - require.NotContains(r, token.Description, staticClientName) + require.NotContains(r, token.Description, StaticClientName) } }) } @@ -363,7 +363,7 @@ func TestPartitions_Connect(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - services, _, err = consulClient.Catalog().Service(staticClientName, "", clientQueryServerOpts) + services, _, err = consulClient.Catalog().Service(StaticClientName, "", clientQueryServerOpts) require.NoError(t, err) require.Len(t, services, 1) @@ -372,18 +372,18 @@ func TestPartitions_Connect(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - services, _, err = consulClient.Catalog().Service(staticClientName, "", clientQueryClientOpts) + services, _, err = consulClient.Catalog().Service(StaticClientName, "", clientQueryClientOpts) require.NoError(t, err) require.Len(t, services, 1) if c.ACLsAndAutoEncryptEnabled { logger.Log(t, "checking that the connection is not successful because there's no intention") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) } else { - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, staticClientName, "http://localhost:1234") - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, StaticClientName, "http://localhost:1234") } intention := &api.ServiceIntentionsConfigEntry{ @@ -392,8 +392,8 @@ func TestPartitions_Connect(t *testing.T) { Namespace: staticServerNamespace, Sources: []*api.SourceIntention{ { - Name: staticClientName, - Namespace: staticClientNamespace, + Name: StaticClientName, + Namespace: StaticClientNamespace, Action: api.IntentionActionAllow, }, }, @@ -421,11 +421,11 @@ func TestPartitions_Connect(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.%s", staticServerNamespace)) } else { - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, staticClientName, "http://localhost:1234") - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, StaticClientName, "http://localhost:1234") } // Test that kubernetes readiness status is synced to Consul. @@ -441,11 +441,11 @@ func TestPartitions_Connect(t *testing.T) { // 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") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, staticClientName, 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, staticClientName, 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, serverClusterStaticClientOpts, StaticClientName, 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, StaticClientName, 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, staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") } }) // This section of the tests runs the cross-partition networking tests. @@ -507,7 +507,7 @@ func TestPartitions_Connect(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - services, _, err = consulClient.Catalog().Service(staticClientName, "", clientQueryServerOpts) + services, _, err = consulClient.Catalog().Service(StaticClientName, "", clientQueryServerOpts) require.NoError(t, err) require.Len(t, services, 1) @@ -516,7 +516,7 @@ func TestPartitions_Connect(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - services, _, err = consulClient.Catalog().Service(staticClientName, "", clientQueryClientOpts) + services, _, err = consulClient.Catalog().Service(StaticClientName, "", clientQueryClientOpts) require.NoError(t, err) require.Len(t, services, 1) @@ -541,15 +541,15 @@ func TestPartitions_Connect(t *testing.T) { logger.Log(t, "checking that the connection is not successful because there's no intention") if cfg.EnableTransparentProxy { if !c.mirrorK8S { - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) } else { - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) } } else { - k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, staticClientName, "http://localhost:1234") - k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, serverClusterStaticClientOpts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, clientClusterStaticClientOpts, StaticClientName, "http://localhost:1234") } intention := &api.ServiceIntentionsConfigEntry{ @@ -558,8 +558,8 @@ func TestPartitions_Connect(t *testing.T) { Namespace: staticServerNamespace, Sources: []*api.SourceIntention{ { - Name: staticClientName, - Namespace: staticClientNamespace, + Name: StaticClientName, + Namespace: StaticClientNamespace, Action: api.IntentionActionAllow, }, }, @@ -590,15 +590,15 @@ func TestPartitions_Connect(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { if !c.mirrorK8S { - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", c.destinationNamespace, defaultPartition)) } else { - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, staticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, secondaryPartition)) + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, StaticClientName, fmt.Sprintf("http://static-server.virtual.%s.ns.%s.ap.dc1.dc.consul", staticServerNamespace, defaultPartition)) } } else { - k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, staticClientName, "http://localhost:1234") - k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, serverClusterStaticClientOpts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, clientClusterStaticClientOpts, StaticClientName, "http://localhost:1234") } // Test that kubernetes readiness status is synced to Consul. @@ -615,15 +615,15 @@ func TestPartitions_Connect(t *testing.T) { logger.Log(t, "checking that connection is unsuccessful") if cfg.EnableTransparentProxy { if !c.mirrorK8S { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, staticClientName, 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, staticClientName, 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)) + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, StaticClientName, 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, StaticClientName, 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, staticClientName, 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, staticClientName, 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)) + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, StaticClientName, 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, StaticClientName, 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, staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, staticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, serverClusterStaticClientOpts, StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, clientClusterStaticClientOpts, StaticClientName, false, []string{"curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server"}, "", "http://localhost:1234") } }) }) diff --git a/acceptance/tests/snapshot-agent/snapshot_agent_vault_test.go b/acceptance/tests/snapshot-agent/snapshot_agent_vault_test.go index cb1667e3ca..bde2d88ab0 100644 --- a/acceptance/tests/snapshot-agent/snapshot_agent_vault_test.go +++ b/acceptance/tests/snapshot-agent/snapshot_agent_vault_test.go @@ -14,6 +14,7 @@ import ( "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/hashicorp/go-uuid" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -40,28 +41,141 @@ func TestSnapshotAgent_Vault(t *testing.T) { // Now fetch the Vault client so we can create the policies and secrets. vaultClient := vaultCluster.VaultClient(t) - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) + + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + MaxTTL: "1h", + AuthMethodPath: "kubernetes", + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } if cfg.EnableEnterprise { - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) } - bootstrapToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") + // Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) - config := generateSnapshotAgentConfig(t, bootstrapToken) - vault.ConfigureSnapshotAgentSecret(t, vaultClient, cfg, config) + // Snapshot Agent config + snapshotAgentConfig := generateSnapshotAgentConfig(t, bootstrapToken) + require.NoError(t, err) + snapshotAgentConfigSecret := &vault.KV2Secret{ + Path: "consul/data/secret/snapshot-agent-config", + Key: "config", + Value: snapshotAgentConfig, + PolicyName: "snapshot-agent-config", + } + snapshotAgentConfigSecret.SaveSecretAndAddReadPolicy(t, vaultClient) - serverPolicies := "gossip,connect-ca-dc1,server-cert-dc1,bootstrap-token" + // ------------------------- + // Additional Auth Roles + // ------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) if cfg.EnableEnterprise { - serverPolicies += ",license" + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) } - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", serverPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "snapshot-agent", "snapshot-agent-config,license") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") - vault.ConfigurePKICA(t, vaultClient) - certPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", "1h") + // server + consulServerRole := "server" + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := "client" + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, "client") + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := "server-acl-init" + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, "server-acl-init") + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: manageSystemACLsRole, + PolicyNames: bootstrapTokenSecret.PolicyName, + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // snapshot agent config + snapAgentRole := "snapshot-agent" + snapAgentServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, "snapshot-agent") + saAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: snapAgentServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: snapAgentRole, + PolicyNames: fmt.Sprintf("%s,%s", licenseSecret.PolicyName, snapshotAgentConfigSecret.PolicyName), + } + saAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) vaultCASecret := vault.CASecretName(vaultReleaseName) @@ -75,36 +189,36 @@ func TestSnapshotAgent_Vault(t *testing.T) { "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "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": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, "global.tls.enabled": "true", - "server.serverCert.secretName": certPath, - "global.tls.caCert.secretName": "pki/cert/ca", + "server.serverCert.secretName": serverPKIConfig.CertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, "global.tls.enableAutoEncrypt": "true", "client.snapshotAgent.enabled": "true", - "client.snapshotAgent.configSecret.secretName": "consul/data/secret/snapshot-agent-config", - "client.snapshotAgent.configSecret.secretKey": "config", - "global.secretsBackend.vault.consulSnapshotAgentRole": "snapshot-agent", + "client.snapshotAgent.configSecret.secretName": snapshotAgentConfigSecret.Path, + "client.snapshotAgent.configSecret.secretKey": snapshotAgentConfigSecret.Key, + "global.secretsBackend.vault.consulSnapshotAgentRole": snapAgentRole, } if cfg.EnableEnterprise { - consulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - consulHelmValues["global.enterpriseLicense.secretKey"] = "license" + consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } logger.Log(t, "Installing Consul") @@ -120,7 +234,7 @@ func TestSnapshotAgent_Vault(t *testing.T) { require.NoError(t, err) require.True(t, len(podList.Items) > 0) - // Wait for 10seconds to allow snapsot to write. + // Wait for 10 seconds to allow snapshot to write. time.Sleep(10 * time.Second) // Loop through snapshot agents. Only one will be the leader and have the snapshot files. diff --git a/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go b/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go index 802187bc21..232c15d13d 100644 --- a/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go +++ b/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go @@ -121,7 +121,7 @@ func TestTerminatingGatewaySingleNamespace(t *testing.T) { // Test that we can make a call to the terminating gateway. logger.Log(t, "trying calls to terminating gateway") - k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, nsK8SOptions, StaticClientName, "http://localhost:1234") }) } } @@ -180,11 +180,11 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", testNamespace) }) - staticClientNamespace := "ns2" - logger.Logf(t, "creating Kubernetes namespace %s", staticClientNamespace) - k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticClientNamespace) + StaticClientNamespace := "ns2" + logger.Logf(t, "creating Kubernetes namespace %s", StaticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { - k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticClientNamespace) + k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) }) ns1K8SOptions := &terratestk8s.KubectlOptions{ @@ -195,7 +195,7 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { ns2K8SOptions := &terratestk8s.KubectlOptions{ ContextName: ctx.KubectlOptions(t).ContextName, ConfigPath: ctx.KubectlOptions(t).ConfigPath, - Namespace: staticClientNamespace, + Namespace: StaticClientNamespace, } // Deploy a static-server that will play the role of an external service. @@ -224,12 +224,12 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { // With the terminating gateway up, we test that we can make a call to it // via the static-server. It should fail to connect with the // static-server pod because of intentions. - assertNoConnectionAndAddIntention(t, consulClient, ns2K8SOptions, staticClientNamespace, testNamespace) + assertNoConnectionAndAddIntention(t, consulClient, ns2K8SOptions, StaticClientNamespace, testNamespace) } // Test that we can make a call to the terminating gateway logger.Log(t, "trying calls to terminating gateway") - k8s.CheckStaticServerConnectionSuccessful(t, ns2K8SOptions, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ns2K8SOptions, StaticClientName, "http://localhost:1234") }) } } diff --git a/acceptance/tests/terminating-gateway/terminating_gateway_test.go b/acceptance/tests/terminating-gateway/terminating_gateway_test.go index 61b01e76e6..411bf9074e 100644 --- a/acceptance/tests/terminating-gateway/terminating_gateway_test.go +++ b/acceptance/tests/terminating-gateway/terminating_gateway_test.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/require" ) -const staticClientName = "static-client" +const StaticClientName = "static-client" const staticServerName = "static-server" // Test that terminating gateways work in a default and secure installations. @@ -93,7 +93,7 @@ func TestTerminatingGateway(t *testing.T) { // Test that we can make a call to the terminating gateway. logger.Log(t, "trying calls to terminating gateway") - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") }) } } @@ -191,7 +191,7 @@ func assertNoConnectionAndAddIntention(t *testing.T, consulClient *api.Client, k t.Helper() logger.Log(t, "testing intentions prevent connections through the terminating gateway") - k8s.CheckStaticServerConnectionFailing(t, k8sOptions, staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, k8sOptions, StaticClientName, "http://localhost:1234") logger.Log(t, "creating static-client => static-server intention") _, _, err := consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ @@ -200,7 +200,7 @@ func assertNoConnectionAndAddIntention(t *testing.T, consulClient *api.Client, k Namespace: destinationNS, Sources: []*api.SourceIntention{ { - Name: staticClientName, + Name: StaticClientName, Namespace: sourceNS, Action: api.IntentionActionAllow, }, diff --git a/acceptance/tests/vault/vault_namespaces_test.go b/acceptance/tests/vault/vault_namespaces_test.go index 161a275fb7..8b1a1989c9 100644 --- a/acceptance/tests/vault/vault_namespaces_test.go +++ b/acceptance/tests/vault/vault_namespaces_test.go @@ -12,6 +12,7 @@ import ( "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/hashicorp/go-uuid" "github.com/stretchr/testify/require" ) @@ -48,26 +49,118 @@ func TestVault_VaultNamespace(t *testing.T) { // Now fetch the Vault client so we can create the policies and secrets. vaultClient := vaultCluster.VaultClient(t) - gossipKey := vault.ConfigureGossipVaultSecret(t, vaultClient) + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + MaxTTL: "1h", + AuthMethodPath: "kubernetes", + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } if cfg.EnableEnterprise { - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) } - bootstrapToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") + //Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) - serverPolicies := "gossip,connect-ca-dc1,server-cert-dc1,bootstrap-token" + // ------------------------- + // Additional Auth Roles + // ------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) if cfg.EnableEnterprise { - serverPolicies += ",license" + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) } - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", serverPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") - vault.ConfigurePKICA(t, vaultClient) - certPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", "1h") + // server + consulServerRole := "server" + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: manageSystemACLsRole, + PolicyNames: bootstrapTokenSecret.PolicyName, + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: "kubernetes", + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) vaultCASecret := vault.CASecretName(vaultReleaseName) @@ -81,35 +174,35 @@ func TestVault_VaultNamespace(t *testing.T) { "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "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": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, "global.secretsBackend.vault.connectCA.additionalConfig": fmt.Sprintf(`"{\"connect\": [{ \"ca_config\": [{ \"namespace\": \"%s\"}]}]}"`, vaultNamespacePath), "global.secretsBackend.vault.agentAnnotations": fmt.Sprintf("\"vault.hashicorp.com/namespace\": \"%s\"", vaultNamespacePath), "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, "global.tls.enabled": "true", - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, "ingressGateways.enabled": "true", "ingressGateways.defaults.replicas": "1", "terminatingGateways.enabled": "true", "terminatingGateways.defaults.replicas": "1", - "server.serverCert.secretName": certPath, - "global.tls.caCert.secretName": "pki/cert/ca", + "server.serverCert.secretName": serverPKIConfig.CertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, "global.tls.enableAutoEncrypt": "true", // For sync catalog, it is sufficient to check that the deployment is running and ready @@ -122,8 +215,8 @@ func TestVault_VaultNamespace(t *testing.T) { } if cfg.EnableEnterprise { - consulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - consulHelmValues["global.enterpriseLicense.secretKey"] = "license" + consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } logger.Log(t, "Installing Consul") @@ -175,8 +268,8 @@ func TestVault_VaultNamespace(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } } diff --git a/acceptance/tests/vault/vault_partitions_test.go b/acceptance/tests/vault/vault_partitions_test.go index a89d262113..0fb88a3a4c 100644 --- a/acceptance/tests/vault/vault_partitions_test.go +++ b/acceptance/tests/vault/vault_partitions_test.go @@ -11,6 +11,7 @@ import ( "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/hashicorp/go-uuid" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -102,24 +103,175 @@ func TestVault_Partitions(t *testing.T) { secondaryVaultCluster.ConfigureAuthMethod(t, vaultClient, "kubernetes-"+secondaryPartition, k8sAuthMethodHost, authMethodRBACName, ns) } - vault.ConfigureGossipVaultSecret(t, vaultClient) - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) - vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") - vault.ConfigureACLTokenVaultSecret(t, vaultClient, "partition") + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) + + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + MaxTTL: "1h", + AuthMethodPath: KubernetesAuthMethodPath, + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } + if cfg.EnableEnterprise { + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + } - serverPolicies := "gossip,license,connect-ca-dc1,server-cert-dc1,bootstrap-token" - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", serverPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token,partition-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") + // Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // Partition Token + partitionToken, err := uuid.GenerateUUID() + require.NoError(t, err) + partitionTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/partition", + Key: "token", + Value: partitionToken, + PolicyName: "partition", + } + partitionTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // ------------------------------------------- + // Additional Auth Roles in Primary Datacenter + // ------------------------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) + if cfg.EnableEnterprise { + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) + } - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-"+secondaryPartition, "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-"+secondaryPartition, "server-acl-init", "partition-token") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-"+secondaryPartition, "partition-init", "partition-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes-"+secondaryPartition) - vault.ConfigurePKICA(t, vaultClient) - certPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", "1h") + // server + consulServerRole := "server" + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: manageSystemACLsRole, + PolicyNames: fmt.Sprintf("%s,%s", bootstrapTokenSecret.PolicyName, partitionTokenSecret.PolicyName), + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // --------------------------------------------- + // Additional Auth Roles in Secondary Datacenter + // --------------------------------------------- + + // client + clientAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: fmt.Sprintf("kubernetes-%s", secondaryPartition), + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + aclAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: fmt.Sprintf("kubernetes-%s", secondaryPartition), + RoleName: manageSystemACLsRole, + PolicyNames: partitionTokenSecret.PolicyName, + } + aclAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // partition init + adminPartitionsRole := "partition-init" + partitionInitServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, "partition-init") + prtAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: partitionInitServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: fmt.Sprintf("kubernetes-%s", secondaryPartition), + RoleName: adminPartitionsRole, + PolicyNames: partitionTokenSecret.PolicyName, + } + prtAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: fmt.Sprintf("kubernetes-%s", secondaryPartition), + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) vaultCASecretName := vault.CASecretName(vaultReleaseName) @@ -133,9 +285,9 @@ func TestVault_Partitions(t *testing.T) { "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "global.secretsBackend.vault.ca.secretName": vaultCASecretName, "global.secretsBackend.vault.ca.secretKey": "tls.crt", @@ -144,28 +296,28 @@ func TestVault_Partitions(t *testing.T) { "global.tls.enabled": "true", "global.tls.enableAutoEncrypt": "true", - "global.tls.caCert.secretName": "pki/cert/ca", + "global.tls.caCert.secretName": serverPKIConfig.CAPath, - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, - "global.enterpriseLicense.secretName": "consul/data/secret/license", - "global.enterpriseLicense.secretKey": "license", + "global.enterpriseLicense.secretName": licenseSecret.Path, + "global.enterpriseLicense.secretKey": licenseSecret.Key, } serverHelmValues := map[string]string{ - "global.secretsBackend.vault.consulServerRole": "server", + "global.secretsBackend.vault.consulServerRole": consulServerRole, "global.secretsBackend.vault.connectCA.address": serverClusterVault.Address(), - "global.secretsBackend.vault.connectCA.rootPKIPath": "connect_root", - "global.secretsBackend.vault.connectCA.intermediatePKIPath": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", - "global.acls.partitionToken.secretName": "consul/data/secret/partition", - "global.acls.partitionToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, + "global.acls.partitionToken.secretName": partitionTokenSecret.Path, + "global.acls.partitionToken.secretKey": partitionTokenSecret.Key, "server.exposeGossipAndRPCPorts": "true", - "server.serverCert.secretName": certPath, + "server.serverCert.secretName": serverPKIConfig.CertPath, "server.extraVolumes[0].type": "secret", "server.extraVolumes[0].name": vaultCASecretName, @@ -211,11 +363,11 @@ func TestVault_Partitions(t *testing.T) { "global.adminPartitions.name": secondaryPartition, - "global.acls.bootstrapToken.secretName": "consul/data/secret/partition", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": partitionTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": partitionTokenSecret.Key, "global.secretsBackend.vault.agentAnnotations": fmt.Sprintf("vault.hashicorp.com/tls-server-name: %s-vault", vaultReleaseName), - "global.secretsBackend.vault.adminPartitionsRole": "partition-init", + "global.secretsBackend.vault.adminPartitionsRole": adminPartitionsRole, "externalServers.enabled": "true", "externalServers.hosts[0]": partitionSvcAddress, diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 46d374c251..981b2c771a 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -10,10 +10,17 @@ import ( "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/hashicorp/go-uuid" "github.com/stretchr/testify/require" ) -const staticClientName = "static-client" +const ( + StaticClientName = "static-client" + KubernetesAuthMethodPath = "kubernetes" + ManageSystemACLsRole = "server-acl-init" + ClientRole = "client" + ServerRole = "server" +) // 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. @@ -32,26 +39,118 @@ func TestVault(t *testing.T) { // Now fetch the Vault client so we can create the policies and secrets. vaultClient := vaultCluster.VaultClient(t) - gossipKey := vault.ConfigureGossipVaultSecret(t, vaultClient) + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) + + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + MaxTTL: "1h", + AuthMethodPath: KubernetesAuthMethodPath, + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } if cfg.EnableEnterprise { - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) } - bootstrapToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") + // Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) - serverPolicies := "gossip,connect-ca-dc1,server-cert-dc1,bootstrap-token" + // ------------------------- + // Additional Auth Roles + // ------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) if cfg.EnableEnterprise { - serverPolicies += ",license" + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) + } + + // server + consulServerRole := ServerRole + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: manageSystemACLsRole, + PolicyNames: bootstrapTokenSecret.PolicyName, } - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", serverPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) - vault.ConfigurePKICA(t, vaultClient) - certPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", "1h") + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) vaultCASecret := vault.CASecretName(vaultReleaseName) @@ -65,32 +164,32 @@ func TestVault(t *testing.T) { "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "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": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, "global.tls.enabled": "true", - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, "ingressGateways.enabled": "true", "ingressGateways.defaults.replicas": "1", "terminatingGateways.enabled": "true", "terminatingGateways.defaults.replicas": "1", - "server.serverCert.secretName": certPath, - "global.tls.caCert.secretName": "pki/cert/ca", + "server.serverCert.secretName": serverPKIConfig.CertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, "global.tls.enableAutoEncrypt": "true", // For sync catalog, it is sufficient to check that the deployment is running and ready @@ -103,8 +202,8 @@ func TestVault(t *testing.T) { } if cfg.EnableEnterprise { - consulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - consulHelmValues["global.enterpriseLicense.secretKey"] = "license" + consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } logger.Log(t, "Installing Consul") @@ -156,8 +255,8 @@ func TestVault(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } } diff --git a/acceptance/tests/vault/vault_tls_auto_reload_test.go b/acceptance/tests/vault/vault_tls_auto_reload_test.go index dd5e486b88..cfc65cf18a 100644 --- a/acceptance/tests/vault/vault_tls_auto_reload_test.go +++ b/acceptance/tests/vault/vault_tls_auto_reload_test.go @@ -13,6 +13,7 @@ import ( "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/hashicorp/go-uuid" "github.com/stretchr/testify/require" ) @@ -34,25 +35,15 @@ func TestVault_TlsAutoReload(t *testing.T) { // Now fetch the Vault client so we can create the policies and secrets. vaultClient := vaultCluster.VaultClient(t) - vault.ConfigureGossipVaultSecret(t, vaultClient) - - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") - if cfg.EnableEnterprise { - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) - } - - bootstrapToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") - - serverPolicies := "gossip,connect-ca-dc1,server-cert-dc1,bootstrap-token" - if cfg.EnableEnterprise { - serverPolicies += ",license" - } - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", serverPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") - - vault.ConfigurePKICA(t, vaultClient) + // ------------------------- + // PKI + // ------------------------- + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) // Initially tried toset the expiration to 5-20s to keep the test as short running as possible, // but at those levels, the pods would fail to start becuase the certs had expired and would throw errors. @@ -61,12 +52,112 @@ func TestVault_TlsAutoReload(t *testing.T) { // If wanting to make this higher, there is no problem except for consideration of how long the test will // take to complete. expirationInSeconds := 30 - certPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", fmt.Sprintf("%ds", expirationInSeconds)) + //Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "server"), + MaxTTL: fmt.Sprintf("%ds", expirationInSeconds), + AuthMethodPath: KubernetesAuthMethodPath, + } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } + if cfg.EnableEnterprise { + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + } + + // Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // ------------------------- + // Additional Auth Roles + // ------------------------- + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", gossipSecret.PolicyName, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) + if cfg.EnableEnterprise { + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) + } + + // server + consulServerRole := "server" + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: manageSystemACLsRole, + PolicyNames: bootstrapTokenSecret.PolicyName, + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) vaultCASecret := vault.CASecretName(vaultReleaseName) consulHelmValues := map[string]string{ - "client.grpc": "true", "server.extraVolumes[0].type": "secret", "server.extraVolumes[0].name": vaultCASecret, "server.extraVolumes[0].load": "false", @@ -76,33 +167,46 @@ func TestVault_TlsAutoReload(t *testing.T) { "controller.enabled": "true", "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "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": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, "global.tls.enabled": "true", - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, + + "ingressGateways.enabled": "true", + "ingressGateways.defaults.replicas": "1", + "terminatingGateways.enabled": "true", + "terminatingGateways.defaults.replicas": "1", - "server.serverCert.secretName": certPath, - "global.tls.caCert.secretName": "pki/cert/ca", + "server.serverCert.secretName": serverPKIConfig.CertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, "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", } if cfg.EnableEnterprise { - consulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - consulHelmValues["global.enterpriseLicense.secretKey"] = "license" + consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } logger.Log(t, "Installing Consul") @@ -146,9 +250,9 @@ func TestVault_TlsAutoReload(t *testing.T) { logger.Log(t, "checking that connection is successful") if cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } logger.Logf(t, "Wait %d seconds for certificates to rotate....", expirationInSeconds) diff --git a/acceptance/tests/vault/vault_wan_fed_test.go b/acceptance/tests/vault/vault_wan_fed_test.go index e0d8ae1779..d5ceacac2e 100644 --- a/acceptance/tests/vault/vault_wan_fed_test.go +++ b/acceptance/tests/vault/vault_wan_fed_test.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/vault" "github.com/hashicorp/consul/api" + "github.com/hashicorp/go-uuid" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -66,11 +67,7 @@ func TestVault_WANFederationViaGateways(t *testing.T) { vaultClient := primaryVaultCluster.VaultClient(t) - vault.ConfigureGossipVaultSecret(t, vaultClient) - - if cfg.EnableEnterprise { - vault.ConfigureEnterpriseLicenseVaultSecret(t, vaultClient, cfg) - } + secondaryAuthMethodName := "kubernetes-dc2" // Configure Vault Kubernetes auth method for the secondary datacenter. { @@ -108,39 +105,206 @@ func TestVault_WANFederationViaGateways(t *testing.T) { k8sAuthMethodHost := k8s.KubernetesAPIServerHost(t, cfg, secondaryCtx) // Now, configure the auth method in Vault. - secondaryVaultCluster.ConfigureAuthMethod(t, vaultClient, "kubernetes-dc2", k8sAuthMethodHost, authMethodRBACName, ns) + secondaryVaultCluster.ConfigureAuthMethod(t, vaultClient, secondaryAuthMethodName, k8sAuthMethodHost, authMethodRBACName, ns) + } + // ------------------------- + // PKI + // ------------------------- + // dc1 + // Configure Service Mesh CA + connectCAPolicy := "connect-ca-dc1" + connectCARootPath := "connect_root" + connectCAIntermediatePath := "dc1/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicy, connectCARootPath, connectCAIntermediatePath) + + // Configure Server PKI + serverPKIConfig := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy", + RoleName: "consul-ca-role", + KubernetesNamespace: ns, + DataCenter: "dc1", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + MaxTTL: "1h", + AuthMethodPath: KubernetesAuthMethodPath, } + serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient) + + // dc2 + // Configure Service Mesh CA + connectCAPolicySecondary := "connect-ca-dc2" + connectCARootPathSecondary := "connect_root" + connectCAIntermediatePathSecondary := "dc2/connect_inter" + // Configure Policy for Connect CA + vault.CreateConnectCARootAndIntermediatePKIPolicy(t, vaultClient, connectCAPolicySecondary, connectCARootPathSecondary, connectCAIntermediatePathSecondary) + + // Configure Server PKI + serverPKIConfigSecondary := &vault.PKIAndAuthRoleConfiguration{ + BaseURL: "pki", + PolicyName: "consul-ca-policy-dc2", + RoleName: "consul-ca-role-dc2", + KubernetesNamespace: ns, + DataCenter: "dc2", + ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, ServerRole), + MaxTTL: "1h", + AuthMethodPath: secondaryAuthMethodName, + SkipPKIMount: true, + } + serverPKIConfigSecondary.ConfigurePKIAndAuthRole(t, vaultClient) + + // ------------------------- + // KV2 secrets + // ------------------------- + // Gossip key + gossipKey, err := vault.GenerateGossipSecret() + require.NoError(t, err) + gossipSecret := &vault.KV2Secret{ + Path: "consul/data/secret/gossip", + Key: "gossip", + Value: gossipKey, + PolicyName: "gossip", + } + gossipSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // License + licenseSecret := &vault.KV2Secret{ + Path: "consul/data/secret/license", + Key: "license", + Value: cfg.EnterpriseLicense, + PolicyName: "license", + } + if cfg.EnableEnterprise { + licenseSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + } + + // Bootstrap Token + bootstrapToken, err := uuid.GenerateUUID() + require.NoError(t, err) + bootstrapTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/bootstrap", + Key: "token", + Value: bootstrapToken, + PolicyName: "bootstrap", + } + bootstrapTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) + + // Replication Token + replicationToken, err := uuid.GenerateUUID() + require.NoError(t, err) + replicationTokenSecret := &vault.KV2Secret{ + Path: "consul/data/secret/replication", + Key: "token", + Value: replicationToken, + PolicyName: "replication", + } + replicationTokenSecret.SaveSecretAndAddReadPolicy(t, vaultClient) commonServerPolicies := "gossip" if cfg.EnableEnterprise { commonServerPolicies += ",license" } - primaryServerPolicies := commonServerPolicies + ",connect-ca-dc1,server-cert-dc1,bootstrap-token" - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server", primaryServerPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes", "server-acl-init", "bootstrap-token,replication-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes") - - secondaryServerPolicies := commonServerPolicies + ",connect-ca-dc2,server-cert-dc2,replication-token" - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-dc2", "server", secondaryServerPolicies) - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-dc2", "client", "gossip") - vault.ConfigureKubernetesAuthRole(t, vaultClient, consulReleaseName, ns, "kubernetes-dc2", "server-acl-init", "replication-token") - vault.ConfigureConsulCAKubernetesAuthRole(t, vaultClient, ns, "kubernetes-dc2") - - // Generate a CA and create PKI roles for the primary and secondary Consul servers. - vault.ConfigurePKICA(t, vaultClient) - primaryCertPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc1", "1h") - secondaryCertPath := vault.ConfigurePKICertificates(t, vaultClient, consulReleaseName, ns, "dc2", "1h") - - bootstrapToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "bootstrap") - replicationToken := vault.ConfigureACLTokenVaultSecret(t, vaultClient, "replication") - - // Create the Vault Policy for the Connect CA in both datacenters. - vault.CreateConnectCAPolicy(t, vaultClient, "dc1") - vault.CreateConnectCAPolicy(t, vaultClient, "dc2") - - // Move Vault CA secret from primary to secondary so that we can mount it to pods in the - // secondary cluster. + + // -------------------------------------------- + // Additional Auth Roles for Primary Datacenter + // -------------------------------------------- + // server + serverPolicies := fmt.Sprintf("%s,%s,%s,%s", commonServerPolicies, connectCAPolicy, serverPKIConfig.PolicyName, bootstrapTokenSecret.PolicyName) + if cfg.EnableEnterprise { + serverPolicies += fmt.Sprintf(",%s", licenseSecret.PolicyName) + } + consulServerRole := ServerRole + srvAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulServerRole, + PolicyNames: serverPolicies, + } + srvAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // client + consulClientRole := ClientRole + consulClientServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ClientRole) + clientAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + manageSystemACLsRole := ManageSystemACLsRole + manageSystemACLsServiceAccountName := fmt.Sprintf("%s-consul-%s", consulReleaseName, ManageSystemACLsRole) + aclAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: manageSystemACLsRole, + PolicyNames: fmt.Sprintf("%s,%s", bootstrapTokenSecret.PolicyName, replicationTokenSecret.PolicyName), + } + aclAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfig := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: KubernetesAuthMethodPath, + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfig.ConfigureK8SAuthRole(t, vaultClient) + + // -------------------------------------------- + // Additional Auth Roles for Secondary Datacenter + // -------------------------------------------- + // server + secondaryServerPolicies := fmt.Sprintf("%s,%s,%s,%s", commonServerPolicies, connectCAPolicySecondary, serverPKIConfigSecondary.PolicyName, replicationTokenSecret.PolicyName) + srvAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: serverPKIConfig.ServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: secondaryAuthMethodName, + RoleName: consulServerRole, + PolicyNames: secondaryServerPolicies, + } + srvAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // client + clientAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: consulClientServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: secondaryAuthMethodName, + RoleName: consulClientRole, + PolicyNames: gossipSecret.PolicyName, + } + clientAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // manageSystemACLs + aclAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: manageSystemACLsServiceAccountName, + KubernetesNamespace: ns, + AuthMethodPath: secondaryAuthMethodName, + RoleName: manageSystemACLsRole, + PolicyNames: replicationTokenSecret.PolicyName, + } + aclAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // allow all components to access server ca + srvCAAuthRoleConfigSecondary := &vault.KubernetesAuthRoleConfiguration{ + ServiceAccountName: "*", + KubernetesNamespace: ns, + AuthMethodPath: secondaryAuthMethodName, + RoleName: serverPKIConfig.RoleName, + PolicyNames: serverPKIConfig.PolicyName, + } + srvCAAuthRoleConfigSecondary.ConfigureK8SAuthRole(t, vaultClient) + + // // Move Vault CA secret from primary to secondary so that we can mount it to pods in the + // // secondary cluster. vaultCASecretName := vault.CASecretName(vaultReleaseName) logger.Logf(t, "retrieving Vault CA secret %s from the primary cluster and applying to the secondary", vaultCASecretName) vaultCASecret, err := primaryCtx.KubernetesClient(t).CoreV1().Secrets(ns).Get(context.Background(), vaultCASecretName, metav1.GetOptions{}) @@ -160,20 +324,20 @@ func TestVault_WANFederationViaGateways(t *testing.T) { // TLS config. "global.tls.enabled": "true", "global.tls.enableAutoEncrypt": "true", - "global.tls.caCert.secretName": "pki/cert/ca", - "server.serverCert.secretName": primaryCertPath, + "global.tls.caCert.secretName": serverPKIConfig.CAPath, + "server.serverCert.secretName": serverPKIConfig.CertPath, // Gossip config. - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, // ACL config. "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": "consul/data/secret/bootstrap", - "global.acls.bootstrapToken.secretKey": "token", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecret.Path, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecret.Key, "global.acls.createReplicationToken": "true", - "global.acls.replicationToken.secretName": "consul/data/secret/replication", - "global.acls.replicationToken.secretKey": "token", + "global.acls.replicationToken.secretName": replicationTokenSecret.Path, + "global.acls.replicationToken.secretKey": replicationTokenSecret.Key, // Mesh config. "connectInject.enabled": "true", @@ -188,20 +352,20 @@ func TestVault_WANFederationViaGateways(t *testing.T) { // Vault config. "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "global.secretsBackend.vault.ca.secretName": vaultCASecretName, "global.secretsBackend.vault.ca.secretKey": "tls.crt", "global.secretsBackend.vault.connectCA.address": primaryVaultCluster.Address(), - "global.secretsBackend.vault.connectCA.rootPKIPath": "connect_root", - "global.secretsBackend.vault.connectCA.intermediatePKIPath": "dc1/connect_inter", + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPath, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePath, } if cfg.EnableEnterprise { - primaryConsulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - primaryConsulHelmValues["global.enterpriseLicense.secretKey"] = "license" + primaryConsulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + primaryConsulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } if cfg.UseKind { @@ -218,7 +382,7 @@ func TestVault_WANFederationViaGateways(t *testing.T) { // which will point the node IP. if cfg.UseKind { // The Kubernetes AuthMethod host is read from the endpoints for the Kubernetes service. - kubernetesEndpoint, err := secondaryCtx.KubernetesClient(t).CoreV1().Endpoints("default").Get(context.Background(), "kubernetes", metav1.GetOptions{}) + kubernetesEndpoint, err := secondaryCtx.KubernetesClient(t).CoreV1().Endpoints("default").Get(context.Background(), KubernetesAuthMethodPath, metav1.GetOptions{}) require.NoError(t, err) k8sAuthMethodHost = fmt.Sprintf("%s:%d", kubernetesEndpoint.Subsets[0].Addresses[0].IP, kubernetesEndpoint.Subsets[0].Ports[0].Port) } else { @@ -238,17 +402,17 @@ func TestVault_WANFederationViaGateways(t *testing.T) { // TLS config. "global.tls.enabled": "true", "global.tls.enableAutoEncrypt": "true", - "global.tls.caCert.secretName": "pki/cert/ca", - "server.serverCert.secretName": secondaryCertPath, + "global.tls.caCert.secretName": serverPKIConfigSecondary.CAPath, + "server.serverCert.secretName": serverPKIConfigSecondary.CertPath, // Gossip config. - "global.gossipEncryption.secretName": "consul/data/secret/gossip", - "global.gossipEncryption.secretKey": "gossip", + "global.gossipEncryption.secretName": gossipSecret.Path, + "global.gossipEncryption.secretKey": gossipSecret.Key, // ACL config. "global.acls.manageSystemACLs": "true", - "global.acls.replicationToken.secretName": "consul/data/secret/replication", - "global.acls.replicationToken.secretKey": "token", + "global.acls.replicationToken.secretName": replicationTokenSecret.Path, + "global.acls.replicationToken.secretKey": replicationTokenSecret.Key, // Mesh config. "connectInject.enabled": "true", @@ -262,23 +426,23 @@ func TestVault_WANFederationViaGateways(t *testing.T) { // Vault config. "global.secretsBackend.vault.enabled": "true", - "global.secretsBackend.vault.consulServerRole": "server", - "global.secretsBackend.vault.consulClientRole": "client", - "global.secretsBackend.vault.consulCARole": "consul-ca", - "global.secretsBackend.vault.manageSystemACLsRole": "server-acl-init", + "global.secretsBackend.vault.consulServerRole": consulServerRole, + "global.secretsBackend.vault.consulClientRole": consulClientRole, + "global.secretsBackend.vault.consulCARole": serverPKIConfig.RoleName, + "global.secretsBackend.vault.manageSystemACLsRole": manageSystemACLsRole, "global.secretsBackend.vault.ca.secretName": vaultCASecretName, "global.secretsBackend.vault.ca.secretKey": "tls.crt", "global.secretsBackend.vault.agentAnnotations": fmt.Sprintf("vault.hashicorp.com/tls-server-name: %s-vault", vaultReleaseName), "global.secretsBackend.vault.connectCA.address": externalVaultAddress, - "global.secretsBackend.vault.connectCA.authMethodPath": "kubernetes-dc2", - "global.secretsBackend.vault.connectCA.rootPKIPath": "connect_root", - "global.secretsBackend.vault.connectCA.intermediatePKIPath": "dc2/connect_inter", + "global.secretsBackend.vault.connectCA.authMethodPath": secondaryAuthMethodName, + "global.secretsBackend.vault.connectCA.rootPKIPath": connectCARootPathSecondary, + "global.secretsBackend.vault.connectCA.intermediatePKIPath": connectCAIntermediatePathSecondary, "global.secretsBackend.vault.connectCA.additionalConfig": fmt.Sprintf(`"{"connect": [{"ca_config": [{"tls_server_name": "%s-vault"}]}]}"`, vaultReleaseName), } if cfg.EnableEnterprise { - secondaryConsulHelmValues["global.enterpriseLicense.secretName"] = "consul/data/secret/license" - secondaryConsulHelmValues["global.enterpriseLicense.secretKey"] = "license" + secondaryConsulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path + secondaryConsulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key } if cfg.UseKind { @@ -328,7 +492,7 @@ func TestVault_WANFederationViaGateways(t *testing.T) { require.NoError(t, err) logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, primaryCtx.KubectlOptions(t), staticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, primaryCtx.KubectlOptions(t), StaticClientName, "http://localhost:1234") } // vaultAddress returns Vault's server URL depending on test configuration.