prevent ctx-switching from failing on server err
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
+ "net/url"
kapi "k8s.io/kubernetes/pkg/api"
kapierrors "k8s.io/kubernetes/pkg/api/errors"
@@ -104,10 +105,33 @@ func (o *ProjectOptions) Complete(f *clientcmd.Factory, args []string, out io.Wr
}
o.ClientConfig, err = f.ClientConfig()
+ if err != nil {
+ contextNameExists := false
+ if _, exists := o.GetContextFromName(o.ProjectName); exists {
+ contextNameExists = exists
+ }
+
+ if _, isURLError := err.(*url.Error); !(isURLError || kapierrors.IsInternalError(err)) || !contextNameExists {
+ return err
+ }
+
+ // if the argument for o.ProjectName passed by the user is a context name,
+ // prevent local context-switching from failing due to an unreachable
+ // server or an unfetchable ClientConfig.
+ o.Config.CurrentContext = o.ProjectName
+ if err := kclientcmd.ModifyConfig(o.PathOptions, o.Config, true); err != nil {
+ return err
+ }
+
+ // since we failed to retrieve ClientConfig for the current server,
+ // fetch local OpenShift client config
+ o.ClientConfig, err = f.OpenShiftClientConfig().ClientConfig()
if err != nil {
return err
}
+ }
+
o.ClientFn = func() (*client.Client, kclientset.Interface, error) {
oc, kc, err := f.Clients()
return oc, kc, err
@@ -183,12 +207,11 @@ func (o ProjectOptions) RunProject() error {
// Check if argument is an existing context, if so just set it as the context in use.
// If not a context then we will try to handle it as a project.
- if context, contextExists := config.Contexts[argument]; !o.ProjectOnly && contextExists {
+ if context, contextExists := o.GetContextFromName(argument); contextExists {
contextInUse = argument
namespaceInUse = context.Namespace
config.CurrentContext = argument
-
} else {
if !o.SkipAccessValidation {
client, kubeclient, err := o.ClientFn()
@@ -281,6 +304,15 @@ func (o ProjectOptions) RunProject() error {
return nil
}
+// returns a context by the given contextName and a boolean true if the context exists
+func (o *ProjectOptions) GetContextFromName(contextName string) (*clientcmdapi.Context, bool) {
+ if context, contextExists := o.Config.Contexts[contextName]; !o.ProjectOnly && contextExists {
+ return context, true
+ }
+
+ return nil, false
+}
+
func confirmProjectAccess(currentProject string, oClient *client.Client, kClient kclientset.Interface) error {
_, projectErr := oClient.Projects().Get(currentProject)
if !kapierrors.IsNotFound(projectErr) && !kapierrors.IsForbidden(projectErr) {
