Skip to content

Commit 2855dc9

Browse files
committed
oc login: Implement --context flag
The flag can be used to tell oc what context name to use when updating kubeconfig. If a matching context already exists, it is replaced altogether, including the linked cluster and authInfo. This means that the configured cluster and authInfo names are also reused.
1 parent 4df0e94 commit 2855dc9

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

pkg/cli/login/login.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ var (
4444
# Log in to the given server with the given credentials (will not prompt interactively)
4545
oc login localhost:8443 --username=myuser --password=mypass
4646
47+
# Log in to the given server as myuser and use a custom kubeconfig context name.
48+
oc login localhost:8443 --username=myuser --context=local
49+
4750
# Log in to the given server through a browser
4851
oc login localhost:8443 --web --callback-port 8280
4952
@@ -162,6 +165,7 @@ func (o *LoginOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []s
162165
o.Token = kcmdutil.GetFlagString(cmd, "token")
163166

164167
o.DefaultNamespace, _, _ = f.ToRawKubeConfigLoader().Namespace()
168+
o.Context = kcmdutil.GetFlagString(cmd, "context")
165169

166170
o.PathOptions = kclientcmd.NewDefaultPathOptions()
167171
// we need to set explicit path if one was specified, since NewDefaultPathOptions doesn't do it for us

pkg/cli/login/loginoptions.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type LoginOptions struct {
7575
StartingKubeConfig *kclientcmdapi.Config
7676
DefaultNamespace string
7777
Config *restclient.Config
78+
Context string
7879

7980
// cert data to be used when authenticating
8081
CertFile string
@@ -570,7 +571,7 @@ func (o *LoginOptions) SaveConfig() (bool, error) {
570571
return false, err
571572
}
572573

573-
configToWrite, err := cliconfig.MergeConfig(*o.StartingKubeConfig, *newConfig)
574+
configToWrite, err := o.mergeConfig(*newConfig)
574575
if err != nil {
575576
return false, err
576577
}
@@ -593,6 +594,46 @@ func (o *LoginOptions) SaveConfig() (bool, error) {
593594
return created, nil
594595
}
595596

597+
// mergeConfig merges StartingKubeConfig with additionalConfig,
598+
// which must contain just a single context, cluster and authInfo.
599+
func (o *LoginOptions) mergeConfig(additionalConfig kclientcmdapi.Config) (*kclientcmdapi.Config, error) {
600+
if o.Context == "" {
601+
return cliconfig.MergeConfig(*o.StartingKubeConfig, additionalConfig)
602+
}
603+
604+
// Set the custom context name in additionalConfig. This needs to happen in any case.
605+
var newContext *kclientcmdapi.Context
606+
for _, v := range additionalConfig.Contexts {
607+
newContext = v
608+
additionalConfig.Contexts = map[string]*kclientcmdapi.Context{
609+
o.Context: v,
610+
}
611+
}
612+
if newContext == nil {
613+
panic(errors.New("no context found in additionalConfig"))
614+
}
615+
616+
// If there is a matching context, replace the linked cluster and authInfo.
617+
existingContext, ok := o.StartingKubeConfig.Contexts[o.Context]
618+
if ok {
619+
for _, v := range additionalConfig.Clusters {
620+
additionalConfig.Clusters = map[string]*kclientcmdapi.Cluster{
621+
existingContext.Cluster: v,
622+
}
623+
newContext.Cluster = existingContext.Cluster
624+
}
625+
for _, v := range additionalConfig.AuthInfos {
626+
additionalConfig.AuthInfos = map[string]*kclientcmdapi.AuthInfo{
627+
existingContext.AuthInfo: v,
628+
}
629+
newContext.AuthInfo = existingContext.AuthInfo
630+
}
631+
}
632+
633+
additionalConfig.CurrentContext = o.Context
634+
return cliconfig.MergeConfig(*o.StartingKubeConfig, additionalConfig)
635+
}
636+
596637
func (o *LoginOptions) whoAmI(clientConfig *restclient.Config) (*userv1.User, error) {
597638
if o.whoAmIFunc != nil {
598639
return o.whoAmIFunc(clientConfig)

0 commit comments

Comments
 (0)