// 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 }
// RunProjects lists all projects a user belongs to func (o ProjectsOptions) RunProjects() error { config := o.Config clientCfg := o.ClientConfig out := o.Out var currentProject string currentContext := config.Contexts[config.CurrentContext] if currentContext != nil { currentProject = currentContext.Namespace } var currentProjectExists bool var currentProjectErr error client := o.Client if len(currentProject) > 0 { if _, currentProjectErr := client.Projects().Get(currentProject); currentProjectErr == nil { currentProjectExists = true } } var defaultContextName string if currentContext != nil { defaultContextName = cliconfig.GetContextNickname(currentContext.Namespace, currentContext.Cluster, currentContext.AuthInfo) } var msg string projects, err := getProjects(client) if err == nil { switch len(projects) { case 0: msg += "You are not a member of any projects. You can request a project to be created with the 'new-project' command." case 1: if o.DisplayShort { msg += fmt.Sprintf("%s", api.DisplayNameAndNameForProject(&projects[0])) } else { msg += fmt.Sprintf("You have one project on this server: %q.", api.DisplayNameAndNameForProject(&projects[0])) } default: asterisk := "" count := 0 if !o.DisplayShort { msg += fmt.Sprintf("You have access to the following projects and can switch between them with '%s project <projectname>':\n", o.CommandName) } sort.Sort(SortByProjectName(projects)) for _, project := range projects { count = count + 1 displayName := project.Annotations["openshift.io/display-name"] linebreak := "\n" if len(displayName) == 0 { displayName = project.Annotations["displayName"] } if currentProjectExists && !o.DisplayShort { asterisk = " " if currentProject == project.Name { asterisk = " * " } } if len(displayName) > 0 && displayName != project.Name && !o.DisplayShort { msg += fmt.Sprintf("\n"+asterisk+"%s - %s", project.Name, displayName) } else { if o.DisplayShort && count == 1 { linebreak = "" } msg += fmt.Sprintf(linebreak+asterisk+"%s", project.Name) } } } fmt.Println(msg) if len(projects) > 0 && !o.DisplayShort { if !currentProjectExists { if clientcmd.IsForbidden(currentProjectErr) { fmt.Printf("You do not have rights to view project %q. Please switch to an existing one.\n", currentProject) } return currentProjectErr } // if they specified a project name and got a generated context, then only show the information they care about. They won't recognize // a context name they didn't choose if config.CurrentContext == defaultContextName { fmt.Fprintf(out, "\nUsing project %q on server %q.\n", currentProject, clientCfg.Host) } else { fmt.Fprintf(out, "\nUsing project %q from context named %q on server %q.\n", currentProject, config.CurrentContext, clientCfg.Host) } } return nil } return err }
// RunProject contains all the necessary functionality for the OpenShift cli project command func (o ProjectOptions) RunProject() error { config := o.Config clientCfg := o.ClientConfig out := o.Out // No argument provided, we will just print info if len(o.ProjectName) == 0 { currentContext := config.Contexts[config.CurrentContext] currentProject := currentContext.Namespace if len(currentProject) > 0 { if o.DisplayShort { fmt.Fprintln(out, currentProject) return nil } _, err := o.Client.Projects().Get(currentProject) if err != nil { if kapierrors.IsNotFound(err) { return fmt.Errorf("the project %q specified in your config does not exist.", currentProject) } if clientcmd.IsForbidden(err) { return fmt.Errorf("you do not have rights to view project %q.", currentProject) } return err } defaultContextName := cliconfig.GetContextNickname(currentContext.Namespace, currentContext.Cluster, currentContext.AuthInfo) // if they specified a project name and got a generated context, then only show the information they care about. They won't recognize // a context name they didn't choose if config.CurrentContext == defaultContextName { fmt.Fprintf(out, "Using project %q on server %q.\n", currentProject, clientCfg.Host) } else { fmt.Fprintf(out, "Using project %q from context named %q on server %q.\n", currentProject, config.CurrentContext, clientCfg.Host) } } else { if o.DisplayShort { return fmt.Errorf("no project has been set") } fmt.Fprintf(out, "No project has been set. Pass a project name to make that the default.\n") } return nil } // We have an argument that can be either a context or project argument := o.ProjectName contextInUse := "" namespaceInUse := "" // 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 { contextInUse = argument namespaceInUse = context.Namespace config.CurrentContext = argument } else { if !o.SkipAccessValidation { _, err := o.Client.Projects().Get(argument) if err != nil { if isNotFound, isForbidden := kapierrors.IsNotFound(err), clientcmd.IsForbidden(err); isNotFound || isForbidden { var msg string if isForbidden { msg = fmt.Sprintf("You are not a member of project %q.", argument) } else { msg = fmt.Sprintf("A project named %q does not exist on %q.", argument, clientCfg.Host) } projects, err := getProjects(o.Client) if err == nil { switch len(projects) { case 0: msg += "\nYou are not a member of any projects. You can request a project to be created with the 'new-project' command." case 1: msg += fmt.Sprintf("\nYou have one project on this server: %s", api.DisplayNameAndNameForProject(&projects[0])) default: msg += "\nYour projects are:" for _, project := range projects { msg += fmt.Sprintf("\n* %s", api.DisplayNameAndNameForProject(&project)) } } } if hasMultipleServers(config) { msg += "\nTo see projects on another server, pass '--server=<server>'." } return errors.New(msg) } return err } } projectName := argument kubeconfig, err := cliconfig.CreateConfig(projectName, o.ClientConfig) if err != nil { return err } merged, err := cliconfig.MergeConfig(config, *kubeconfig) if err != nil { return err } config = *merged namespaceInUse = projectName contextInUse = merged.CurrentContext } if err := kubecmdconfig.ModifyConfig(o.PathOptions, config, true); err != nil { return err } if o.DisplayShort { fmt.Fprintln(out, namespaceInUse) return nil } // calculate what name we'd generate for the context. If the context has the same name, don't drop it into the output, because the user won't // recognize the name since they didn't choose it. defaultContextName := cliconfig.GetContextNickname(namespaceInUse, config.Contexts[contextInUse].Cluster, config.Contexts[contextInUse].AuthInfo) switch { // if there is no namespace, then the only information we can provide is the context and server case (len(namespaceInUse) == 0): fmt.Fprintf(out, "Now using context named %q on server %q.\n", contextInUse, clientCfg.Host) // if they specified a project name and got a generated context, then only show the information they care about. They won't recognize // a context name they didn't choose case (argument == namespaceInUse) && (contextInUse == defaultContextName): fmt.Fprintf(out, "Now using project %q on server %q.\n", namespaceInUse, clientCfg.Host) // in all other cases, display all information default: fmt.Fprintf(out, "Now using project %q from context named %q on server %q.\n", namespaceInUse, contextInUse, clientCfg.Host) } return nil }
func (o CreateKubeConfigOptions) CreateKubeConfig() (*clientcmdapi.Config, error) { glog.V(4).Infof("creating a .kubeconfig with: %#v", o) // read all the referenced filenames caData, err := ioutil.ReadFile(o.APIServerCAFile) if err != nil { return nil, err } certData, err := ioutil.ReadFile(o.CertFile) if err != nil { return nil, err } keyData, err := ioutil.ReadFile(o.KeyFile) if err != nil { return nil, err } certConfig, err := crypto.GetTLSCertificateConfig(o.CertFile, o.KeyFile) if err != nil { return nil, err } // determine all the nicknames clusterNick, err := cliconfig.GetClusterNicknameFromURL(o.APIServerURL) if err != nil { return nil, err } userNick, err := cliconfig.GetUserNicknameFromCert(clusterNick, certConfig.Certs...) if err != nil { return nil, err } contextNick, err := cliconfig.GetContextNickname(o.ContextNamespace, clusterNick, userNick) if err != nil { return nil, err } credentials := make(map[string]clientcmdapi.AuthInfo) credentials[userNick] = clientcmdapi.AuthInfo{ ClientCertificateData: certData, ClientKeyData: keyData, } clusters := make(map[string]clientcmdapi.Cluster) clusters[clusterNick] = clientcmdapi.Cluster{ Server: o.APIServerURL, CertificateAuthorityData: caData, } contexts := make(map[string]clientcmdapi.Context) contexts[contextNick] = clientcmdapi.Context{Cluster: clusterNick, AuthInfo: userNick, Namespace: o.ContextNamespace} createPublic := (len(o.PublicAPIServerURL) > 0) && o.APIServerURL != o.PublicAPIServerURL if createPublic { publicClusterNick, err := cliconfig.GetClusterNicknameFromURL(o.PublicAPIServerURL) if err != nil { return nil, err } publicContextNick, err := cliconfig.GetContextNickname(o.ContextNamespace, publicClusterNick, userNick) if err != nil { return nil, err } clusters[publicClusterNick] = clientcmdapi.Cluster{ Server: o.PublicAPIServerURL, CertificateAuthorityData: caData, } contexts[publicContextNick] = clientcmdapi.Context{Cluster: publicClusterNick, AuthInfo: userNick, Namespace: o.ContextNamespace} } kubeConfig := &clientcmdapi.Config{ Clusters: clusters, AuthInfos: credentials, Contexts: contexts, CurrentContext: contextNick, } glog.V(3).Infof("Generating '%s' API client config as %s\n", userNick, o.KubeConfigFile) // Ensure the parent dir exists if err := os.MkdirAll(filepath.Dir(o.KubeConfigFile), os.FileMode(0755)); err != nil { return nil, err } if err := clientcmd.WriteToFile(*kubeConfig, o.KubeConfigFile); err != nil { return nil, err } return kubeConfig, nil }