DockerCLI/cli/command/context/create_test.go

201 lines
5.5 KiB
Go
Raw Normal View History

package context
import (
"io/ioutil"
"os"
"testing"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/kubernetes"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/internal/test"
"gotest.tools/assert"
"gotest.tools/env"
)
func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) (*test.FakeCli, func()) {
dir, err := ioutil.TempDir("", t.Name())
assert.NilError(t, err)
storeConfig := store.NewConfig(
func() interface{} { return &command.DockerContext{} },
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
store.EndpointTypeGetter(kubernetes.KubernetesEndpoint, func() interface{} { return &kubernetes.EndpointMeta{} }),
)
store := &command.ContextStoreWithDefault{
Store: store.New(dir, storeConfig),
Resolver: func() (*command.DefaultContext, error) {
return &command.DefaultContext{
Meta: store.ContextMetadata{
Endpoints: map[string]interface{}{
docker.DockerEndpoint: docker.EndpointMeta{
Host: "unix:///var/run/docker.sock",
},
},
Metadata: command.DockerContext{
Description: "",
StackOrchestrator: command.OrchestratorSwarm,
},
Name: command.DefaultContextName,
},
TLS: store.ContextTLSData{},
}, nil
},
}
cleanup := func() {
os.RemoveAll(dir)
}
result := test.NewFakeCli(nil, opts...)
for _, o := range opts {
o(result)
}
result.SetContextStore(store)
return result, cleanup
}
func withCliConfig(configFile *configfile.ConfigFile) func(*test.FakeCli) {
return func(m *test.FakeCli) {
m.SetConfigFile(configFile)
}
}
func TestCreateInvalids(t *testing.T) {
cli, cleanup := makeFakeCli(t)
defer cleanup()
assert.NilError(t, cli.ContextStore().CreateOrUpdateContext(store.ContextMetadata{Name: "existing-context"}))
tests := []struct {
options CreateOptions
expecterErr string
}{
{
expecterErr: `context name cannot be empty`,
},
{
options: CreateOptions{
Name: "default",
},
expecterErr: `"default" is a reserved context name`,
},
{
options: CreateOptions{
Name: " ",
},
expecterErr: `context name " " is invalid`,
},
{
options: CreateOptions{
Name: "existing-context",
},
expecterErr: `context "existing-context" already exists`,
},
{
options: CreateOptions{
Name: "invalid-docker-host",
Docker: map[string]string{
keyHost: "some///invalid/host",
},
},
expecterErr: `unable to parse docker host`,
},
{
options: CreateOptions{
Name: "invalid-orchestrator",
DefaultStackOrchestrator: "invalid",
},
expecterErr: `specified orchestrator "invalid" is invalid, please use either kubernetes, swarm or all`,
},
{
options: CreateOptions{
Name: "orchestrator-swarm-no-endpoint",
DefaultStackOrchestrator: "swarm",
},
expecterErr: `docker endpoint configuration is required`,
},
{
options: CreateOptions{
Name: "orchestrator-kubernetes-no-endpoint",
DefaultStackOrchestrator: "kubernetes",
Docker: map[string]string{},
},
expecterErr: `cannot specify orchestrator "kubernetes" without configuring a Kubernetes endpoint`,
},
{
options: CreateOptions{
Name: "orchestrator-all-no-endpoint",
DefaultStackOrchestrator: "all",
Docker: map[string]string{},
},
expecterErr: `cannot specify orchestrator "all" without configuring a Kubernetes endpoint`,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.options.Name, func(t *testing.T) {
err := RunCreate(cli, &tc.options)
assert.ErrorContains(t, err, tc.expecterErr)
})
}
}
func TestCreateOrchestratorSwarm(t *testing.T) {
cli, cleanup := makeFakeCli(t)
defer cleanup()
err := RunCreate(cli, &CreateOptions{
Name: "test",
DefaultStackOrchestrator: "swarm",
Docker: map[string]string{},
})
assert.NilError(t, err)
assert.Equal(t, "test\n", cli.OutBuffer().String())
assert.Equal(t, "Successfully created context \"test\"\n", cli.ErrBuffer().String())
}
func TestCreateOrchestratorEmpty(t *testing.T) {
cli, cleanup := makeFakeCli(t)
defer cleanup()
err := RunCreate(cli, &CreateOptions{
Name: "test",
Docker: map[string]string{},
})
assert.NilError(t, err)
}
func validateTestKubeEndpoint(t *testing.T, s store.Store, name string) {
t.Helper()
ctxMetadata, err := s.GetContextMetadata(name)
assert.NilError(t, err)
kubeMeta := ctxMetadata.Endpoints[kubernetes.KubernetesEndpoint].(kubernetes.EndpointMeta)
kubeEP, err := kubeMeta.WithTLSData(s, name)
assert.NilError(t, err)
assert.Equal(t, "https://someserver", kubeEP.Host)
assert.Equal(t, "the-ca", string(kubeEP.TLSData.CA))
assert.Equal(t, "the-cert", string(kubeEP.TLSData.Cert))
assert.Equal(t, "the-key", string(kubeEP.TLSData.Key))
}
func createTestContextWithKube(t *testing.T, cli command.Cli) {
t.Helper()
revert := env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig")
defer revert()
err := RunCreate(cli, &CreateOptions{
Name: "test",
DefaultStackOrchestrator: "all",
Kubernetes: map[string]string{
keyFromCurrent: "true",
},
Docker: map[string]string{},
})
assert.NilError(t, err)
}
func TestCreateOrchestratorAllKubernetesEndpointFromCurrent(t *testing.T) {
cli, cleanup := makeFakeCli(t)
defer cleanup()
createTestContextWithKube(t, cli)
validateTestKubeEndpoint(t, cli.ContextStore(), "test")
}