-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Better namespace experience with Kubernetes #991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a17f07f to
b03b1c0
Compare
|
@silvin-lubecki looks like there's a linting issue |
|
Yes, I'm on it, thanks @thaJeztah! |
b03b1c0 to
e3fb0c4
Compare
|
PTAL |
e3fb0c4 to
27f8396
Compare
|
Rebased! |
|
@silvin-lubecki what's the easiest way for me to test this ? |
|
@vieux silvin is on holiday, I'm carrying his PRs meanwhile. |
vdemeester
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🐸
|
On non docker-for-desktop, you need to have |
cli/command/stack/kubernetes/cli.go
Outdated
|
|
||
| configNamespace, _, err := clientConfig.Namespace() | ||
| if err != nil { | ||
| return nil, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this code is executed (possibly showing an error) even if the namespace is overridden through opts.Namespace. Retrieving the namespace from the config should probably be done conditional (i.e., if there's no --namespace option set)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll invert the condition below, but the code in here is likely going to change when I address your next comment about --namespace.
cli/command/stack/kubernetes/cli.go
Outdated
| return nil, err | ||
| } | ||
| cli.kubeNamespace = configNamespace | ||
| if opts.Namespace != "default" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- What if
opts.Namespaceis an empty string? (also; I'm not a big fan of magic words, such as"default"for default values) - What if I run
docker stack ls --namespace=default; will the specified ("default") namespace be ignored? (perhapskubernetes.NewOptions()should useflags.Changed()to detect if the flag was set (even if it's with the default value)cli/cli/command/stack/kubernetes/cli.go
Lines 31 to 41 in 854aad8
// NewOptions returns an Options initialized with command line flags func NewOptions(flags *flag.FlagSet) Options { var opts Options if namespace, err := flags.GetString("namespace"); err == nil { opts.Namespace = namespace } if kubeConfig, err := flags.GetString("kubeconfig"); err == nil { opts.Config = kubeConfig } return opts }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running a complete set of (manual) tests with both kubectl get stacks and docker stack ls reveals a few discrepancies. I'll sort that out.
kubernetes/config.go
Outdated
| // NewKubernetesConfig resolves the path to the desired Kubernetes configuration file, depending | ||
| // environment variable and command line flag. | ||
| func NewKubernetesConfig(configFlag string) (*restclient.Config, error) { | ||
| func NewKubernetesConfig(configFlag string) clientcmd.ClientConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not new, but the configFlag variable is a bit confusing (i.e., it's not the flag itself, but a custom path, which happens to be passed through a flag). Perhaps renamed this to (e.g.) configPath
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, changing this.
| func NewKubernetesConfig(configFlag string) (*restclient.Config, error) { | ||
| func NewKubernetesConfig(configFlag string) clientcmd.ClientConfig { | ||
| kubeConfig := configFlag | ||
| if kubeConfig == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exact same code is also in cli.WrapCli() (and looks to be redundant). I suggest extracting this to a function, e.g.
func ConfigPath(kubeconfigPath string) string {
if kubeconfigPath != "" {
return kubeconfigPath
}
if config := os.Getenv("KUBECONFIG"); config != "" {
return config
}
return filepath.Join(homedir.Get(), ".kube/config")
}Is a non-existing path reason for an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well actually WrapCli calls NewKubernetesConfig right after the duplicated code so this looks like the code was moved/factorized and not removed…
Fixed!
| // NewStackFormat returns a format for use with a stack Context | ||
| func NewStackFormat(source string) Format { | ||
| switch source { | ||
| case TableFormatKey: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a change in behaviour; before this change:
docker stack ls --format=table
NAME SERVICES
foobar 1After this change:
docker stack ls --format=table
# (no output)Perhaps remove this function, and in swarm/kubernetes do;
if len(format) == 0 || format == formatter.TableFormatKey {
format = formatter.KubernetesStackTableFormat
}
stackCtx := formatter.Context{
Output: dockerCli.Out(),
Format: formatter.Format(format),
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, fixing this!
cli/command/stack/kubernetes/list.go
Outdated
| return err | ||
| } | ||
| format := opts.Format | ||
| if len(format) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my other comment above
cli/command/stack/swarm/list.go
Outdated
| return err | ||
| } | ||
| format := opts.Format | ||
| if len(format) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my other comment above
| flags := cmd.Flags() | ||
| 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.SetAnnotation("all-namespaces", "kubernetes", nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have to be gated by API-version as well? (possibly not because it was experimental so far)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it was experimental and also targeting only Kubernetes and UCP. The behavior toward the Docker daemon is supposed to not have been changed.
|
|
||
| flags := cmd.Flags() | ||
| 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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if we considered
- using
--namespace=all(e.g.) to show all namespaces (which would be consistent with--orchestrator=all), also allowing listing stack in a single namespace--namespace=<something> - showing all namespaces by default, but use a
--filter namespace=footo limit the output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe what drives the current design is to mimic what kubectl does in order to not confuse Kubernetes users.
|
Oh, this also needs a documentation update to document the |
|
For the record, here is the manual test suite I ran against kubectl, obviously this is highly dependent on the services deployed beforehand… |
|
And here is the matching |
|
@thaJeztah I believe I have addressed all your comments. I added small commits so it remains easy for you to check the changes, but afterwards if you would rather have me collapse them or merge them with the bigger commits from @silvin-lubecki I'll do it. |
thaJeztah
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but if you can combine some of the commits, that'd be good
Signed-off-by: Silvin Lubecki <[email protected]>
Signed-off-by: Silvin Lubecki <[email protected]>
…elongs Signed-off-by: Silvin Lubecki <[email protected]>
…rnetes orchestrator Signed-off-by: Silvin Lubecki <[email protected]>
…rator, to list all stacks in all namespaces. Signed-off-by: Silvin Lubecki <[email protected]>
…alues Signed-off-by: Mathieu Champlon <[email protected]>
a82c9f1 to
2af66be
Compare
|
Done, thanks for your help! |
- What I did
I redesigned a better UX for namespaces with Kubernetes:
~/.kube/configis now used with all stack commandsNAMESPACEcolumn is added fordocker stack lscommand on Kubernetes orchestrator only--all-namespacesflag is added fordocker stack lscommand on Kubernetes orchestrator only- How I did it
NAMESPACEcolumn, I modified the formatter/stack.go:NewStackFormat function, which is now almost no-op. We now have two default format, a Kubernetes one with a NAMESPACE column, and a Swarm one without it, so I let the caller choosing the appropriate default table format. Buy the way now these two default format are exported. A closer look will be appreciated 😄--all-namespacesflag, I patched the Stack client to handle the all-namespaces option on List command. All stack clients are namespaced, but with Kubernetes, setting the namespace to empty string means all namespaces.- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)