From 38fde5882f2094b2b04879b760be38f6a1b120c5 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 27 Oct 2020 15:06:15 -0700 Subject: [PATCH] Use global token for controller Controller token must be global because config entry writes all go to the primary datacenter. This means secondary datacenters need a token that is known by the primary datacenters. --- CHANGELOG.md | 2 ++ subcommand/server-acl-init/command.go | 5 ++++- subcommand/server-acl-init/command_ent_test.go | 10 ++++++++++ subcommand/server-acl-init/command_test.go | 18 ++++++++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7503935f53..dce85a35bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ BUG FIXES: * Federation: ensure replication ACL token can replicate policies and tokens in Consul namespaces other than `default` (Consul-enterprise only). [[GH-364](https://github.com/hashicorp/consul-k8s/issues/364)] * CRDs: validate custom resources can only set namespace fields if Consul namespaces are enabled [[GH-375](https://github.com/hashicorp/consul-k8s/pull/375)] +* CRDs: Ensure ACL token is global so that secondary DCs can manage custom resources. + Without this fix, controllers running in secondary datacenters would get ACL errors. [[GH-369](https://github.com/hashicorp/consul-k8s/pull/369)] ## 0.19.0 (October 12, 2020) diff --git a/subcommand/server-acl-init/command.go b/subcommand/server-acl-init/command.go index b4f514166b..e17aec2e54 100644 --- a/subcommand/server-acl-init/command.go +++ b/subcommand/server-acl-init/command.go @@ -666,7 +666,10 @@ func (c *Command) Run(args []string) int { c.log.Error("Error templating controller token rules", "err", err) return 1 } - err = c.createLocalACL("controller", rules, consulDC, consulClient) + // Controller token must be global because config entry writes all + // go to the primary datacenter. This means secondary datacenters need + // a token that is known by the primary datacenters. + err = c.createGlobalACL("controller", rules, consulDC, consulClient) if err != nil { c.log.Error(err.Error()) return 1 diff --git a/subcommand/server-acl-init/command_ent_test.go b/subcommand/server-acl-init/command_ent_test.go index 8b497c1ee6..7cd28e4b3e 100644 --- a/subcommand/server-acl-init/command_ent_test.go +++ b/subcommand/server-acl-init/command_ent_test.go @@ -232,6 +232,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "-ingress-gateway-name=anothergw", "-terminating-gateway-name=gw", "-terminating-gateway-name=anothergw", + "-create-controller-token", } // Our second run, we're going to update from namespaces disabled to // namespaces enabled with a single destination ns. @@ -267,6 +268,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "anothergw-ingress-gateway-token", "gw-terminating-gateway-token", "anothergw-terminating-gateway-token", + "controller-token", } policies, _, err := consul.ACL().PolicyList(nil) require.NoError(err) @@ -318,6 +320,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "anothergw-ingress-gateway-token", "gw-terminating-gateway-token", "anothergw-terminating-gateway-token", + "controller-token", } policies, _, err = consul.ACL().PolicyList(nil) require.NoError(err) @@ -682,6 +685,13 @@ func TestRun_TokensWithNamespacesEnabled(t *testing.T) { SecretNames: []string{resourcePrefix + "-connect-inject-acl-token"}, LocalToken: false, }, + "controller token": { + TokenFlags: []string{"-create-controller-token"}, + PolicyNames: []string{"controller-token"}, + PolicyDCs: nil, + SecretNames: []string{resourcePrefix + "-controller-acl-token"}, + LocalToken: false, + }, } for testName, c := range cases { t.Run(testName, func(t *testing.T) { diff --git a/subcommand/server-acl-init/command_test.go b/subcommand/server-acl-init/command_test.go index fa1d577e63..17065894bb 100644 --- a/subcommand/server-acl-init/command_test.go +++ b/subcommand/server-acl-init/command_test.go @@ -233,9 +233,9 @@ func TestRun_TokensPrimaryDC(t *testing.T) { TestName: "Controller token", TokenFlags: []string{"-create-controller-token"}, PolicyNames: []string{"controller-token"}, - PolicyDCs: []string{"dc1"}, + PolicyDCs: nil, SecretNames: []string{resourcePrefix + "-controller-acl-token"}, - LocalToken: true, + LocalToken: false, }, { TestName: "Health Checks ACL token", @@ -400,6 +400,14 @@ func TestRun_TokensReplicatedDC(t *testing.T) { SecretNames: []string{resourcePrefix + "-connect-inject-acl-token"}, LocalToken: true, }, + { + TestName: "Controller token", + TokenFlags: []string{"-create-controller-token"}, + PolicyNames: []string{"controller-token-dc2"}, + PolicyDCs: nil, + SecretNames: []string{resourcePrefix + "-controller-acl-token"}, + LocalToken: false, + }, } for _, c := range cases { t.Run(c.TestName, func(t *testing.T) { @@ -530,6 +538,12 @@ func TestRun_TokensWithProvidedBootstrapToken(t *testing.T) { PolicyNames: []string{"connect-inject-token"}, SecretNames: []string{resourcePrefix + "-connect-inject-acl-token"}, }, + { + TestName: "Controller token", + TokenFlags: []string{"-create-controller-token"}, + PolicyNames: []string{"controller-token"}, + SecretNames: []string{resourcePrefix + "-controller-acl-token"}, + }, } for _, c := range cases { t.Run(c.TestName, func(t *testing.T) {