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
[WIP] Raise error if the user has multiple contexts but no current set #94905
Conversation
Hi @oz123. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
looks sane to me. Just wondering why the title is WIP? Still more progress to made related to this RFE? @oz123 |
@dougsland well, it's WIP, because I think there is still some work to do.
I am OK if it's merged like this, but I'm not sure it will be accepted. |
I agree we might useful to add a test here.
I can't merge patches but let me try to dig here and help moving this one forward. |
/remove-sig api-machinery |
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.
just double checked, this is the correct repo to send the PR, my bad. The client-go is a mirror.
@ahmetb @corneliusweig @soltysh might help here. |
@douglasland thanks 😊 you beat me to respond. I was trying to comment on this. |
It's not an option to break |
b8ed01e
to
aa74aaa
Compare
The current behavior is to ignore this and try to connect to localhost:8080. [This is quite confusing, as reported in this issue][1]. This commit improves the UX by telling the users they need to explicitly choose a context in the that multiple context exist: ``` $ kubectl get pods error: Multiple contexts found. However, no current-context is set in the configuration ``` [1]: kubernetes/kubectl#936
To enable this sub command, it was necessary to propagate the error further up the calling chain for inspection. All the subcommands of config, can now look at the error and decide whether the can continue or not. As the only command that should still work is "use-context" they all stop with error if a context is not set. But this was not enough, since the config is also read while doing the actual write, it was needed to check for the actually command which was running. Hence, the signature of `ModifyConfig` and `writeCurrentContext` was updated. If the use-context subcommand is called the last argument is set to `true`, this signals that it's OK to ignore the error `NoConextSet` and continue the execution. This set of changes displays the error: ``` error: Multiple contexts found. However, no current-context is set in the configuration ``` If running, for example, `kubectl get pods`, but it still allows one to `get-contexts` and `use-context` quickly from the command line to fix the probelm. Demo: ``` $ ./kubectl get pods error: Multiple contexts found. However, no current-context is set in the configuration $ ./kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE coldsweet microk8s-cluster admin-microk8s coldsweet devops devops-calico admin devops-cilium devops-cilium admin-cilium microk8s-context microk8s-cluster admin-microk8s $ ./kubectl config use-context devops Switched to context "devops". ./kubectl get pods NAME READY STATUS RESTARTS AGE nginx-blue-9cf945578-6gsmz 1/1 Running 0 20d nginx-green-df5fcc8d5-xk7ww 1/1 Running 0 20d ```
aa74aaa
to
3c6fe02
Compare
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.
Your change has led to some fundamental changes. I think it's better to iterate on it via an issue than a PR to avoid wasting time. The go-to person for these questions are @.soltysh or @.seans3.
ErrNoContext = errors.New("no context chosen") | ||
ErrEmptyConfig = NewEmptyConfigError("no configuration has been provided, try setting KUBERNETES_MASTER environment variable") | ||
ErrNoContext = errors.New("no context chosen") | ||
ErrNoContextSet = errors.New("Multiple contexts found. However, no current-context is set in the configuration") |
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.
ErrNoContextSet = errors.New("Multiple contexts found. However, no current-context is set in the configuration") | |
ErrNoContextSet = errors.New("multiple contexts found, but no current-context is set") |
Go errors should not be sentences, because it reads better if they are chained. Therefore also start in lower case.
if err != nil { | ||
if errors.Is(err, ErrNoContextSet) { | ||
return &rawConfig, err | ||
} | ||
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.
if err != nil { | |
if errors.Is(err, ErrNoContextSet) { | |
return &rawConfig, err | |
} | |
return nil, err | |
} | |
if err != nil && !errors.Is(err, ErrNoContextSet) { | |
return nil, err | |
} |
@@ -244,6 +244,9 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) { | |||
mergo.MergeWithOverwrite(config, mapConfig) | |||
mergo.MergeWithOverwrite(config, nonMapConfig) | |||
|
|||
if (len(config.Contexts) > 1 && config.CurrentContext == "") { |
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.
if (len(config.Contexts) > 1 && config.CurrentContext == "") { | |
if len(config.Contexts) > 0 && config.CurrentContext == "" { |
This seems to be the wrong place to add this logic though. The loader
s responsibility is to load stuff, not validate that the loaded file satisfies some invariants. This forced you into making a lot more error assertions/exception to compensate for this premature check.
I think the better place is to add it in ClientConfigLoadingRules
if rules.ResolvePaths() { |
@@ -164,7 +167,7 @@ func NewDefaultPathOptions() *PathOptions { | |||
// (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference, | |||
// that means that this code will only write into a single file. If you want to relativizePaths, you must provide a fully qualified path in any | |||
// modified element. | |||
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error { | |||
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool, isSetContext bool) 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.
I'm not sure why the isSetContext
parameter was introduced. I'd assume you can remove it and the logic works just fine.
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 changing external API in a library we provide, you can't do that b/c you're breaking all the existing users.
|
||
err != nil { | ||
if isSetContext && errors.Is(err, ErrNoContextSet) { | ||
|
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.
empty if blocks are unidiomatic in Go. Try to refactor.
if err != nil { | ||
return err | ||
if isSetContext && errors.Is(err, ErrNoContextSet) { |
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.
You need to be careful with errors.Is()
. It returns true if at least one of the reported errors is the respective instance. However, please think about what should happen, if multiple errors are returned in the aggregate.
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.
My intent here was to keep the old behavior. Other errors should be reported as before. I added isSetContext
, so one can still use set-context
. I tried explaining this in the commit message.
Without this, the check I added caused an error on all the commands.
I will need some time to think of an alternative without isSetContext
.
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.
Maybe I missed some detail why this is necessary. However, my main point is to discuss this change in an issue before investing more time into the implementation. It's possible that there is a reason for the current behavior that I don't know.
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 understand that the change should be discussed in an issue first. This is why I created one and initially sent a very minimal patch.
Can the discussion for this issue happen on the original issue I opened in the kubectl repository or should I open a new issue in this repository?
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 rest of the comments from Cornelius still hold.
@@ -164,7 +167,7 @@ func NewDefaultPathOptions() *PathOptions { | |||
// (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference, | |||
// that means that this code will only write into a single file. If you want to relativizePaths, you must provide a fully qualified path in any | |||
// modified element. | |||
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error { | |||
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool, isSetContext bool) 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.
This is changing external API in a library we provide, you can't do that b/c you're breaking all the existing users.
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: oz123 The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Stale issues rot after 30d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-contributor-experience at kubernetes/community. |
Rotten issues close after 30d of inactivity. Send feedback to sig-contributor-experience at kubernetes/community. |
@oz123: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@fejta-bot: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
The current behavior is to ignore this and try to connect to
localhost:8080
.This is quite confusing, as reported in this issue.
This commit improves the UX by telling the users they need to explicitly choose a context, if there are multiple contexts:
What type of PR is this?
/kind bug
What this PR does / why we need it:
This is an attept to improve a confusing error message. Please see the issue linked.
Which issue(s) this PR fixes:
Fixes kubernetes/kubectl#936
Special notes for your reviewer:
I am aware that this PR is still missing test cases. However, I'm publishing this to solicit feedback, and I do not expect this to be merged at this state for the reasons explained below.
With the current patch, if you have not set a context, you see a clear error message. However, you can now only use an editor to fix the issue. That is because this patch disables the ability to use
kubeconfig config set-context
.Users who are a bit familiar with the shell can circumvent the problem:
IMHO, this would be a better interface to exclude the
config
sub-command from producing this error. There are two possible solutions I could think of:kubernetes/vendor/k8s.io/kubectl/pkg/cmd
.I haven't implemented any yet. It's quite obvious that both approaches make the PR significantly larger. The latter approach makes even larger than the former approach.
Maybe there is another way I have not thought of or not aware of?
I would be happy to get some feedback.
In any case, once I know which approach is preferred I will add the required changes and include tests.
Does this PR introduce a user-facing change?: