Files
nomad/command/namespace_apply_test.go
Tim Gross 3ee6c31241 ACLs: allow/deny/default config for Consul/Vault clusters by namespace (#18425)
In Nomad Enterprise when multiple Vault/Consul clusters are configured, cluster admins can control access to clusters for jobs via namespace ACLs, similar to how we've done so for node pools. This changeset updates the ACL configuration structs, but doesn't wire them up.
2023-09-08 11:37:20 -04:00

169 lines
3.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package command
import (
"strings"
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/ci"
"github.com/mitchellh/cli"
"github.com/shoenig/test/must"
"github.com/stretchr/testify/assert"
)
func TestNamespaceApplyCommand_Implements(t *testing.T) {
ci.Parallel(t)
var _ cli.Command = &NamespaceApplyCommand{}
}
func TestNamespaceApplyCommand_Fails(t *testing.T) {
ci.Parallel(t)
ui := cli.NewMockUi()
cmd := &NamespaceApplyCommand{Meta: Meta{Ui: ui}}
// Fails on misuse
if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 {
t.Fatalf("expected exit code 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) {
t.Fatalf("expected help output, got: %s", out)
}
ui.ErrorWriter.Reset()
if code := cmd.Run([]string{"-address=nope"}); code != 1 {
t.Fatalf("expected exit code 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) {
t.Fatalf("name required error, got: %s", out)
}
ui.ErrorWriter.Reset()
}
func TestNamespaceApplyCommand_Good(t *testing.T) {
ci.Parallel(t)
// Create a server
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
ui := cli.NewMockUi()
cmd := &NamespaceApplyCommand{Meta: Meta{Ui: ui}}
// Create a namespace
name, desc := "foo", "bar"
if code := cmd.Run([]string{"-address=" + url, "-description=" + desc, name}); code != 0 {
t.Fatalf("expected exit 0, got: %d; %v", code, ui.ErrorWriter.String())
}
namespaces, _, err := client.Namespaces().List(nil)
assert.Nil(t, err)
assert.Len(t, namespaces, 2)
}
func TestNamespaceApplyCommand_parseNamesapceSpec(t *testing.T) {
ci.Parallel(t)
testCases := []struct {
name string
input string
expected *api.Namespace
}{
{
name: "valid namespace",
input: `
name = "test-namespace"
description = "Test namespace"
quota = "test"
capabilities {
enabled_task_drivers = ["exec", "docker"]
disabled_task_drivers = ["raw_exec"]
}
node_pool_config {
default = "dev"
allowed = ["prod*"]
}
vault {
default = "infra"
allowed = ["apps", "infra"]
}
consul {
default = "prod"
allowed = ["prod", "apps*"]
}
meta {
dept = "eng"
}`,
expected: &api.Namespace{
Name: "test-namespace",
Description: "Test namespace",
Quota: "test",
Capabilities: &api.NamespaceCapabilities{
EnabledTaskDrivers: []string{"exec", "docker"},
DisabledTaskDrivers: []string{"raw_exec"},
},
NodePoolConfiguration: &api.NamespaceNodePoolConfiguration{
Default: "dev",
Allowed: []string{"prod*"},
},
VaultConfiguration: &api.NamespaceVaultConfiguration{
Default: "infra",
Allowed: []string{"apps", "infra"},
},
ConsulConfiguration: &api.NamespaceConsulConfiguration{
Default: "prod",
Allowed: []string{"prod", "apps*"},
},
Meta: map[string]string{
"dept": "eng",
},
},
},
{
name: "minimal",
input: `name = "test-small"`,
expected: &api.Namespace{
Name: "test-small",
},
},
{
name: "empty",
input: "",
expected: &api.Namespace{},
},
{
name: "lists in node pool config are nil if not provided",
input: `
name = "nil-lists"
node_pool_config {
default = "default"
}
`,
expected: &api.Namespace{
Name: "nil-lists",
NodePoolConfiguration: &api.NamespaceNodePoolConfiguration{
Default: "default",
Allowed: nil,
Denied: nil,
},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := parseNamespaceSpec([]byte(tc.input))
must.NoError(t, err)
must.Eq(t, tc.expected, got)
})
}
}