mirror of https://github.com/docker/cli.git
Support multiple namespaces for docker stack ls
Signed-off-by: Mathieu Champlon <mathieu.champlon@docker.com>
This commit is contained in:
parent
4d947de292
commit
84241cc393
|
@ -31,9 +31,6 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
newServicesCommand(dockerCli),
|
newServicesCommand(dockerCli),
|
||||||
)
|
)
|
||||||
flags := cmd.PersistentFlags()
|
flags := cmd.PersistentFlags()
|
||||||
flags.String("namespace", "", "Kubernetes namespace to use")
|
|
||||||
flags.SetAnnotation("namespace", "kubernetes", nil)
|
|
||||||
flags.SetAnnotation("namespace", "experimentalCLI", nil)
|
|
||||||
flags.String("kubeconfig", "", "Kubernetes config file")
|
flags.String("kubeconfig", "", "Kubernetes config file")
|
||||||
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
|
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
|
||||||
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)
|
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)
|
||||||
|
|
|
@ -49,5 +49,6 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
`Query the registry to resolve image digest and supported platforms ("`+swarm.ResolveImageAlways+`"|"`+swarm.ResolveImageChanged+`"|"`+swarm.ResolveImageNever+`")`)
|
`Query the registry to resolve image digest and supported platforms ("`+swarm.ResolveImageAlways+`"|"`+swarm.ResolveImageChanged+`"|"`+swarm.ResolveImageNever+`")`)
|
||||||
flags.SetAnnotation("resolve-image", "version", []string{"1.30"})
|
flags.SetAnnotation("resolve-image", "version", []string{"1.30"})
|
||||||
flags.SetAnnotation("resolve-image", "swarm", nil)
|
flags.SetAnnotation("resolve-image", "swarm", nil)
|
||||||
|
kubernetes.AddNamespaceFlag(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,15 @@ func NewOptions(flags *flag.FlagSet) Options {
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddNamespaceFlag adds the namespace flag to the given flag set
|
||||||
|
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
|
// WrapCli wraps command.Cli with kubernetes specifics
|
||||||
func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) {
|
func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) {
|
||||||
var err error
|
|
||||||
cli := &KubeCli{
|
cli := &KubeCli{
|
||||||
Cli: dockerCli,
|
Cli: dockerCli,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
package kubernetes
|
package kubernetes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/docker/cli/cli/command/stack/options"
|
"github.com/docker/cli/cli/command/stack/options"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetStacks lists the kubernetes stacks.
|
// GetStacks lists the kubernetes stacks
|
||||||
func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
func GetStacks(dockerCli command.Cli, opts options.List, kopts Options) ([]*formatter.Stack, error) {
|
||||||
|
kubeCli, err := WrapCli(dockerCli, kopts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if opts.AllNamespaces || len(opts.Namespaces) == 0 {
|
||||||
|
return getStacks(kubeCli, opts)
|
||||||
|
}
|
||||||
|
return getStacksWithNamespaces(kubeCli, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||||
composeClient, err := kubeCli.composeClient()
|
composeClient, err := kubeCli.composeClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -31,3 +43,28 @@ func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error)
|
||||||
}
|
}
|
||||||
return formattedStacks, nil
|
return formattedStacks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStacksWithNamespaces(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
|
||||||
|
stacks := []*formatter.Stack{}
|
||||||
|
for _, namespace := range removeDuplicates(opts.Namespaces) {
|
||||||
|
kubeCli.kubeNamespace = namespace
|
||||||
|
ss, err := getStacks(kubeCli, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stacks = append(stacks, ss...)
|
||||||
|
}
|
||||||
|
return stacks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeDuplicates(namespaces []string) []string {
|
||||||
|
found := make(map[string]bool)
|
||||||
|
results := namespaces[:0]
|
||||||
|
for _, n := range namespaces {
|
||||||
|
if !found[n] {
|
||||||
|
results = append(results, n)
|
||||||
|
found[n] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,10 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
|
flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
|
||||||
flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces")
|
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", "kubernetes", nil)
|
||||||
flags.SetAnnotation("all-namespaces", "experimentalCLI", nil)
|
flags.SetAnnotation("all-namespaces", "experimentalCLI", nil)
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -44,16 +47,16 @@ func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error
|
||||||
stacks = append(stacks, ss...)
|
stacks = append(stacks, ss...)
|
||||||
}
|
}
|
||||||
if dockerCli.ClientInfo().HasKubernetes() {
|
if dockerCli.ClientInfo().HasKubernetes() {
|
||||||
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
|
ss, err := kubernetes.GetStacks(dockerCli, opts, kubernetes.NewOptions(cmd.Flags()))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ss, err := kubernetes.GetStacks(kli, opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stacks = append(stacks, ss...)
|
stacks = append(stacks, ss...)
|
||||||
}
|
}
|
||||||
|
return format(dockerCli, opts, stacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
func format(dockerCli command.Cli, opts options.List, stacks []*formatter.Stack) error {
|
||||||
format := opts.Format
|
format := opts.Format
|
||||||
if format == "" || format == formatter.TableFormatKey {
|
if format == "" || format == formatter.TableFormatKey {
|
||||||
format = formatter.SwarmStackTableFormat
|
format = formatter.SwarmStackTableFormat
|
||||||
|
@ -66,7 +69,9 @@ func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error
|
||||||
Format: formatter.Format(format),
|
Format: formatter.Format(format),
|
||||||
}
|
}
|
||||||
sort.Slice(stacks, func(i, j int) bool {
|
sort.Slice(stacks, func(i, j int) bool {
|
||||||
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name)
|
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name) ||
|
||||||
|
!sortorder.NaturalLess(stacks[j].Name, stacks[i].Name) &&
|
||||||
|
sortorder.NaturalLess(stacks[j].Namespace, stacks[i].Namespace)
|
||||||
})
|
})
|
||||||
return formatter.StackWrite(stackCtx, stacks)
|
return formatter.StackWrite(stackCtx, stacks)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ type Deploy struct {
|
||||||
type List struct {
|
type List struct {
|
||||||
Format string
|
Format string
|
||||||
AllNamespaces bool
|
AllNamespaces bool
|
||||||
|
Namespaces []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PS holds docker stack ps options
|
// PS holds docker stack ps options
|
||||||
|
|
|
@ -40,6 +40,6 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.SetAnnotation("filter", "swarm", nil)
|
flags.SetAnnotation("filter", "swarm", nil)
|
||||||
flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display task IDs")
|
flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display task IDs")
|
||||||
flags.StringVar(&opts.Format, "format", "", "Pretty-print tasks using a Go template")
|
flags.StringVar(&opts.Format, "format", "", "Pretty-print tasks using a Go template")
|
||||||
|
kubernetes.AddNamespaceFlag(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,7 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
flags := cmd.Flags()
|
||||||
|
kubernetes.AddNamespaceFlag(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,6 @@ func newServicesCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.StringVar(&opts.Format, "format", "", "Pretty-print services using a Go template")
|
flags.StringVar(&opts.Format, "format", "", "Pretty-print services using a Go template")
|
||||||
flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided")
|
flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided")
|
||||||
flags.SetAnnotation("filter", "swarm", nil)
|
flags.SetAnnotation("filter", "swarm", nil)
|
||||||
|
kubernetes.AddNamespaceFlag(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue