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

Add -create-acl-replication-token flag #210

Merged
merged 1 commit into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
54 changes: 35 additions & 19 deletions subcommand/server-acl-init/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,26 @@ import (
type Command struct {
UI cli.Ui

flags *flag.FlagSet
k8s *k8sflags.K8SFlags
flagReleaseName string
flagServerLabelSelector string
flagResourcePrefix string
flagReplicas int
flagK8sNamespace string
flagAllowDNS bool
flagCreateClientToken bool
flagCreateSyncToken bool
flagCreateInjectToken bool
flagCreateInjectAuthMethod bool
flagBindingRuleSelector string
flagCreateEntLicenseToken bool
flagCreateSnapshotAgentToken bool
flagCreateMeshGatewayToken bool
flagConsulCACert string
flagConsulTLSServerName string
flagUseHTTPS bool
flags *flag.FlagSet
k8s *k8sflags.K8SFlags
flagReleaseName string
flagServerLabelSelector string
flagResourcePrefix string
flagReplicas int
flagK8sNamespace string
flagAllowDNS bool
flagCreateClientToken bool
flagCreateSyncToken bool
flagCreateInjectToken bool
flagCreateInjectAuthMethod bool
flagBindingRuleSelector string
flagCreateEntLicenseToken bool
flagCreateSnapshotAgentToken bool
flagCreateMeshGatewayToken bool
flagCreateACLReplicationToken bool
flagConsulCACert string
flagConsulTLSServerName string
flagUseHTTPS bool

// Flags to support namespaces
flagEnableNamespaces bool // Use namespacing on all components
Expand Down Expand Up @@ -99,6 +100,8 @@ func (c *Command) init() {
"Toggle for creating a token for the Consul snapshot agent deployment (enterprise only)")
c.flags.BoolVar(&c.flagCreateMeshGatewayToken, "create-mesh-gateway-token", false,
"Toggle for creating a token for a Connect mesh gateway")
c.flags.BoolVar(&c.flagCreateACLReplicationToken, "create-acl-replication-token", false,
"Toggle for creating a token for ACL replication between datacenters")
c.flags.StringVar(&c.flagConsulCACert, "consul-ca-cert", "",
"Path to the PEM-encoded CA certificate of the Consul cluster.")
c.flags.StringVar(&c.flagConsulTLSServerName, "consul-tls-server-name", "",
Expand Down Expand Up @@ -416,6 +419,19 @@ func (c *Command) Run(args []string) int {
}
}

if c.flagCreateACLReplicationToken {
rules, err := c.aclReplicationRules()
if err != nil {
c.Log.Error("Error templating acl replication token rules", "err", err)
return 1
}
err = c.createACL("acl-replication", rules, consulClient)
if err != nil {
c.Log.Error(err.Error())
return 1
}
}

c.Log.Info("server-acl-init completed successfully")
return 0
}
Expand Down
14 changes: 14 additions & 0 deletions subcommand/server-acl-init/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,20 @@ func TestRun_Tokens(t *testing.T) {
TokenName: "mesh-gateway",
SecretName: "my-prefix-mesh-gateway-acl-token",
},
"acl-replication token -release-name": {
TokenFlag: "-create-acl-replication-token",
ResourcePrefixFlag: "",
ReleaseNameFlag: "release-name",
TokenName: "acl-replication",
SecretName: "release-name-consul-acl-replication-acl-token",
},
"acl-replication token -resource-prefix": {
TokenFlag: "-create-acl-replication-token",
ResourcePrefixFlag: "my-prefix",
ReleaseNameFlag: "release-name",
TokenName: "acl-replication",
SecretName: "my-prefix-acl-replication-acl-token",
},
}
for testName, c := range cases {
t.Run(testName, func(t *testing.T) {
Expand Down
26 changes: 26 additions & 0 deletions subcommand/server-acl-init/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,32 @@ operator = "write"
return c.renderRules(injectRulesTpl)
}

func (c *Command) aclReplicationRules() (string, error) {
// NOTE: The node_prefix rule is not required for ACL replication. It's
// added so that this token can be used as an ACL replication token *and*
// as an agent token. This allows us to only pass one token between
// datacenters during federation since in order to start ACL replication,
// we need a token with both replication and agent permissions.
aclReplicationRulesTpl := `
acl = "write"
operator = "write"
{{- if .EnableNamespaces }}
namespace_prefix "" {
{{- end }}
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "read"
intentions = "read"
}
{{- if .EnableNamespaces }}
}
{{- end }}
`
return c.renderRules(aclReplicationRulesTpl)
}

func (c *Command) renderRules(tmpl string) (string, error) {
// Check that it's a valid template
compiled, err := template.New("root").Parse(strings.TrimSpace(tmpl))
Expand Down
49 changes: 49 additions & 0 deletions subcommand/server-acl-init/rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,52 @@ operator = "write"`,
})
}
}

func TestReplicationTokenRules(t *testing.T) {
cases := []struct {
Name string
EnableNamespaces bool
Expected string
}{
{
"Namespaces are disabled",
false,
`acl = "write"
operator = "write"
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "read"
intentions = "read"
}`,
},
{
"Namespaces are enabled",
true,
`acl = "write"
operator = "write"
namespace_prefix "" {
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "read"
intentions = "read"
}
}`,
},
}

for _, tt := range cases {
t.Run(tt.Name, func(t *testing.T) {
require := require.New(t)
cmd := Command{
flagEnableNamespaces: tt.EnableNamespaces,
}
replicationTokenRules, err := cmd.aclReplicationRules()
require.NoError(err)
require.Equal(tt.Expected, replicationTokenRules)
})
}
}