Merge component 'cli' from git@github.com:docker/cli master
This commit is contained in:
@ -166,7 +166,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Experimental field")
|
||||
}
|
||||
orchestrator, err := GetOrchestrator(hasExperimental, opts.Common.Orchestrator, cli.configFile.Orchestrator)
|
||||
orchestrator, err := GetOrchestrator(opts.Common.Orchestrator, cli.configFile.Orchestrator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -244,7 +244,7 @@ type ClientInfo struct {
|
||||
|
||||
// HasKubernetes checks if kubernetes orchestrator is enabled
|
||||
func (c ClientInfo) HasKubernetes() bool {
|
||||
return c.HasExperimental && (c.Orchestrator == OrchestratorKubernetes || c.Orchestrator == OrchestratorAll)
|
||||
return c.Orchestrator == OrchestratorKubernetes || c.Orchestrator == OrchestratorAll
|
||||
}
|
||||
|
||||
// HasSwarm checks if swarm orchestrator is enabled
|
||||
|
||||
@ -176,28 +176,14 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "default",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
expectedOrchestrator: "swarm",
|
||||
expectedKubernetes: false,
|
||||
expectedSwarm: true,
|
||||
},
|
||||
{
|
||||
doc: "kubernetesIsExperimental",
|
||||
configfile: `{
|
||||
"experimental": "disabled",
|
||||
"orchestrator": "kubernetes"
|
||||
}`,
|
||||
envOrchestrator: "kubernetes",
|
||||
flagOrchestrator: "kubernetes",
|
||||
expectedOrchestrator: "swarm",
|
||||
expectedKubernetes: false,
|
||||
expectedSwarm: true,
|
||||
},
|
||||
{
|
||||
doc: "kubernetesConfigFile",
|
||||
configfile: `{
|
||||
"experimental": "enabled",
|
||||
"orchestrator": "kubernetes"
|
||||
}`,
|
||||
expectedOrchestrator: "kubernetes",
|
||||
@ -207,7 +193,6 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "kubernetesEnv",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
envOrchestrator: "kubernetes",
|
||||
expectedOrchestrator: "kubernetes",
|
||||
@ -217,7 +202,6 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "kubernetesFlag",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
flagOrchestrator: "kubernetes",
|
||||
expectedOrchestrator: "kubernetes",
|
||||
@ -227,7 +211,6 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "allOrchestratorFlag",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
flagOrchestrator: "all",
|
||||
expectedOrchestrator: "all",
|
||||
@ -237,7 +220,6 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "envOverridesConfigFile",
|
||||
configfile: `{
|
||||
"experimental": "enabled",
|
||||
"orchestrator": "kubernetes"
|
||||
}`,
|
||||
envOrchestrator: "swarm",
|
||||
@ -248,7 +230,6 @@ func TestOrchestratorSwitch(t *testing.T) {
|
||||
{
|
||||
doc: "flagOverridesEnv",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
envOrchestrator: "kubernetes",
|
||||
flagOrchestrator: "swarm",
|
||||
|
||||
@ -38,11 +38,7 @@ func normalize(value string) (Orchestrator, error) {
|
||||
|
||||
// GetOrchestrator checks DOCKER_ORCHESTRATOR environment variable and configuration file
|
||||
// orchestrator value and returns user defined Orchestrator.
|
||||
func GetOrchestrator(isExperimental bool, flagValue, value string) (Orchestrator, error) {
|
||||
// Non experimental CLI has kubernetes disabled
|
||||
if !isExperimental {
|
||||
return defaultOrchestrator, nil
|
||||
}
|
||||
func GetOrchestrator(flagValue, value string) (Orchestrator, error) {
|
||||
// Check flag
|
||||
if o, err := normalize(flagValue); o != orchestratorUnset {
|
||||
return o, err
|
||||
|
||||
@ -33,7 +33,6 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags := cmd.PersistentFlags()
|
||||
flags.String("kubeconfig", "", "Kubernetes config file")
|
||||
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
|
||||
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,6 @@ func NewOptions(flags *flag.FlagSet) Options {
|
||||
func AddNamespaceFlag(flags *flag.FlagSet) {
|
||||
flags.String("namespace", "", "Kubernetes namespace to use")
|
||||
flags.SetAnnotation("namespace", "kubernetes", nil)
|
||||
flags.SetAnnotation("namespace", "experimentalCLI", nil)
|
||||
}
|
||||
|
||||
// WrapCli wraps command.Cli with kubernetes specifics
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/pkg/errors"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
@ -19,11 +20,18 @@ import (
|
||||
// GetStacks lists the kubernetes stacks
|
||||
func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
if opts.AllNamespaces || len(opts.Namespaces) == 0 {
|
||||
if isAllNamespacesDisabled(kubeCli.ConfigFile().Kubernetes) {
|
||||
opts.AllNamespaces = true
|
||||
}
|
||||
return getStacksWithAllNamespaces(kubeCli, opts)
|
||||
}
|
||||
return getStacksWithNamespaces(kubeCli, opts, removeDuplicates(opts.Namespaces))
|
||||
}
|
||||
|
||||
func isAllNamespacesDisabled(kubeCliConfig *configfile.KubernetesConfig) bool {
|
||||
return kubeCliConfig == nil || kubeCliConfig != nil && kubeCliConfig.AllNamespaces != "disabled"
|
||||
}
|
||||
|
||||
func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||
composeClient, err := kubeCli.composeClient()
|
||||
if err != nil {
|
||||
|
||||
@ -30,10 +30,8 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
|
||||
flags.StringSliceVar(&opts.Namespaces, "namespace", []string{}, "Kubernetes namespaces to use")
|
||||
flags.SetAnnotation("namespace", "kubernetes", nil)
|
||||
flags.SetAnnotation("namespace", "experimentalCLI", nil)
|
||||
flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks from all Kubernetes namespaces")
|
||||
flags.SetAnnotation("all-namespaces", "kubernetes", nil)
|
||||
flags.SetAnnotation("all-namespaces", "experimentalCLI", nil)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,9 @@ package swarm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/cli/opts"
|
||||
@ -17,7 +20,7 @@ func getStackFilter(namespace string) filters.Args {
|
||||
return filter
|
||||
}
|
||||
|
||||
func getServiceFilter(namespace string) filters.Args {
|
||||
func getStackServiceFilter(namespace string) filters.Args {
|
||||
return getStackFilter(namespace)
|
||||
}
|
||||
|
||||
@ -33,42 +36,43 @@ func getAllStacksFilter() filters.Args {
|
||||
return filter
|
||||
}
|
||||
|
||||
func getServices(
|
||||
ctx context.Context,
|
||||
apiclient client.APIClient,
|
||||
namespace string,
|
||||
) ([]swarm.Service, error) {
|
||||
return apiclient.ServiceList(
|
||||
ctx,
|
||||
types.ServiceListOptions{Filters: getServiceFilter(namespace)})
|
||||
func getStackServices(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Service, error) {
|
||||
return apiclient.ServiceList(ctx, types.ServiceListOptions{Filters: getStackServiceFilter(namespace)})
|
||||
}
|
||||
|
||||
func getStackNetworks(
|
||||
ctx context.Context,
|
||||
apiclient client.APIClient,
|
||||
namespace string,
|
||||
) ([]types.NetworkResource, error) {
|
||||
return apiclient.NetworkList(
|
||||
ctx,
|
||||
types.NetworkListOptions{Filters: getStackFilter(namespace)})
|
||||
func getStackNetworks(ctx context.Context, apiclient client.APIClient, namespace string) ([]types.NetworkResource, error) {
|
||||
return apiclient.NetworkList(ctx, types.NetworkListOptions{Filters: getStackFilter(namespace)})
|
||||
}
|
||||
|
||||
func getStackSecrets(
|
||||
ctx context.Context,
|
||||
apiclient client.APIClient,
|
||||
namespace string,
|
||||
) ([]swarm.Secret, error) {
|
||||
return apiclient.SecretList(
|
||||
ctx,
|
||||
types.SecretListOptions{Filters: getStackFilter(namespace)})
|
||||
func getStackSecrets(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Secret, error) {
|
||||
return apiclient.SecretList(ctx, types.SecretListOptions{Filters: getStackFilter(namespace)})
|
||||
}
|
||||
|
||||
func getStackConfigs(
|
||||
ctx context.Context,
|
||||
apiclient client.APIClient,
|
||||
namespace string,
|
||||
) ([]swarm.Config, error) {
|
||||
return apiclient.ConfigList(
|
||||
ctx,
|
||||
types.ConfigListOptions{Filters: getStackFilter(namespace)})
|
||||
func getStackConfigs(ctx context.Context, apiclient client.APIClient, namespace string) ([]swarm.Config, error) {
|
||||
return apiclient.ConfigList(ctx, types.ConfigListOptions{Filters: getStackFilter(namespace)})
|
||||
}
|
||||
|
||||
// validateStackName checks if the provided string is a valid stack name (namespace).
|
||||
//
|
||||
// It currently only does a rudimentary check if the string is empty, or consists
|
||||
// of only whitespace and quoting characters.
|
||||
func validateStackName(namespace string) error {
|
||||
v := strings.TrimFunc(namespace, quotesOrWhitespace)
|
||||
if len(v) == 0 {
|
||||
return fmt.Errorf("invalid stack name: %q", namespace)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateStackNames(namespaces []string) error {
|
||||
for _, ns := range namespaces {
|
||||
if err := validateStackName(ns); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func quotesOrWhitespace(r rune) bool {
|
||||
return unicode.IsSpace(r) || r == '"' || r == '\''
|
||||
}
|
||||
|
||||
@ -24,6 +24,9 @@ const (
|
||||
func RunDeploy(dockerCli command.Cli, opts options.Deploy) error {
|
||||
ctx := context.Background()
|
||||
|
||||
if err := validateStackName(opts.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateResolveImageFlag(dockerCli, &opts); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -73,7 +76,7 @@ func checkDaemonIsSwarmManager(ctx context.Context, dockerCli command.Cli) error
|
||||
func pruneServices(ctx context.Context, dockerCli command.Cli, namespace convert.Namespace, services map[string]struct{}) {
|
||||
client := dockerCli.Client()
|
||||
|
||||
oldServices, err := getServices(ctx, client, namespace.Name())
|
||||
oldServices, err := getStackServices(ctx, client, namespace.Name())
|
||||
if err != nil {
|
||||
fmt.Fprintf(dockerCli.Err(), "Failed to list services: %s\n", err)
|
||||
}
|
||||
|
||||
@ -16,6 +16,9 @@ import (
|
||||
)
|
||||
|
||||
func deployBundle(ctx context.Context, dockerCli command.Cli, opts options.Deploy) error {
|
||||
if err := validateStackName(opts.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
bundle, err := loadBundlefile(dockerCli.Err(), opts.Namespace, opts.Bundlefile)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@ -18,6 +18,9 @@ import (
|
||||
)
|
||||
|
||||
func deployCompose(ctx context.Context, dockerCli command.Cli, opts options.Deploy) error {
|
||||
if err := validateStackName(opts.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := loader.LoadComposefile(dockerCli, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -209,7 +212,7 @@ func deployServices(
|
||||
apiClient := dockerCli.Client()
|
||||
out := dockerCli.Out()
|
||||
|
||||
existingServices, err := getServices(ctx, apiClient, namespace.Name())
|
||||
existingServices, err := getStackServices(ctx, apiClient, namespace.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -26,6 +27,15 @@ func TestPruneServices(t *testing.T) {
|
||||
assert.Check(t, is.DeepEqual(buildObjectIDs([]string{objectName("foo", "remove")}), client.removedServices))
|
||||
}
|
||||
|
||||
func TestDeployWithEmptyName(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
client := &fakeClient{}
|
||||
dockerCli := test.NewFakeCli(client)
|
||||
|
||||
err := deployCompose(ctx, dockerCli, options.Deploy{Namespace: "' '", Prune: true})
|
||||
assert.Check(t, is.Error(err, `invalid stack name: "' '"`))
|
||||
}
|
||||
|
||||
// TestServiceUpdateResolveImageChanged tests that the service's
|
||||
// image digest, and "ForceUpdate" is preserved if the image did not change in
|
||||
// the compose file
|
||||
|
||||
@ -13,19 +13,21 @@ import (
|
||||
|
||||
// RunPS is the swarm implementation of docker stack ps
|
||||
func RunPS(dockerCli command.Cli, opts options.PS) error {
|
||||
namespace := opts.Namespace
|
||||
client := dockerCli.Client()
|
||||
ctx := context.Background()
|
||||
if err := validateStackName(opts.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filter := getStackFilterFromOpt(opts.Namespace, opts.Filter)
|
||||
|
||||
ctx := context.Background()
|
||||
client := dockerCli.Client()
|
||||
tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tasks) == 0 {
|
||||
return fmt.Errorf("nothing found in stack: %s", namespace)
|
||||
return fmt.Errorf("nothing found in stack: %s", opts.Namespace)
|
||||
}
|
||||
|
||||
format := opts.Format
|
||||
|
||||
18
components/cli/cli/command/stack/swarm/ps_test.go
Normal file
18
components/cli/cli/command/stack/swarm/ps_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
func TestRunPSWithEmptyName(t *testing.T) {
|
||||
client := &fakeClient{}
|
||||
dockerCli := test.NewFakeCli(client)
|
||||
|
||||
err := RunPS(dockerCli, options.PS{Namespace: "' '"})
|
||||
assert.Check(t, is.Error(err, `invalid stack name: "' '"`))
|
||||
}
|
||||
@ -16,13 +16,16 @@ import (
|
||||
|
||||
// RunRemove is the swarm implementation of docker stack remove
|
||||
func RunRemove(dockerCli command.Cli, opts options.Remove) error {
|
||||
namespaces := opts.Namespaces
|
||||
if err := validateStackNames(opts.Namespaces); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := dockerCli.Client()
|
||||
ctx := context.Background()
|
||||
|
||||
var errs []string
|
||||
for _, namespace := range namespaces {
|
||||
services, err := getServices(ctx, client, namespace)
|
||||
for _, namespace := range opts.Namespaces {
|
||||
services, err := getStackServices(ctx, client, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
18
components/cli/cli/command/stack/swarm/remove_test.go
Normal file
18
components/cli/cli/command/stack/swarm/remove_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
func TestRunRemoveWithEmptyName(t *testing.T) {
|
||||
client := &fakeClient{}
|
||||
dockerCli := test.NewFakeCli(client)
|
||||
|
||||
err := RunRemove(dockerCli, options.Remove{Namespaces: []string{"good", "' '", "alsogood"}})
|
||||
assert.Check(t, is.Error(err, `invalid stack name: "' '"`))
|
||||
}
|
||||
@ -14,6 +14,9 @@ import (
|
||||
|
||||
// RunServices is the swarm implementation of docker stack services
|
||||
func RunServices(dockerCli command.Cli, opts options.Services) error {
|
||||
if err := validateStackName(opts.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
client := dockerCli.Client()
|
||||
|
||||
|
||||
18
components/cli/cli/command/stack/swarm/services_test.go
Normal file
18
components/cli/cli/command/stack/swarm/services_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
func TestRunServicesWithEmptyName(t *testing.T) {
|
||||
client := &fakeClient{}
|
||||
dockerCli := test.NewFakeCli(client)
|
||||
|
||||
err := RunServices(dockerCli, options.Services{Namespace: "' '"})
|
||||
assert.Check(t, is.Error(err, `invalid stack name: "' '"`))
|
||||
}
|
||||
@ -108,7 +108,6 @@ func NewVersionCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template")
|
||||
flags.StringVarP(&opts.kubeConfig, "kubeconfig", "k", "", "Kubernetes config file")
|
||||
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
|
||||
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package configfile
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -46,6 +47,7 @@ type ConfigFile struct {
|
||||
Proxies map[string]ProxyConfig `json:"proxies,omitempty"`
|
||||
Experimental string `json:"experimental,omitempty"`
|
||||
Orchestrator string `json:"orchestrator,omitempty"`
|
||||
Kubernetes *KubernetesConfig `json:"kubernetes,omitempty"`
|
||||
}
|
||||
|
||||
// ProxyConfig contains proxy configuration settings
|
||||
@ -56,6 +58,11 @@ type ProxyConfig struct {
|
||||
FTPProxy string `json:"ftpProxy,omitempty"`
|
||||
}
|
||||
|
||||
// KubernetesConfig contains Kubernetes orchestrator settings
|
||||
type KubernetesConfig struct {
|
||||
AllNamespaces string `json:"allNamespaces,omitempty"`
|
||||
}
|
||||
|
||||
// New initializes an empty configuration file for the given filename 'fn'
|
||||
func New(fn string) *ConfigFile {
|
||||
return &ConfigFile{
|
||||
@ -119,7 +126,7 @@ func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error {
|
||||
ac.ServerAddress = addr
|
||||
configFile.AuthConfigs[addr] = ac
|
||||
}
|
||||
return nil
|
||||
return checkKubernetesConfiguration(configFile.Kubernetes)
|
||||
}
|
||||
|
||||
// ContainsAuth returns whether there is authentication configured
|
||||
@ -312,3 +319,17 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
|
||||
func (configFile *ConfigFile) GetFilename() string {
|
||||
return configFile.Filename
|
||||
}
|
||||
|
||||
func checkKubernetesConfiguration(kubeConfig *KubernetesConfig) error {
|
||||
if kubeConfig == nil {
|
||||
return nil
|
||||
}
|
||||
switch kubeConfig.AllNamespaces {
|
||||
case "":
|
||||
case "enabled":
|
||||
case "disabled":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'kubernetes.allNamespaces' value, should be 'enabled' or 'disabled': %s", kubeConfig.AllNamespaces)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -371,3 +371,45 @@ func TestGetAllCredentialsCredHelperOverridesDefaultStore(t *testing.T) {
|
||||
assert.Check(t, is.Equal(1, testCredsStore.(*mockNativeStore).GetAllCallCount))
|
||||
assert.Check(t, is.Equal(0, testCredHelper.(*mockNativeStore).GetAllCallCount))
|
||||
}
|
||||
|
||||
func TestCheckKubernetesConfigurationRaiseAnErrorOnInvalidValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
config *KubernetesConfig
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
"no kubernetes config is valid",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"enabled is valid",
|
||||
&KubernetesConfig{AllNamespaces: "enabled"},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"disabled is valid",
|
||||
&KubernetesConfig{AllNamespaces: "disabled"},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"empty string is valid",
|
||||
&KubernetesConfig{AllNamespaces: ""},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"other value is invalid",
|
||||
&KubernetesConfig{AllNamespaces: "unknown"},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
err := checkKubernetesConfiguration(test.config)
|
||||
if test.expectError {
|
||||
assert.Assert(t, err != nil, test.name)
|
||||
} else {
|
||||
assert.NilError(t, err, test.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,8 +55,6 @@ func (commonOpts *CommonOptions) InstallFlags(flags *pflag.FlagSet) {
|
||||
flags.StringVarP(&commonOpts.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
|
||||
flags.BoolVar(&commonOpts.TLS, "tls", dockerTLS, "Use TLS; implied by --tlsverify")
|
||||
flags.BoolVar(&commonOpts.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote")
|
||||
flags.StringVar(&commonOpts.Orchestrator, "orchestrator", "", "Orchestrator to use (swarm|kubernetes|all) (experimental)")
|
||||
flags.SetAnnotation("orchestrator", "experimentalCLI", nil)
|
||||
|
||||
// TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
|
||||
|
||||
|
||||
@ -51,6 +51,10 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
|
||||
flags.StringVar(&opts.ConfigDir, "config", cliconfig.Dir(), "Location of client config files")
|
||||
opts.Common.InstallFlags(flags)
|
||||
|
||||
// Install persistent flags
|
||||
persistentFlags := cmd.PersistentFlags()
|
||||
persistentFlags.StringVar(&opts.Common.Orchestrator, "orchestrator", "", "Orchestrator to use (swarm|kubernetes|all)")
|
||||
|
||||
setFlagErrorFunc(dockerCli, cmd, flags, opts)
|
||||
|
||||
setHelpFunc(dockerCli, cmd, flags, opts)
|
||||
|
||||
Reference in New Issue
Block a user