Skip to content

Commit 539654c

Browse files
committed
Support multiple namespaces for docker stack ls
Signed-off-by: Mathieu Champlon <[email protected]>
1 parent 3bfe848 commit 539654c

File tree

8 files changed

+62
-18
lines changed

8 files changed

+62
-18
lines changed

‎cli/command/stack/cmd.go‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command {
3131
newServicesCommand(dockerCli),
3232
)
3333
flags := cmd.PersistentFlags()
34-
flags.String("namespace", "", "Kubernetes namespace to use")
35-
flags.SetAnnotation("namespace", "kubernetes", nil)
36-
flags.SetAnnotation("namespace", "experimentalCLI", nil)
3734
flags.String("kubeconfig", "", "Kubernetes config file")
3835
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
3936
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)

‎cli/command/stack/deploy.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
4949
`Query the registry to resolve image digest and supported platforms ("`+swarm.ResolveImageAlways+`"|"`+swarm.ResolveImageChanged+`"|"`+swarm.ResolveImageNever+`")`)
5050
flags.SetAnnotation("resolve-image", "version", []string{"1.30"})
5151
flags.SetAnnotation("resolve-image", "swarm", nil)
52+
kubernetes.AddNamespaceFlag(flags)
5253
return cmd
5354
}

‎cli/command/stack/kubernetes/cli.go‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ func NewOptions(flags *flag.FlagSet) Options {
3434
return opts
3535
}
3636

37+
// AddNamespaceFlag adds the namespace flag to the given flag set
38+
func AddNamespaceFlag(flags *flag.FlagSet) {
39+
flags.String("namespace", "", "Kubernetes namespace to use")
40+
flags.SetAnnotation("namespace", "kubernetes", nil)
41+
flags.SetAnnotation("namespace", "experimentalCLI", nil)
42+
}
43+
3744
// WrapCli wraps command.Cli with kubernetes specifics
3845
func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) {
39-
var err error
4046
cli := &KubeCli{
4147
Cli: dockerCli,
4248
}

‎cli/command/stack/list.go‎

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
2828

2929
flags := cmd.Flags()
3030
flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
31+
flags.StringSliceVar(&opts.Namespaces, "namespace", []string{}, "Kubernetes namespaces to use")
32+
flags.SetAnnotation("namespace", "kubernetes", nil)
33+
flags.SetAnnotation("namespace", "experimentalCLI", nil)
3134
flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces")
3235
flags.SetAnnotation("all-namespaces", "kubernetes", nil)
3336
flags.SetAnnotation("all-namespaces", "experimentalCLI", nil)
@@ -44,18 +47,26 @@ func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error
4447
stacks = append(stacks, ss...)
4548
}
4649
if dockerCli.ClientInfo().HasKubernetes() {
47-
if dockerCli.ClientInfo().HasAll() && !cmd.Flags().Changed("namespace") {
48-
opts.AllNamespaces = true
50+
kopts := kubernetes.NewOptions(cmd.Flags())
51+
if opts.AllNamespaces || len(opts.Namespaces) == 0 {
52+
if dockerCli.ClientInfo().HasAll() {
53+
opts.AllNamespaces = true
54+
}
55+
ss, err := getStacks(dockerCli, opts, kopts)
56+
if err != nil {
57+
return err
58+
}
59+
stacks = append(stacks, ss...)
60+
} else {
61+
for _, nm := range removeDuplicates(opts.Namespaces) {
62+
kopts.Namespace = nm
63+
ss, err := getStacks(dockerCli, opts, kopts)
64+
if err != nil {
65+
return err
66+
}
67+
stacks = append(stacks, ss...)
68+
}
4969
}
50-
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
51-
if err != nil {
52-
return err
53-
}
54-
ss, err := kubernetes.GetStacks(kli, opts)
55-
if err != nil {
56-
return err
57-
}
58-
stacks = append(stacks, ss...)
5970
}
6071
format := opts.Format
6172
if format == "" || format == formatter.TableFormatKey {
@@ -69,7 +80,33 @@ func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error
6980
Format: formatter.Format(format),
7081
}
7182
sort.Slice(stacks, func(i, j int) bool {
72-
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name)
83+
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name) ||
84+
!sortorder.NaturalLess(stacks[j].Name, stacks[i].Name) &&
85+
sortorder.NaturalLess(stacks[j].Namespace, stacks[i].Namespace)
7386
})
7487
return formatter.StackWrite(stackCtx, stacks)
7588
}
89+
90+
func getStacks(dockerCli command.Cli, opts options.List, kopts kubernetes.Options) ([]*formatter.Stack, error) {
91+
kli, err := kubernetes.WrapCli(dockerCli, kopts)
92+
if err != nil {
93+
return nil, err
94+
}
95+
ss, err := kubernetes.GetStacks(kli, opts)
96+
if err != nil {
97+
return nil, err
98+
}
99+
return ss, nil
100+
}
101+
102+
func removeDuplicates(namespaces []string) []string {
103+
mnms := map[string]struct{}{}
104+
for _, nm := range namespaces {
105+
mnms[nm] = struct{}{}
106+
}
107+
namespaces = []string{}
108+
for nm := range mnms {
109+
namespaces = append(namespaces, nm)
110+
}
111+
return namespaces
112+
}

‎cli/command/stack/options/opts.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Deploy struct {
1616
type List struct {
1717
Format string
1818
AllNamespaces bool
19+
Namespaces []string
1920
}
2021

2122
// PS holds docker stack ps options

‎cli/command/stack/ps.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
4040
flags.SetAnnotation("filter", "swarm", nil)
4141
flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display task IDs")
4242
flags.StringVar(&opts.Format, "format", "", "Pretty-print tasks using a Go template")
43-
43+
kubernetes.AddNamespaceFlag(flags)
4444
return cmd
4545
}

‎cli/command/stack/remove.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,7 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
3333
}
3434
},
3535
}
36+
flags := cmd.Flags()
37+
kubernetes.AddNamespaceFlag(flags)
3638
return cmd
3739
}

‎cli/command/stack/services.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ func newServicesCommand(dockerCli command.Cli) *cobra.Command {
3838
flags.StringVar(&opts.Format, "format", "", "Pretty-print services using a Go template")
3939
flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided")
4040
flags.SetAnnotation("filter", "swarm", nil)
41-
41+
kubernetes.AddNamespaceFlag(flags)
4242
return cmd
4343
}

0 commit comments

Comments
 (0)