Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable configure Connect Injector and Controller Webhooks to be managed by Vault #1191

Merged
merged 80 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
79d97c8
refactored TestVault
jmurret May 12, 2022
10b507c
Fixing name of CreateConnectCARootAndIntermediatePIKPolicy to CreateC…
jmurret May 12, 2022
a34ebb7
refactored all except WAN Fed has error
jmurret May 12, 2022
460125d
fixing vault wan fed test
jmurret May 12, 2022
cf61317
comment formatting
jmurret May 12, 2022
4ecfd7a
PR Feedback. Moving vault helper functions to be on the structs they…
jmurret May 18, 2022
898bf11
PR Feedback. changing name of Save() onkv2secret to something morede…
jmurret May 21, 2022
d192a46
Do not load webhook cert manager when vault is enabled.
jmurret Apr 25, 2022
27ca529
do not mount volumes when using vault
jmurret Apr 25, 2022
14c8b0c
configuring vault injector
jmurret Apr 25, 2022
c0166f3
Fixing linting
jmurret Apr 26, 2022
b37191a
Pods are all running
jmurret Apr 26, 2022
9a2d56a
Fixing cert-dir paths for vault and non-vault use
jmurret Apr 26, 2022
318cca4
fixing volume mount
jmurret Apr 26, 2022
768190e
fixing volume mount again
jmurret Apr 26, 2022
e9c885d
adding bats tests for tls cert directory
jmurret Apr 26, 2022
2661943
fixing cert for tls-cert dir
jmurret Apr 26, 2022
a6ea754
Adding logic to tests for controller tls cert. also adding snapshot …
jmurret Apr 27, 2022
517f573
it works...with hardocded stuff...need to refactor from here
jmurret May 5, 2022
d867059
refactoring out the updating of the webhook config
jmurret May 5, 2022
cf4bec7
adding missing file
jmurret May 5, 2022
bbf9616
adding tests for webhook-cert-manager
jmurret May 9, 2022
68a7e1a
refining webhook cert manager to remove setting of global.enablePodSe…
jmurret May 9, 2022
219366d
adding connect-inject bats tests
jmurret May 9, 2022
401ba17
adding test for controller and use of resource-prefix
jmurret May 9, 2022
8ef4d2b
adding tests for mwc update code
jmurret May 9, 2022
6f8deaf
configure controller to only update mwc with ca bundle when using vau…
jmurret May 9, 2022
f2ddbf1
configure connect inject to only update mwc with ca bundle when using…
jmurret May 9, 2022
b0d6452
fixing lint errors for unnahdled errors
jmurret May 9, 2022
fb16cf1
embedding tlsCertDir for controller and connectInject under vault in …
jmurret May 9, 2022
d9423d6
embedding tlsCertDir for controller and connectInject under vault in …
jmurret May 9, 2022
c22fe6f
change vault role for controller to come from global.secretsBackend.v…
jmurret May 10, 2022
69688cb
fixing vault namespaces and snapshot agent on vault acceptance tests
jmurret May 10, 2022
4123629
fixing VAULT_TLSAUtoReload test
jmurret May 10, 2022
369b265
rebased fromvault refactor. static server replicaset has error about…
jmurret May 12, 2022
e7664ec
Working using separate CAs for connect-injector and controller. only…
jmurret May 13, 2022
228d2f8
adding failure if .Values.global.secretsBackend.vault.consulConnectIn…
jmurret May 17, 2022
1fe928f
updating chart with caCert configs
jmurret May 19, 2022
85eb377
enforcing setting both controller and connectInject CA and tls vault …
jmurret May 19, 2022
a982ec9
correcting connect inject tests
jmurret May 20, 2022
a6b52fb
Update controller tests
jmurret May 20, 2022
328ac87
fixing condition on which web certmanager is shut off
jmurret May 20, 2022
0bd9666
only rendering vault role when suppled in controller and connect-inje…
jmurret May 20, 2022
359fab6
fixing connect inject deploy for vault role
jmurret May 20, 2022
84538d9
making global.secretsBackend.vault.consulCARole the fallback in the c…
jmurret May 21, 2022
dfe53c4
Updating the doc string for TestVault_WebhookCerts
jmurret May 21, 2022
75e2248
correct rebasing issues
jmurret May 22, 2022
2c1a2dd
removing unneccessary format changes. refactoring consul.serverTLSCA…
jmurret May 22, 2022
7450ca5
updating test descriptions for webhook-cert-manager resources
jmurret May 22, 2022
d1cdbc7
updating connect-inject-clusterrole and controller-clusterrole tests
jmurret May 23, 2022
c061aa8
updated maybeFailValuesIfVaultWebhookCertSettingsAreIncomplete
jmurret May 23, 2022
c3b4c2f
Adding Changelog
jmurret May 23, 2022
1ee0d6c
Update maybeFailValuesIfVaultWebhookCertSettingsAreIncomplete to vali…
jmurret May 23, 2022
91b432c
Updating wbhook vault test to make sure that webhook-cert-manager is …
jmurret May 23, 2022
23d30b8
Fixing the validation that webhook-cert-manager is not running in the…
jmurret May 23, 2022
914dfa5
Renamed consulControllerCARole to consulControllerRole and consulCont…
jmurret May 26, 2022
b2db4f1
fixing linting
jmurret May 26, 2022
130360f
Renamed configureCABundleUpdate() to updateWebhookCABundle()
jmurret May 26, 2022
f7c5023
Make ca.crt a constant
jmurret May 26, 2022
8db287f
Adding doc strings for webhook certs secretName
jmurret May 27, 2022
ff519a1
updated alt_names for controller and connect inject deployments to be…
jmurret May 27, 2022
a97e041
Change mutatingwebhookconfigurationswhen to mutatingwebhookconfigurat…
jmurret May 27, 2022
31884b0
added test cases for vault to controller test
jmurret May 31, 2022
687b99e
Webhook certs vault test - checking cert rotation. currently failing.
jmurret May 31, 2022
282057d
moved vault webhook stuff into main vault test and deleted the webhoo…
jmurret Jun 1, 2022
26e2c34
getting rid of lint error
jmurret Jun 1, 2022
dffe549
refactoring long conditional in webhook-cert-manager files into a var…
jmurret Jun 1, 2022
5ea8b94
addressing PR feedback
jmurret Jun 2, 2022
fcf5cac
Apply suggestions from code review
jmurret Jun 2, 2022
ea52b4e
Fixing broken test with retry change
jmurret Jun 2, 2022
43e238a
Update charts/consul/templates/_helpers.tpl
jmurret Jun 2, 2022
04ead9c
Removing 127.0.0.1 from ip_sans
jmurret Jun 6, 2022
afe0288
Removing reference to common_name: Consul Webhook Certificates Service
jmurret Jun 6, 2022
fae8c2f
Removing a dangle reference to Consul Webhook Certificates Service
jmurret Jun 6, 2022
04bd8d9
adding 127.0.0.1 back into server ip_sans
jmurret Jun 13, 2022
81cde1b
making common name the name of the service for connect-inject and con…
jmurret Jun 8, 2022
21c2ee7
Update the description for enable-webhook-ca-update flag in control-p…
jmurret Jun 13, 2022
5cec9a4
Dropping the consul prefix from consulConnectInjectRole and consulCon…
jmurret Jun 13, 2022
bf9de95
Updating values.yaml file descriptions for connectInject and controll…
jmurret Jun 13, 2022
53b740b
Updating cert expiry in logging in vault test from RPC expiry.
jmurret Jun 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## UNRELEASED

