mirror of https://github.com/docker/cli.git
Activate kubernetes only when experimental cli is enabled
* Refactor tests on version and kubernetes switch * Fix rebase errors * Refactor for gocyclo linter Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
This commit is contained in:
parent
5d375b348a
commit
ad409767bf
|
@ -136,11 +136,11 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Experimental field")
|
return errors.Wrap(err, "Experimental field")
|
||||||
}
|
}
|
||||||
orchestrator := GetOrchestrator(opts.Common.Orchestrator, cli.configFile.Orchestrator)
|
orchestrator := GetOrchestrator(hasExperimental, opts.Common.Orchestrator, cli.configFile.Orchestrator)
|
||||||
cli.clientInfo = ClientInfo{
|
cli.clientInfo = ClientInfo{
|
||||||
DefaultVersion: cli.client.ClientVersion(),
|
DefaultVersion: cli.client.ClientVersion(),
|
||||||
HasExperimental: hasExperimental,
|
HasExperimental: hasExperimental,
|
||||||
HasKubernetes: orchestrator == OrchestratorKubernetes,
|
HasKubernetes: hasExperimental && orchestrator == OrchestratorKubernetes,
|
||||||
Orchestrator: orchestrator,
|
Orchestrator: orchestrator,
|
||||||
}
|
}
|
||||||
cli.initializeFromClient()
|
cli.initializeFromClient()
|
||||||
|
|
|
@ -170,6 +170,110 @@ func TestExperimentalCLI(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrchestratorSwitch(t *testing.T) {
|
||||||
|
defaultVersion := "v1.55"
|
||||||
|
|
||||||
|
var testcases = []struct {
|
||||||
|
doc string
|
||||||
|
configfile string
|
||||||
|
envOrchestrator string
|
||||||
|
flagOrchestrator string
|
||||||
|
expectedOrchestrator string
|
||||||
|
expectedKubernetes bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
doc: "default",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled"
|
||||||
|
}`,
|
||||||
|
expectedOrchestrator: "swarm",
|
||||||
|
expectedKubernetes: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "kubernetesIsExperimental",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "disabled",
|
||||||
|
"orchestrator": "kubernetes"
|
||||||
|
}`,
|
||||||
|
envOrchestrator: "kubernetes",
|
||||||
|
flagOrchestrator: "kubernetes",
|
||||||
|
expectedOrchestrator: "swarm",
|
||||||
|
expectedKubernetes: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "kubernetesConfigFile",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled",
|
||||||
|
"orchestrator": "kubernetes"
|
||||||
|
}`,
|
||||||
|
expectedOrchestrator: "kubernetes",
|
||||||
|
expectedKubernetes: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "kubernetesEnv",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled"
|
||||||
|
}`,
|
||||||
|
envOrchestrator: "kubernetes",
|
||||||
|
expectedOrchestrator: "kubernetes",
|
||||||
|
expectedKubernetes: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "kubernetesFlag",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled"
|
||||||
|
}`,
|
||||||
|
flagOrchestrator: "kubernetes",
|
||||||
|
expectedOrchestrator: "kubernetes",
|
||||||
|
expectedKubernetes: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "envOverridesConfigFile",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled",
|
||||||
|
"orchestrator": "kubernetes"
|
||||||
|
}`,
|
||||||
|
envOrchestrator: "swarm",
|
||||||
|
expectedOrchestrator: "swarm",
|
||||||
|
expectedKubernetes: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
doc: "flagOverridesEnv",
|
||||||
|
configfile: `{
|
||||||
|
"experimental": "enabled"
|
||||||
|
}`,
|
||||||
|
envOrchestrator: "kubernetes",
|
||||||
|
flagOrchestrator: "swarm",
|
||||||
|
expectedOrchestrator: "swarm",
|
||||||
|
expectedKubernetes: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
t.Run(testcase.doc, func(t *testing.T) {
|
||||||
|
dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile))
|
||||||
|
defer dir.Remove()
|
||||||
|
apiclient := &fakeClient{
|
||||||
|
version: defaultVersion,
|
||||||
|
}
|
||||||
|
if testcase.envOrchestrator != "" {
|
||||||
|
defer patchEnvVariable(t, "DOCKER_ORCHESTRATOR", testcase.envOrchestrator)()
|
||||||
|
}
|
||||||
|
|
||||||
|
cli := &DockerCli{client: apiclient, err: os.Stderr}
|
||||||
|
cliconfig.SetDir(dir.Path())
|
||||||
|
options := flags.NewClientOptions()
|
||||||
|
if testcase.flagOrchestrator != "" {
|
||||||
|
options.Common.Orchestrator = testcase.flagOrchestrator
|
||||||
|
}
|
||||||
|
err := cli.Initialize(options)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, testcase.expectedKubernetes, cli.ClientInfo().HasKubernetes)
|
||||||
|
assert.Equal(t, testcase.expectedOrchestrator, string(cli.ClientInfo().Orchestrator))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetClientWithPassword(t *testing.T) {
|
func TestGetClientWithPassword(t *testing.T) {
|
||||||
expected := "password"
|
expected := "password"
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,11 @@ func normalize(flag string) Orchestrator {
|
||||||
|
|
||||||
// GetOrchestrator checks DOCKER_ORCHESTRATOR environment variable and configuration file
|
// GetOrchestrator checks DOCKER_ORCHESTRATOR environment variable and configuration file
|
||||||
// orchestrator value and returns user defined Orchestrator.
|
// orchestrator value and returns user defined Orchestrator.
|
||||||
func GetOrchestrator(flagValue, value string) Orchestrator {
|
func GetOrchestrator(isExperimental bool, flagValue, value string) Orchestrator {
|
||||||
|
// Non experimental CLI has kubernetes disabled
|
||||||
|
if !isExperimental {
|
||||||
|
return defaultOrchestrator
|
||||||
|
}
|
||||||
// Check flag
|
// Check flag
|
||||||
if o := normalize(flagValue); o != orchestratorUnset {
|
if o := normalize(flagValue); o != orchestratorUnset {
|
||||||
return o
|
return o
|
||||||
|
|
|
@ -19,7 +19,7 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
Args: cli.ExactArgs(1),
|
Args: cli.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
opts.Namespace = args[0]
|
opts.Namespace = args[0]
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,7 +18,7 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
Short: "List stacks",
|
Short: "List stacks",
|
||||||
Args: cli.NoArgs,
|
Args: cli.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -19,7 +19,7 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
Args: cli.ExactArgs(1),
|
Args: cli.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
opts.Namespace = args[0]
|
opts.Namespace = args[0]
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -19,7 +19,7 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
Args: cli.RequiresMinArgs(1),
|
Args: cli.RequiresMinArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
opts.Namespaces = args
|
opts.Namespaces = args
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -19,7 +19,7 @@ func newServicesCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
Args: cli.ExactArgs(1),
|
Args: cli.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
opts.Namespace = args[0]
|
opts.Namespace = args[0]
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
kli, err := kubernetes.WrapCli(dockerCli, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -5,7 +5,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/command"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
@ -33,23 +34,14 @@ func fakeServerVersion(ctx context.Context) (types.Version, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVersionWithDefaultOrchestrator(t *testing.T) {
|
func TestVersionWithOrchestrator(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{serverVersion: fakeServerVersion})
|
cli := test.NewFakeCli(&fakeClient{serverVersion: fakeServerVersion})
|
||||||
|
cli.SetClientInfo(func() command.ClientInfo { return command.ClientInfo{Orchestrator: "swarm"} })
|
||||||
cmd := NewVersionCommand(cli)
|
cmd := NewVersionCommand(cli)
|
||||||
assert.NoError(t, cmd.Execute())
|
assert.NoError(t, cmd.Execute())
|
||||||
assert.Contains(t, cleanTabs(cli.OutBuffer().String()), "Orchestrator: swarm")
|
assert.Contains(t, cleanTabs(cli.OutBuffer().String()), "Orchestrator: swarm")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVersionWithOverridenOrchestrator(t *testing.T) {
|
|
||||||
cli := test.NewFakeCli(&fakeClient{serverVersion: fakeServerVersion})
|
|
||||||
config := configfile.New("configfile")
|
|
||||||
config.Orchestrator = "Kubernetes"
|
|
||||||
cli.SetConfigFile(config)
|
|
||||||
cmd := NewVersionCommand(cli)
|
|
||||||
assert.NoError(t, cmd.Execute())
|
|
||||||
assert.Contains(t, cleanTabs(cli.OutBuffer().String()), "Orchestrator: kubernetes")
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanTabs(line string) string {
|
func cleanTabs(line string) string {
|
||||||
return strings.Join(strings.Fields(line), " ")
|
return strings.Join(strings.Fields(line), " ")
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,24 @@ type versionDetails interface {
|
||||||
Client() client.APIClient
|
Client() client.APIClient
|
||||||
ClientInfo() command.ClientInfo
|
ClientInfo() command.ClientInfo
|
||||||
ServerInfo() command.ServerInfo
|
ServerInfo() command.ServerInfo
|
||||||
ClientInfo() command.ClientInfo
|
}
|
||||||
|
|
||||||
|
func hideFeatureFlag(f *pflag.Flag, hasFeature bool, annotation string) {
|
||||||
|
if hasFeature {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := f.Annotations[annotation]; ok {
|
||||||
|
f.Hidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hideFeatureSubCommand(subcmd *cobra.Command, hasFeature bool, annotation string) {
|
||||||
|
if hasFeature {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := subcmd.Annotations[annotation]; ok {
|
||||||
|
subcmd.Hidden = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) {
|
func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) {
|
||||||
|
@ -206,27 +223,10 @@ func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) {
|
||||||
hasKubernetes := details.ClientInfo().HasKubernetes
|
hasKubernetes := details.ClientInfo().HasKubernetes
|
||||||
|
|
||||||
cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
||||||
// hide experimental flags
|
hideFeatureFlag(f, hasExperimental, "experimental")
|
||||||
if !hasExperimental {
|
hideFeatureFlag(f, hasExperimentalCLI, "experimentalCLI")
|
||||||
if _, ok := f.Annotations["experimental"]; ok {
|
hideFeatureFlag(f, hasKubernetes, "kubernetes")
|
||||||
f.Hidden = true
|
hideFeatureFlag(f, !hasKubernetes, "swarm")
|
||||||
}
|
|
||||||
}
|
|
||||||
if !hasExperimentalCLI {
|
|
||||||
if _, ok := f.Annotations["experimentalCLI"]; ok {
|
|
||||||
f.Hidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !hasKubernetes {
|
|
||||||
if _, ok := f.Annotations["kubernetes"]; ok {
|
|
||||||
f.Hidden = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, ok := f.Annotations["swarm"]; ok {
|
|
||||||
f.Hidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// hide flags not supported by the server
|
// hide flags not supported by the server
|
||||||
if !isOSTypeSupported(f, osType) || !isVersionSupported(f, clientVersion) {
|
if !isOSTypeSupported(f, osType) || !isVersionSupported(f, clientVersion) {
|
||||||
f.Hidden = true
|
f.Hidden = true
|
||||||
|
@ -234,28 +234,10 @@ func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) {
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, subcmd := range cmd.Commands() {
|
for _, subcmd := range cmd.Commands() {
|
||||||
// hide experimental subcommands
|
hideFeatureSubCommand(subcmd, hasExperimental, "experimental")
|
||||||
if !hasExperimental {
|
hideFeatureSubCommand(subcmd, hasExperimentalCLI, "experimentalCLI")
|
||||||
if _, ok := subcmd.Annotations["experimental"]; ok {
|
hideFeatureSubCommand(subcmd, hasKubernetes, "kubernetes")
|
||||||
subcmd.Hidden = true
|
hideFeatureSubCommand(subcmd, !hasKubernetes, "swarm")
|
||||||
}
|
|
||||||
}
|
|
||||||
if !hasExperimentalCLI {
|
|
||||||
if _, ok := subcmd.Annotations["experimentalCLI"]; ok {
|
|
||||||
subcmd.Hidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hasKubernetes {
|
|
||||||
if _, ok := subcmd.Annotations["kubernetes"]; ok {
|
|
||||||
subcmd.Hidden = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, ok := subcmd.Annotations["swarm"]; ok {
|
|
||||||
subcmd.Hidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// hide subcommands not supported by the server
|
// hide subcommands not supported by the server
|
||||||
if subcmdVersion, ok := subcmd.Annotations["version"]; ok && versions.LessThan(clientVersion, subcmdVersion) {
|
if subcmdVersion, ok := subcmd.Annotations["version"]; ok && versions.LessThan(clientVersion, subcmdVersion) {
|
||||||
subcmd.Hidden = true
|
subcmd.Hidden = true
|
||||||
|
@ -279,7 +261,8 @@ func areFlagsSupported(cmd *cobra.Command, details versionDetails) error {
|
||||||
clientVersion := details.Client().ClientVersion()
|
clientVersion := details.Client().ClientVersion()
|
||||||
osType := details.ServerInfo().OSType
|
osType := details.ServerInfo().OSType
|
||||||
hasExperimental := details.ServerInfo().HasExperimental
|
hasExperimental := details.ServerInfo().HasExperimental
|
||||||
hasKubernetes := details.ClientInfo().HasKubernetes()
|
hasKubernetes := details.ClientInfo().HasKubernetes
|
||||||
|
hasExperimentalCLI := details.ClientInfo().HasExperimental
|
||||||
|
|
||||||
errs := []string{}
|
errs := []string{}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type notaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
type notaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
||||||
|
type clientInfoFuncType func() command.ClientInfo
|
||||||
|
|
||||||
// FakeCli emulates the default DockerCli
|
// FakeCli emulates the default DockerCli
|
||||||
type FakeCli struct {
|
type FakeCli struct {
|
||||||
|
@ -26,6 +27,7 @@ type FakeCli struct {
|
||||||
err *bytes.Buffer
|
err *bytes.Buffer
|
||||||
in *command.InStream
|
in *command.InStream
|
||||||
server command.ServerInfo
|
server command.ServerInfo
|
||||||
|
clientInfoFunc clientInfoFuncType
|
||||||
notaryClientFunc notaryClientFuncType
|
notaryClientFunc notaryClientFuncType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +90,19 @@ func (c *FakeCli) ServerInfo() command.ServerInfo {
|
||||||
return c.server
|
return c.server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientInfo returns client information
|
||||||
|
func (c *FakeCli) ClientInfo() command.ClientInfo {
|
||||||
|
if c.clientInfoFunc != nil {
|
||||||
|
return c.clientInfoFunc()
|
||||||
|
}
|
||||||
|
return c.DockerCli.ClientInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClientInfo sets the internal getter for retrieving a ClientInfo
|
||||||
|
func (c *FakeCli) SetClientInfo(clientInfoFunc clientInfoFuncType) {
|
||||||
|
c.clientInfoFunc = clientInfoFunc
|
||||||
|
}
|
||||||
|
|
||||||
// OutBuffer returns the stdout buffer
|
// OutBuffer returns the stdout buffer
|
||||||
func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
||||||
return c.outBuffer
|
return c.outBuffer
|
||||||
|
|
Loading…
Reference in New Issue