func TestTokenLeavesCert(t *testing.T) { authInfoWithCerts := clientcmdapi.NewAuthInfo() authInfoWithCerts.ClientCertificate = "cert" authInfoWithCerts.ClientCertificateData = []byte("certdata") authInfoWithCerts.ClientKey = "key" authInfoWithCerts.ClientKeyData = []byte("keydata") authInfoWithTokenAndCerts := clientcmdapi.NewAuthInfo() authInfoWithTokenAndCerts.Token = "token" authInfoWithTokenAndCerts.ClientCertificate = "cert" authInfoWithTokenAndCerts.ClientCertificateData = []byte("certdata") authInfoWithTokenAndCerts.ClientKey = "key" authInfoWithTokenAndCerts.ClientKeyData = []byte("keydata") startingConfig := newRedFederalCowHammerConfig() startingConfig.AuthInfos["another-user"] = authInfoWithCerts expectedConfig := newRedFederalCowHammerConfig() expectedConfig.AuthInfos["another-user"] = authInfoWithTokenAndCerts test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagBearerToken + "=token"}, startingConfig: startingConfig, expectedConfig: expectedConfig, } test.run(t) }
// setupKubeconfig reads config from disk, adds the minikube settings, and writes it back. // activeContext is true when minikube is the CurrentContext // If no CurrentContext is set, the given name will be used. func setupKubeconfig(server, certAuth string) error { configFile := constants.KubeconfigPath // read existing config or create new if does not exist config, err := kubeconfig.ReadConfigOrNew(configFile) if err != nil { return err } currentContextName := config.CurrentContext currentContext := config.Contexts[currentContextName] clusterName, err := ocfg.GetClusterNicknameFromURL(server) if err != nil { return err } cluster := cfg.NewCluster() cluster.Server = server cluster.CertificateAuthorityData = []byte(certAuth) config.Clusters[clusterName] = cluster // user userName := "******" + clusterName user := cfg.NewAuthInfo() if currentContext != nil && currentContext.AuthInfo == userName { currentUser := config.AuthInfos[userName] if currentUser != nil { user.Token = config.AuthInfos[userName].Token } } config.AuthInfos[userName] = user // context context := cfg.NewContext() context.Cluster = clusterName context.AuthInfo = userName context.Namespace = api.NamespaceDefault contextName := ocfg.GetContextNickname(api.NamespaceDefault, clusterName, userName) if currentContext != nil && currentContext.Cluster == clusterName && currentContext.AuthInfo == userName { contextName = currentContextName context.Namespace = currentContext.Namespace } config.Contexts[contextName] = context config.CurrentContext = contextName // write back to disk if err := kubeconfig.WriteConfig(config, configFile); err != nil { return err } fmt.Println("oc is now configured to use the cluster.") if len(user.Token) == 0 { fmt.Println("Run this command to use the cluster: ") fmt.Println("oc login --username=admin --password=admin") } return nil }
func TestNewEmptyAuth(t *testing.T) { expectedConfig := *clientcmdapi.NewConfig() expectedConfig.AuthInfos["the-user-name"] = clientcmdapi.NewAuthInfo() test := configCommandTest{ args: []string{"set-credentials", "the-user-name"}, startingConfig: *clientcmdapi.NewConfig(), expectedConfig: expectedConfig, } test.run(t) }
func TestUnsetField(t *testing.T) { expectedConfig := newRedFederalCowHammerConfig() expectedConfig.AuthInfos["red-user"] = clientcmdapi.NewAuthInfo() test := configCommandTest{ args: []string{"unset", "users.red-user.token"}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } test.run(t) }
func TestAdditionalAuth(t *testing.T) { expectedConfig := newRedFederalCowHammerConfig() authInfo := clientcmdapi.NewAuthInfo() authInfo.Token = "token" expectedConfig.AuthInfos["another-user"] = authInfo test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagBearerToken + "=token"}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } test.run(t) }
func TestTokenClearsBasic(t *testing.T) { authInfoWithBasic := clientcmdapi.NewAuthInfo() authInfoWithBasic.Username = "******" authInfoWithBasic.Password = "******" authInfoWithToken := clientcmdapi.NewAuthInfo() authInfoWithToken.Token = "token" startingConfig := newRedFederalCowHammerConfig() startingConfig.AuthInfos["another-user"] = authInfoWithBasic expectedConfig := newRedFederalCowHammerConfig() expectedConfig.AuthInfos["another-user"] = authInfoWithToken test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagBearerToken + "=token"}, startingConfig: startingConfig, expectedConfig: expectedConfig, } test.run(t) }
// CreateConfig takes a clientCfg and builds a config (kubeconfig style) from it. func CreateConfig(namespace string, clientCfg *client.Config) (*clientcmdapi.Config, error) { clusterNick, err := GetClusterNicknameFromConfig(clientCfg) if err != nil { return nil, err } userNick, err := GetUserNicknameFromConfig(clientCfg) if err != nil { return nil, err } contextNick, err := GetContextNicknameFromConfig(namespace, clientCfg) if err != nil { return nil, err } config := clientcmdapi.NewConfig() credentials := clientcmdapi.NewAuthInfo() credentials.Token = clientCfg.BearerToken credentials.ClientCertificate = clientCfg.TLSClientConfig.CertFile if len(credentials.ClientCertificate) == 0 { credentials.ClientCertificateData = clientCfg.TLSClientConfig.CertData } credentials.ClientKey = clientCfg.TLSClientConfig.KeyFile if len(credentials.ClientKey) == 0 { credentials.ClientKeyData = clientCfg.TLSClientConfig.KeyData } config.AuthInfos[userNick] = credentials cluster := clientcmdapi.NewCluster() cluster.Server = clientCfg.Host cluster.CertificateAuthority = clientCfg.CAFile if len(cluster.CertificateAuthority) == 0 { cluster.CertificateAuthorityData = clientCfg.CAData } cluster.InsecureSkipTLSVerify = clientCfg.Insecure if clientCfg.GroupVersion != nil { cluster.APIVersion = clientCfg.GroupVersion.String() } config.Clusters[clusterNick] = cluster context := clientcmdapi.NewContext() context.Cluster = clusterNick context.AuthInfo = userNick context.Namespace = namespace config.Contexts[contextNick] = context config.CurrentContext = contextNick return config, nil }
func TestCertLeavesToken(t *testing.T) { authInfoWithToken := clientcmdapi.NewAuthInfo() authInfoWithToken.Token = "token" authInfoWithTokenAndCerts := clientcmdapi.NewAuthInfo() authInfoWithTokenAndCerts.Token = "token" authInfoWithTokenAndCerts.ClientCertificate = "/cert" authInfoWithTokenAndCerts.ClientKey = "/key" startingConfig := newRedFederalCowHammerConfig() startingConfig.AuthInfos["another-user"] = authInfoWithToken expectedConfig := newRedFederalCowHammerConfig() expectedConfig.AuthInfos["another-user"] = authInfoWithTokenAndCerts test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=/cert", "--" + clientcmd.FlagKeyFile + "=/key"}, startingConfig: startingConfig, expectedConfig: expectedConfig, } test.run(t) }
func TestTokenAndCertAllowed(t *testing.T) { expectedConfig := newRedFederalCowHammerConfig() authInfo := clientcmdapi.NewAuthInfo() authInfo.Token = "token" authInfo.ClientCertificate = "/cert-file" expectedConfig.AuthInfos["another-user"] = authInfo test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=/cert-file", "--" + clientcmd.FlagBearerToken + "=token"}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } test.run(t) }
func TestEmptyTokenAndCertAllowed(t *testing.T) { fakeCertFile, _ := ioutil.TempFile("", "cert-file") expectedConfig := newRedFederalCowHammerConfig() authInfo := clientcmdapi.NewAuthInfo() authInfo.ClientCertificate = path.Base(fakeCertFile.Name()) expectedConfig.AuthInfos["another-user"] = authInfo test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=" + fakeCertFile.Name(), "--" + clientcmd.FlagBearerToken + "="}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } test.run(t) }
func MakeClientConfigWithToken(config *clientcmdapi.Config, clusterName string, userName string, token string) *clientcmdapi.Config { newConfig := config name := fmt.Sprintf("%s@%s", userName, clusterName) authInfo := clientcmdapi.NewAuthInfo() authInfo.Token = token context := clientcmdapi.NewContext() context.Cluster = clusterName context.AuthInfo = userName newConfig.AuthInfos[userName] = authInfo newConfig.Contexts[name] = context newConfig.CurrentContext = name return newConfig }
func MakeClientConfigWithCerts(config *clientcmdapi.Config, clusterName string, userName string, clientKey []byte, clientCert []byte) *clientcmdapi.Config { newConfig := config name := fmt.Sprintf("%s@%s", userName, clusterName) authInfo := clientcmdapi.NewAuthInfo() authInfo.ClientKeyData = clientKey authInfo.ClientCertificateData = clientCert context := clientcmdapi.NewContext() context.Cluster = clusterName context.AuthInfo = userName newConfig.AuthInfos[userName] = authInfo newConfig.Contexts[name] = context newConfig.CurrentContext = name return newConfig }
func TestEmbedClientKey(t *testing.T) { fakeKeyFile, _ := ioutil.TempFile("", "") defer os.Remove(fakeKeyFile.Name()) fakeData := []byte("fake-data") ioutil.WriteFile(fakeKeyFile.Name(), fakeData, 0600) expectedConfig := newRedFederalCowHammerConfig() authInfo := clientcmdapi.NewAuthInfo() authInfo.ClientKeyData = fakeData expectedConfig.AuthInfos["another-user"] = authInfo test := configCommandTest{ args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagKeyFile + "=" + fakeKeyFile.Name(), "--" + clientcmd.FlagEmbedCerts + "=true"}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } test.run(t) }
func updateKubeconfig(config util.AdminConfig, name, endpoint string, entKeyPairs *entityKeyPairs, dryRun bool) error { po := config.PathOptions() kubeconfig, err := po.GetStartingConfig() if err != nil { return err } // Populate API server endpoint info. cluster := clientcmdapi.NewCluster() // Prefix "https" as the URL scheme to endpoint. if !strings.HasPrefix(endpoint, "https://") { endpoint = fmt.Sprintf("https://%s", endpoint) } cluster.Server = endpoint cluster.CertificateAuthorityData = certutil.EncodeCertPEM(entKeyPairs.ca.Cert) // Populate credentials. authInfo := clientcmdapi.NewAuthInfo() authInfo.ClientCertificateData = certutil.EncodeCertPEM(entKeyPairs.admin.Cert) authInfo.ClientKeyData = certutil.EncodePrivateKeyPEM(entKeyPairs.admin.Key) authInfo.Username = AdminCN // Populate context. context := clientcmdapi.NewContext() context.Cluster = name context.AuthInfo = name // Update the config struct with API server endpoint info, // credentials and context. kubeconfig.Clusters[name] = cluster kubeconfig.AuthInfos[name] = authInfo kubeconfig.Contexts[name] = context if !dryRun { // Write the update kubeconfig. if err := clientcmd.ModifyConfig(po, *kubeconfig, true); err != nil { return err } } return nil }
// setupKubeconfig reads config from disk, adds the minikube settings, and writes it back. // activeContext is true when minikube is the CurrentContext // If no CurrentContext is set, the given name will be used. func setupKubeconfig(name, server, certAuth, cliCert, cliKey string) error { configFile := constants.KubeconfigPath // read existing config or create new if does not exist config, err := kubeconfig.ReadConfigOrNew(configFile) if err != nil { return err } clusterName := name cluster := cfg.NewCluster() cluster.Server = server cluster.CertificateAuthority = certAuth config.Clusters[clusterName] = cluster // user userName := name user := cfg.NewAuthInfo() user.ClientCertificate = cliCert user.ClientKey = cliKey config.AuthInfos[userName] = user // context contextName := name context := cfg.NewContext() context.Cluster = clusterName context.AuthInfo = userName config.Contexts[contextName] = context // Always set current context to minikube. config.CurrentContext = contextName // write back to disk if err := kubeconfig.WriteConfig(config, configFile); err != nil { return err } return nil }
// minikubeConfig returns a config that reasonably approximates a localkube cluster func minikubeConfig(config *api.Config) { // cluster clusterName := "minikube" cluster := api.NewCluster() cluster.Server = "https://192.168.99.100:" + strconv.Itoa(constants.APIServerPort) cluster.CertificateAuthority = "/home/tux/.minikube/apiserver.crt" config.Clusters[clusterName] = cluster // user userName := "******" user := api.NewAuthInfo() user.ClientCertificate = "/home/tux/.minikube/apiserver.crt" user.ClientKey = "/home/tux/.minikube/apiserver.key" config.AuthInfos[userName] = user // context contextName := "minikube" context := api.NewContext() context.Cluster = clusterName context.AuthInfo = userName config.Contexts[contextName] = context config.CurrentContext = contextName }
func (o createAuthInfoOptions) run() error { err := o.validate() if err != nil { return err } config, err := o.configAccess.GetStartingConfig() if err != nil { return err } startingStanza, exists := config.AuthInfos[o.name] if !exists { startingStanza = clientcmdapi.NewAuthInfo() } authInfo := o.modifyAuthInfo(*startingStanza) config.AuthInfos[o.name] = &authInfo if err := clientcmd.ModifyConfig(o.configAccess, *config, true); err != nil { return err } return nil }
func init() { err := api.Scheme.AddConversionFuncs( func(in *Cluster, out *api.Cluster, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *api.Cluster, out *Cluster, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *Preferences, out *api.Preferences, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *api.Preferences, out *Preferences, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *AuthInfo, out *api.AuthInfo, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *api.AuthInfo, out *AuthInfo, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *Context, out *api.Context, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *api.Context, out *Context, s conversion.Scope) error { return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) }, func(in *Config, out *api.Config, s conversion.Scope) error { out.CurrentContext = in.CurrentContext if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil { return err } out.Clusters = make(map[string]*api.Cluster) if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil { return err } out.AuthInfos = make(map[string]*api.AuthInfo) if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil { return err } out.Contexts = make(map[string]*api.Context) if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil { return err } out.Extensions = make(map[string]runtime.Object) if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil { return err } return nil }, func(in *api.Config, out *Config, s conversion.Scope) error { out.CurrentContext = in.CurrentContext if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil { return err } out.Clusters = make([]NamedCluster, 0, 0) if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil { return err } out.AuthInfos = make([]NamedAuthInfo, 0, 0) if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil { return err } out.Contexts = make([]NamedContext, 0, 0) if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil { return err } out.Extensions = make([]NamedExtension, 0, 0) if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil { return err } return nil }, func(in *[]NamedCluster, out *map[string]*api.Cluster, s conversion.Scope) error { for _, curr := range *in { newCluster := api.NewCluster() if err := s.Convert(&curr.Cluster, newCluster, 0); err != nil { return err } (*out)[curr.Name] = newCluster } return nil }, func(in *map[string]*api.Cluster, out *[]NamedCluster, s conversion.Scope) error { allKeys := make([]string, 0, len(*in)) for key := range *in { allKeys = append(allKeys, key) } sort.Strings(allKeys) for _, key := range allKeys { newCluster := (*in)[key] oldCluster := &Cluster{} if err := s.Convert(newCluster, oldCluster, 0); err != nil { return err } namedCluster := NamedCluster{key, *oldCluster} *out = append(*out, namedCluster) } return nil }, func(in *[]NamedAuthInfo, out *map[string]*api.AuthInfo, s conversion.Scope) error { for _, curr := range *in { newAuthInfo := api.NewAuthInfo() if err := s.Convert(&curr.AuthInfo, newAuthInfo, 0); err != nil { return err } (*out)[curr.Name] = newAuthInfo } return nil }, func(in *map[string]*api.AuthInfo, out *[]NamedAuthInfo, s conversion.Scope) error { allKeys := make([]string, 0, len(*in)) for key := range *in { allKeys = append(allKeys, key) } sort.Strings(allKeys) for _, key := range allKeys { newAuthInfo := (*in)[key] oldAuthInfo := &AuthInfo{} if err := s.Convert(newAuthInfo, oldAuthInfo, 0); err != nil { return err } namedAuthInfo := NamedAuthInfo{key, *oldAuthInfo} *out = append(*out, namedAuthInfo) } return nil }, func(in *[]NamedContext, out *map[string]*api.Context, s conversion.Scope) error { for _, curr := range *in { newContext := api.NewContext() if err := s.Convert(&curr.Context, newContext, 0); err != nil { return err } (*out)[curr.Name] = newContext } return nil }, func(in *map[string]*api.Context, out *[]NamedContext, s conversion.Scope) error { allKeys := make([]string, 0, len(*in)) for key := range *in { allKeys = append(allKeys, key) } sort.Strings(allKeys) for _, key := range allKeys { newContext := (*in)[key] oldContext := &Context{} if err := s.Convert(newContext, oldContext, 0); err != nil { return err } namedContext := NamedContext{key, *oldContext} *out = append(*out, namedContext) } return nil }, func(in *[]NamedExtension, out *map[string]runtime.Object, s conversion.Scope) error { for _, curr := range *in { var newExtension runtime.Object if err := s.Convert(&curr.Extension, &newExtension, 0); err != nil { return err } (*out)[curr.Name] = newExtension } return nil }, func(in *map[string]runtime.Object, out *[]NamedExtension, s conversion.Scope) error { allKeys := make([]string, 0, len(*in)) for key := range *in { allKeys = append(allKeys, key) } sort.Strings(allKeys) for _, key := range allKeys { newExtension := (*in)[key] oldExtension := &runtime.RawExtension{} if err := s.Convert(newExtension, oldExtension, 0); err != nil { return err } namedExtension := NamedExtension{key, *oldExtension} *out = append(*out, namedExtension) } return nil }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) } }
func modifyConfig(configAccess clientcmd.ConfigAccess, suppliedConfig *clientcmdapi.Config) error { config, err := configAccess.GetStartingConfig() if err != nil { return err } for name, authInfo := range suppliedConfig.AuthInfos { initial, ok := config.AuthInfos[name] if !ok { initial = clientcmdapi.NewAuthInfo() } modifiedAuthInfo := *initial var setToken, setBasic bool if len(authInfo.ClientCertificate) > 0 { modifiedAuthInfo.ClientCertificate = authInfo.ClientCertificate } if len(authInfo.ClientCertificateData) > 0 { modifiedAuthInfo.ClientCertificateData = authInfo.ClientCertificateData } if len(authInfo.ClientKey) > 0 { modifiedAuthInfo.ClientKey = authInfo.ClientKey } if len(authInfo.ClientKeyData) > 0 { modifiedAuthInfo.ClientKeyData = authInfo.ClientKeyData } if len(authInfo.Token) > 0 { modifiedAuthInfo.Token = authInfo.Token setToken = len(modifiedAuthInfo.Token) > 0 } if len(authInfo.Username) > 0 { modifiedAuthInfo.Username = authInfo.Username setBasic = setBasic || len(modifiedAuthInfo.Username) > 0 } if len(authInfo.Password) > 0 { modifiedAuthInfo.Password = authInfo.Password setBasic = setBasic || len(modifiedAuthInfo.Password) > 0 } // If any auth info was set, make sure any other existing auth types are cleared if setToken || setBasic { if !setToken { modifiedAuthInfo.Token = "" } if !setBasic { modifiedAuthInfo.Username = "" modifiedAuthInfo.Password = "" } } config.AuthInfos[name] = &modifiedAuthInfo } for name, cluster := range suppliedConfig.Clusters { initial, ok := config.Clusters[name] if !ok { initial = clientcmdapi.NewCluster() } modifiedCluster := *initial if len(cluster.Server) > 0 { modifiedCluster.Server = cluster.Server } if cluster.InsecureSkipTLSVerify { modifiedCluster.InsecureSkipTLSVerify = cluster.InsecureSkipTLSVerify // Specifying insecure mode clears any certificate authority if modifiedCluster.InsecureSkipTLSVerify { modifiedCluster.CertificateAuthority = "" modifiedCluster.CertificateAuthorityData = nil } } if len(cluster.CertificateAuthorityData) > 0 { modifiedCluster.CertificateAuthorityData = cluster.CertificateAuthorityData modifiedCluster.InsecureSkipTLSVerify = false } if len(cluster.CertificateAuthority) > 0 { modifiedCluster.CertificateAuthority = cluster.CertificateAuthority modifiedCluster.InsecureSkipTLSVerify = false } config.Clusters[name] = &modifiedCluster } for name, context := range suppliedConfig.Contexts { initial, ok := config.Contexts[name] if !ok { initial = clientcmdapi.NewContext() } modifiedContext := *initial if len(context.Cluster) > 0 { modifiedContext.Cluster = context.Cluster } if len(context.AuthInfo) > 0 { modifiedContext.AuthInfo = context.AuthInfo } if len(context.Namespace) > 0 { modifiedContext.Namespace = context.Namespace } config.Contexts[name] = &modifiedContext } if err := clientcmd.ModifyConfig(configAccess, *config, true); err != nil { return err } return nil }