diff --git a/cli/command/formatter/stack.go b/cli/command/formatter/stack.go index 66b876d11b..965eaf60d5 100644 --- a/cli/command/formatter/stack.go +++ b/cli/command/formatter/stack.go @@ -5,10 +5,14 @@ import ( ) const ( - defaultStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}" + // KubernetesStackTableFormat is the default Kubernetes stack format + KubernetesStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}\t{{.Namespace}}" + // SwarmStackTableFormat is the default Swarm stack format + SwarmStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}" stackServicesHeader = "SERVICES" stackOrchestrastorHeader = "ORCHESTRATOR" + stackNamespaceHeader = "NAMESPACE" ) // Stack contains deployed stack information. @@ -17,17 +21,10 @@ type Stack struct { Name string // Services is the number of the services Services int - // Orchestratort is the platform on which the stack is deployed + // Orchestrator is the platform where the stack is deployed Orchestrator string -} - -// NewStackFormat returns a format for use with a stack Context -func NewStackFormat(source string) Format { - switch source { - case TableFormatKey: - return defaultStackTableFormat - } - return Format(source) + // Namespace is the Kubernetes namespace assigned to the stack + Namespace string } // StackWrite writes formatted stacks using the Context @@ -54,6 +51,7 @@ func newStackContext() *stackContext { "Name": nameHeader, "Services": stackServicesHeader, "Orchestrator": stackOrchestrastorHeader, + "Namespace": stackNamespaceHeader, } return &stackCtx } @@ -73,3 +71,7 @@ func (s *stackContext) Services() string { func (s *stackContext) Orchestrator() string { return s.s.Orchestrator } + +func (s *stackContext) Namespace() string { + return s.s.Namespace +} diff --git a/cli/command/formatter/stack_test.go b/cli/command/formatter/stack_test.go index 743be49dfc..27ca17e5a6 100644 --- a/cli/command/formatter/stack_test.go +++ b/cli/command/formatter/stack_test.go @@ -26,14 +26,22 @@ func TestStackContextWrite(t *testing.T) { }, // Table format { - Context{Format: NewStackFormat("table")}, + Context{Format: Format(SwarmStackTableFormat)}, `NAME SERVICES ORCHESTRATOR baz 2 orchestrator1 bar 1 orchestrator2 `, }, + // Kubernetes table format adds Namespace column { - Context{Format: NewStackFormat("table {{.Name}}")}, + Context{Format: Format(KubernetesStackTableFormat)}, + `NAME SERVICES ORCHESTRATOR NAMESPACE +baz 2 orchestrator1 namespace1 +bar 1 orchestrator2 namespace2 +`, + }, + { + Context{Format: Format("table {{.Name}}")}, `NAME baz bar @@ -41,7 +49,7 @@ bar }, // Custom Format { - Context{Format: NewStackFormat("{{.Name}}")}, + Context{Format: Format("{{.Name}}")}, `baz bar `, @@ -49,8 +57,8 @@ bar } stacks := []*Stack{ - {Name: "baz", Services: 2, Orchestrator: "orchestrator1"}, - {Name: "bar", Services: 1, Orchestrator: "orchestrator2"}, + {Name: "baz", Services: 2, Orchestrator: "orchestrator1", Namespace: "namespace1"}, + {Name: "bar", Services: 1, Orchestrator: "orchestrator2", Namespace: "namespace2"}, } for _, testcase := range cases { out := bytes.NewBufferString("") diff --git a/cli/command/stack/kubernetes/convert.go b/cli/command/stack/kubernetes/convert.go index fbddacc4e8..aa63daf276 100644 --- a/cli/command/stack/kubernetes/convert.go +++ b/cli/command/stack/kubernetes/convert.go @@ -37,6 +37,7 @@ func stackFromV1beta1(in *v1beta1.Stack) (stack, error) { } return stack{ name: in.ObjectMeta.Name, + namespace: in.ObjectMeta.Namespace, composeFile: in.Spec.ComposeFile, spec: fromComposeConfig(ioutil.Discard, cfg), }, nil @@ -55,8 +56,9 @@ func stackToV1beta1(s stack) *v1beta1.Stack { func stackFromV1beta2(in *v1beta2.Stack) stack { return stack{ - name: in.ObjectMeta.Name, - spec: in.Spec, + name: in.ObjectMeta.Name, + namespace: in.ObjectMeta.Namespace, + spec: in.Spec, } } diff --git a/cli/command/stack/kubernetes/list.go b/cli/command/stack/kubernetes/list.go index 915fb8b925..7ad125518a 100644 --- a/cli/command/stack/kubernetes/list.go +++ b/cli/command/stack/kubernetes/list.go @@ -16,12 +16,12 @@ func RunList(dockerCli *KubeCli, opts options.List) error { return err } format := opts.Format - if len(format) == 0 { - format = formatter.TableFormatKey + if format == "" || format == formatter.TableFormatKey { + format = formatter.KubernetesStackTableFormat } stackCtx := formatter.Context{ Output: dockerCli.Out(), - Format: formatter.NewStackFormat(format), + Format: formatter.Format(format), } sort.Sort(byName(stacks)) return formatter.StackWrite(stackCtx, stacks) @@ -51,6 +51,7 @@ func getStacks(kubeCli *KubeCli) ([]*formatter.Stack, error) { Name: stack.name, Services: len(stack.getServices()), Orchestrator: "Kubernetes", + Namespace: stack.namespace, }) } return formattedStacks, nil diff --git a/cli/command/stack/kubernetes/stack.go b/cli/command/stack/kubernetes/stack.go index 76cf07aa20..dedae3707f 100644 --- a/cli/command/stack/kubernetes/stack.go +++ b/cli/command/stack/kubernetes/stack.go @@ -15,6 +15,7 @@ import ( // stack is the main type used by stack commands so they remain independent from kubernetes compose component version. type stack struct { name string + namespace string composeFile string spec *v1beta2.StackSpec } diff --git a/cli/command/stack/swarm/list.go b/cli/command/stack/swarm/list.go index c9fcc8ffc5..b80e4ab8c5 100644 --- a/cli/command/stack/swarm/list.go +++ b/cli/command/stack/swarm/list.go @@ -24,12 +24,12 @@ func RunList(dockerCli command.Cli, opts options.List) error { return err } format := opts.Format - if len(format) == 0 { - format = formatter.TableFormatKey + if format == "" || format == formatter.TableFormatKey { + format = formatter.SwarmStackTableFormat } stackCtx := formatter.Context{ Output: dockerCli.Out(), - Format: formatter.NewStackFormat(format), + Format: formatter.Format(format), } sort.Sort(byName(stacks)) return formatter.StackWrite(stackCtx, stacks) diff --git a/docs/reference/commandline/stack_ls.md b/docs/reference/commandline/stack_ls.md index 7205bc8acb..6613577e64 100644 --- a/docs/reference/commandline/stack_ls.md +++ b/docs/reference/commandline/stack_ls.md @@ -55,6 +55,7 @@ Valid placeholders for the Go template are listed below: | `.Name` | Stack name | | `.Services` | Number of services | | `.Orchestrator` | Orchestrator name | +| `.Namespace` | Namespace | When using the `--format` option, the `stack ls` command either outputs the data exactly as the template declares or, when using the