package certs import ( "errors" "fmt" "io/ioutil" "os" "path/filepath" "github.com/golang/glog" "github.com/spf13/cobra" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api" ) type CreateKubeConfigOptions struct { APIServerURL string PublicAPIServerURL string APIServerCAFile string ServerNick string CertFile string KeyFile string UserNick string KubeConfigFile string } func NewCommandCreateKubeConfig() *cobra.Command { options := &CreateKubeConfigOptions{} cmd := &cobra.Command{ Use: "create-kubeconfig", Short: "Create a basic .kubeconfig file from client certs", Long: ` Create's a .kubeconfig file at <--kubeconfig> that looks like this: clusters: - cluster: certificate-authority-data: <contents of --certificate-authority> server: <--master> name: <--cluster> - cluster: certificate-authority-data: <contents of --certificate-authority> server: <--public-master> name: public-<--cluster> contexts: - context: cluster: <--cluster> user: <--user> name: <--cluster> current-context: <--cluster> kind: Config users: - name: <--user> user: client-certificate-data: <contents of --client-certificate> client-key-data: <contents of --client-key> `, Run: func(c *cobra.Command, args []string) { if err := options.Validate(args); err != nil { fmt.Println(err.Error()) c.Help() return } if _, err := options.CreateKubeConfig(); err != nil { glog.Fatal(err) } }, } flags := cmd.Flags() flags.StringVar(&options.APIServerURL, "master", "https://localhost:8443", "The API server's URL.") flags.StringVar(&options.PublicAPIServerURL, "public-master", "", "The API public facing server's URL (if applicable).") flags.StringVar(&options.APIServerCAFile, "certificate-authority", "openshift.local.certificates/ca/cert.crt", "Path to the API server's CA file.") flags.StringVar(&options.ServerNick, "cluster", "master", "Nick name for this server in .kubeconfig.") flags.StringVar(&options.CertFile, "client-certificate", "openshift.local.certificates/admin/cert.crt", "The client cert file.") flags.StringVar(&options.KeyFile, "client-key", "openshift.local.certificates/admin/key.key", "The client key file.") flags.StringVar(&options.UserNick, "user", "user", "Nick name for this user in .kubeconfig.") flags.StringVar(&options.KubeConfigFile, "kubeconfig", ".kubeconfig", "Path for the resulting .kubeconfig file.") return cmd } func (o CreateKubeConfigOptions) Validate(args []string) error { if len(args) != 0 { return errors.New("no arguments are supported") } if len(o.KubeConfigFile) == 0 { return errors.New("kubeconfig must be provided") } if len(o.ServerNick) == 0 { return errors.New("cluster must be provided") } if len(o.UserNick) == 0 { return errors.New("user-nick must be provided") } return nil } func (o CreateKubeConfigOptions) CreateKubeConfig() (*clientcmdapi.Config, error) { glog.V(2).Infof("creating a .kubeconfig with: %#v", o) 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 } credentials := make(map[string]clientcmdapi.AuthInfo) credentials[o.UserNick] = clientcmdapi.AuthInfo{ ClientCertificateData: certData, ClientKeyData: keyData, } clusters := make(map[string]clientcmdapi.Cluster) clusters[o.ServerNick] = clientcmdapi.Cluster{ Server: o.APIServerURL, CertificateAuthorityData: caData, } contexts := make(map[string]clientcmdapi.Context) contexts[o.ServerNick] = clientcmdapi.Context{Cluster: o.ServerNick, AuthInfo: o.UserNick} createPublic := len(o.PublicAPIServerURL) > 0 if createPublic { publicNick := "public-" + o.ServerNick clusters[publicNick] = clientcmdapi.Cluster{ Server: o.PublicAPIServerURL, CertificateAuthorityData: caData, } contexts[publicNick] = clientcmdapi.Context{Cluster: o.ServerNick, AuthInfo: o.UserNick} } kubeConfig := &clientcmdapi.Config{ Clusters: clusters, AuthInfos: credentials, Contexts: contexts, CurrentContext: o.ServerNick, } // 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 }