IMPROVEMENTS:
* Control Plane
* Enable configuring Connect Injector and Controller Webhooks' certificates to be managed by Vault. [[GH-1191](https://github.com/hashicorp/consul-k8s/pull/1191/)]
* Helm
* Enable the configuring of snapshot intervals in the client snapshot agent via `client.snapshotAgent.interval`. [[GH-1235](https://github.com/hashicorp/consul-k8s/pull/1235)]
* Enable configuring the pod topologySpreadConstraints for mesh, terminating, and ingress gateways. [[GH-1257](https://github.com/hashicorp/consul-k8s/pull/1257)]
Expand Down
8 changes: 6 additions & 2 deletions acceptance/framework/consul/helm_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,16 @@ func (h *HelmCluster) Upgrade(t *testing.T, helmValues map[string]string) {
}

func (h *HelmCluster) CreatePortForwardTunnel(t *testing.T, remotePort int) string {
localPort := terratestk8s.GetAvailablePort(t)
serverPod := fmt.Sprintf("%s-consul-server-0", h.releaseName)
return h.CreatePortForwardTunnelToResourcePort(t, serverPod, remotePort)
}

func (h *HelmCluster) CreatePortForwardTunnelToResourcePort(t *testing.T, resourceName string, remotePort int) string {
localPort := terratestk8s.GetAvailablePort(t)
tunnel := terratestk8s.NewTunnelWithLogger(
h.helmOptions.KubectlOptions,
terratestk8s.ResourceTypePod,
serverPod,
resourceName,
localPort,
remotePort,
h.logger)
Expand Down
4 changes: 2 additions & 2 deletions acceptance/framework/vault/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func GenerateGossipSecret() (string, error) {
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)
allowedDomains := fmt.Sprintf("%s.consul,%s,%s.%s,%s.%s.svc,%s.default.svc.cluster.local", datacenter,
allowedSubdomain, allowedSubdomain, ns, allowedSubdomain, ns, allowedSubdomain)
params := map[string]interface{}{
"allowed_domains": allowedDomains,
"allow_bare_domains": "true",
Expand Down
229 changes: 226 additions & 3 deletions acceptance/tests/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,42 @@ import (
"testing"
"time"

"github.com/hashicorp/consul-k8s/acceptance/framework/config"
"github.com/hashicorp/consul-k8s/acceptance/framework/consul"
"github.com/hashicorp/consul-k8s/acceptance/framework/environment"
"github.com/hashicorp/consul-k8s/acceptance/framework/helpers"
"github.com/hashicorp/consul-k8s/acceptance/framework/k8s"
"github.com/hashicorp/consul-k8s/acceptance/framework/logger"
"github.com/hashicorp/consul-k8s/acceptance/framework/vault"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
)

const (
KubernetesAuthMethodPath = "kubernetes"
ManageSystemACLsRole = "server-acl-init"
ClientRole = "client"
ServerRole = "server"
)

func TestController(t *testing.T) {
cfg := suite.Config()

cases := []struct {
secure bool
autoEncrypt bool
useVault bool
}{
{false, false},
{true, false},
{true, true},
{false, false, false},
{true, false, false},
{true, true, false},
{true, true, true},
{false, false, true},
// Vault with TLS requires autoEncrypt set to true as well, so the below
// is not valid
// {true, false, true},
}

// The name of a service intention in consul is
Expand All @@ -46,11 +63,22 @@ func TestController(t *testing.T) {
}

releaseName := helpers.RandomName()

var bootstrapToken string
var helmConsulValues map[string]string
if c.useVault {
helmConsulValues, bootstrapToken = configureAndGetVaultHelmValues(t, ctx, cfg, releaseName, c.secure)
helpers.MergeMaps(helmConsulValues, helmValues)
}
consulCluster := consul.NewHelmCluster(t, helmValues, ctx, cfg, releaseName)

consulCluster.Create(t)
consulClient, _ := consulCluster.SetupConsulClient(t, c.secure)

if c.useVault {
consulCluster.ACLToken = bootstrapToken
}

// Test creation.
{
logger.Log(t, "creating custom resources")
Expand Down Expand Up @@ -340,3 +368,198 @@ func TestController(t *testing.T) {
})
}
}

func configureAndGetVaultHelmValues(t *testing.T, ctx environment.TestContext,
cfg *config.TestConfig, consulReleaseName string, secure bool) (map[string]string, string) {
vaultReleaseName := helpers.RandomName()
ns := ctx.KubectlOptions(t).Namespace

vaultCluster := vault.NewVaultCluster(t, ctx, cfg, vaultReleaseName, nil)
vaultCluster.Create(t, ctx, "")
// Vault is now installed in the cluster.

// Now fetch the Vault client so we can create the policies and secrets.
vaultClient := vaultCluster.VaultClient(t)

// -------------------------
// 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",
CommonName: "Consul CA",
}
serverPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient)

webhookCertTtl := 25 * time.Second
// Configure controller webhook PKI
controllerWebhookPKIConfig := &vault.PKIAndAuthRoleConfiguration{
BaseURL: "controller",
PolicyName: "controller-ca-policy",
RoleName: "controller-ca-role",
KubernetesNamespace: ns,
DataCenter: "dc1",
ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "controller"),
AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "controller-webhook"),
MaxTTL: webhookCertTtl.String(),
AuthMethodPath: "kubernetes",
}
controllerWebhookPKIConfig.ConfigurePKIAndAuthRole(t, vaultClient)

// Configure controller webhook PKI
connectInjectorWebhookPKIConfig := &vault.PKIAndAuthRoleConfiguration{
BaseURL: "connect",
PolicyName: "connect-ca-policy",
RoleName: "connect-ca-role",
KubernetesNamespace: ns,
DataCenter: "dc1",
ServiceAccountName: fmt.Sprintf("%s-consul-%s", consulReleaseName, "connect-injector"),
AllowedSubdomain: fmt.Sprintf("%s-consul-%s", consulReleaseName, "connect-injector"),
MaxTTL: webhookCertTtl.String(),
AuthMethodPath: "kubernetes",
}
connectInjectorWebhookPKIConfig.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 := 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,
}
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{
"server.extraVolumes[0].type": "secret",
"server.extraVolumes[0].name": vaultCASecret,
"server.extraVolumes[0].load": "false",

"global.secretsBackend.vault.enabled": "true",
"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",
}

if cfg.EnableEnterprise {
consulHelmValues["global.enterpriseLicense.secretName"] = licenseSecret.Path
consulHelmValues["global.enterpriseLicense.secretKey"] = licenseSecret.Key
}

if secure {
consulHelmValues["server.serverCert.secretName"] = serverPKIConfig.CertPath
consulHelmValues["global.tls.caCert.secretName"] = serverPKIConfig.CAPath
consulHelmValues["global.secretsBackend.vault.connectInject.tlsCert.secretName"] = connectInjectorWebhookPKIConfig.CertPath
consulHelmValues["global.secretsBackend.vault.connectInject.caCert.secretName"] = connectInjectorWebhookPKIConfig.CAPath
consulHelmValues["global.secretsBackend.vault.controller.tlsCert.secretName"] = controllerWebhookPKIConfig.CertPath
consulHelmValues["global.secretsBackend.vault.controller.caCert.secretName"] = controllerWebhookPKIConfig.CAPath
consulHelmValues["global.secretsBackend.vault.connectInjectRole"] = connectInjectorWebhookPKIConfig.RoleName
consulHelmValues["global.secretsBackend.vault.controllerRole"] = controllerWebhookPKIConfig.RoleName
consulHelmValues["global.acls.bootstrapToken.secretName"] = bootstrapTokenSecret.Path
consulHelmValues["global.acls.bootstrapToken.secretKey"] = bootstrapTokenSecret.Key
consulHelmValues["global.gossipEncryption.secretName"] = gossipSecret.Path
consulHelmValues["global.gossipEncryption.secretKey"] = gossipSecret.Key
}

return consulHelmValues, bootstrapToken
}
Loading