From 80b949bdbaa0a725ed15f1442a7240a22e30fb69 Mon Sep 17 00:00:00 2001 From: Marc Wickenden Date: Wed, 12 Dec 2018 23:26:20 +0000 Subject: [PATCH] Make providers a subcommand of bootstrap --- cmd/kubeletmein/main.go | 10 ++- pkg/do/bootstrap.go | 123 -------------------------------- pkg/do/do.go | 38 ---------- pkg/gke/bootstrap.go | 151 ---------------------------------------- pkg/gke/gke.go | 50 ------------- 5 files changed, 4 insertions(+), 368 deletions(-) delete mode 100644 pkg/do/bootstrap.go delete mode 100644 pkg/do/do.go delete mode 100644 pkg/gke/bootstrap.go delete mode 100644 pkg/gke/gke.go diff --git a/cmd/kubeletmein/main.go b/cmd/kubeletmein/main.go index ad4f53b..8ca70ef 100644 --- a/cmd/kubeletmein/main.go +++ b/cmd/kubeletmein/main.go @@ -19,9 +19,8 @@ import ( "fmt" "os" - "github.com/4armed/kubeletmein/pkg/common" - "github.com/4armed/kubeletmein/pkg/do" - "github.com/4armed/kubeletmein/pkg/gke" + "github.com/4armed/kubeletmein/pkg/bootstrap" + "github.com/4armed/kubeletmein/pkg/generate" "github.com/kubicorn/kubicorn/pkg/logger" "github.com/spf13/cobra" ) @@ -42,9 +41,8 @@ func main() { } func init() { - rootCmd.AddCommand(common.GenerateCmd()) - rootCmd.AddCommand(do.Command()) - rootCmd.AddCommand(gke.Command()) + rootCmd.AddCommand(bootstrap.Command()) + rootCmd.AddCommand(generate.Command()) rootCmd.PersistentFlags().IntVarP(&logger.Level, "verbose", "v", 3, "set log level, use 0 to silence, 4 for debugging") rootCmd.PersistentFlags().BoolVarP(&logger.Color, "color", "C", true, "toggle colorized logs") diff --git a/pkg/do/bootstrap.go b/pkg/do/bootstrap.go deleted file mode 100644 index 45426f4..0000000 --- a/pkg/do/bootstrap.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright © 2018 Marc Wickenden -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package do - -import ( - "fmt" - "io/ioutil" - "net/http" - "os" - - "github.com/4armed/kubeletmein/pkg/config" - "github.com/kubicorn/kubicorn/pkg/logger" - "github.com/spf13/cobra" - yaml "gopkg.in/yaml.v2" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -const ( - metadataIP = "169.254.169.254" -) - -// Metadata stores the Kubernetes-related YAML -type Metadata struct { - CaCert string `yaml:"k8saas_ca_cert"` - KubeletToken string `yaml:"k8saas_bootstrap_token"` -} - -// bootstrapCmd represents the bootstrap command -func bootstrapCmd() *cobra.Command { - m := Metadata{} - config := &config.Config{} - userData := []byte{} - var err error - - cmd := &cobra.Command{ - Use: "bootstrap", - Short: "Write out a bootstrap kubeconfig for the kubelet LoadClientCert function", - RunE: func(cmd *cobra.Command, args []string) error { - - if config.MetadataFile == "" { - logger.Info("fetching kubelet creds from metadata service") - resp, err := http.Get("http://" + metadataIP + "/metadata/v1/user-data") - if err != nil { - panic(err) - } - defer resp.Body.Close() - userData, err = ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - } else { - logger.Info("fetching kubelet creds from file: %v", config.MetadataFile) - userData, err = ioutil.ReadFile(config.MetadataFile) - if err != nil { - return err - } - } - - err = yaml.Unmarshal([]byte(userData), &m) - if err != nil { - return fmt.Errorf("unable to parse YAML from user-data: %v", err) - } - - logger.Info("writing ca cert to: %v", config.CaCertPath) - err = ioutil.WriteFile(config.CaCertPath, []byte(m.CaCert), 0644) - if err != nil { - return fmt.Errorf("unable to write ca cert to file: %v", err) - } - - logger.Info("generating bootstrap-kubeconfig file at: %v", config.BootstrapConfig) - kubeconfigData := clientcmdapi.Config{ - // Define a cluster stanza - Clusters: map[string]*clientcmdapi.Cluster{"local": { - Server: "https://" + os.Getenv("KUBERNETES_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_SERVICE_PORT_HTTPS"), - InsecureSkipTLSVerify: false, - CertificateAuthority: config.CaCertPath, - }}, - // Define auth based on the kubelet client cert retrieved - AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubelet": { - Token: m.KubeletToken, - }}, - // Define a context and set as current - Contexts: map[string]*clientcmdapi.Context{"service-account-context": { - Cluster: "local", - AuthInfo: "kubelet", - }}, - CurrentContext: "service-account-context", - } - - // Marshal to disk - err = clientcmd.WriteToFile(kubeconfigData, config.BootstrapConfig) - if err != nil { - return fmt.Errorf("unable to write bootstrap-kubeconfig file: %v", err) - } - - logger.Info("wrote bootstrap-kubeconfig") - logger.Info("now generate a new node certificate with: kubeletmein do generate") - - return err - }, - } - - cmd.Flags().StringVarP(&config.BootstrapConfig, "bootstrap-kubeconfig", "b", "bootstrap-kubeconfig", "The filename to write the bootstrap kubeconfig to") - cmd.Flags().StringVarP(&config.CaCertPath, "ca-cert", "a", "ca-certificates.crt", "The filename to write the apiserver CA cert to") - cmd.Flags().StringVarP(&config.KubeAPIServer, "server", "s", "", "The k8s api server hostname/IP address. Only needed if skipping discovery.") - cmd.Flags().StringVarP(&config.MetadataFile, "metadata-file", "f", "", "Don't try to parse metadata, load from the specified filename instead.") - - return cmd -} diff --git a/pkg/do/do.go b/pkg/do/do.go deleted file mode 100644 index aec66ab..0000000 --- a/pkg/do/do.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © 2018 Marc Wickenden -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package do - -import ( - "github.com/spf13/cobra" -) - -// Command represents the gke command -func Command() *cobra.Command { - - cmd := &cobra.Command{ - Use: "do", - Short: "Retrieve kubelet creds in Digital Ocean", - Run: func(cmd *cobra.Command, args []string) { - - }, - } - - cmd.AddCommand(bootstrapCmd()) - // cmd.AddCommand(generateCmd()) - - return cmd - -} diff --git a/pkg/gke/bootstrap.go b/pkg/gke/bootstrap.go deleted file mode 100644 index 6f69477..0000000 --- a/pkg/gke/bootstrap.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright © 2018 Marc Wickenden -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package gke - -import ( - "encoding/base64" - "fmt" - "io/ioutil" - "net/http" - - "cloud.google.com/go/compute/metadata" - "github.com/4armed/kubeletmein/pkg/config" - "github.com/kubicorn/kubicorn/pkg/logger" - "github.com/spf13/cobra" - yaml "gopkg.in/yaml.v2" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -// Kubeenv stores the kube-env YAML -type Kubeenv struct { - CaCert string `yaml:"CA_CERT"` - KubeletCert string `yaml:"KUBELET_CERT"` - KubeletKey string `yaml:"KUBELET_KEY"` - KubeMasterName string `yaml:"KUBERNETES_MASTER_NAME"` -} - -// bootstrapCmd represents the bootstrap command -func bootstrapCmd() *cobra.Command { - c := metadata.NewClient(&http.Client{}) - k := Kubeenv{} - config := &config.Config{} - var kubeenv []byte - var err error - - cmd := &cobra.Command{ - Use: "bootstrap", - Short: "Write out a bootstrap kubeconfig for the kubelet LoadClientCert function", - RunE: func(cmd *cobra.Command, args []string) error { - - if config.MetadataFile == "" { - logger.Info("fetching kubelet creds from metadata service") - ke, err := c.InstanceAttributeValue("kube-env") - if err != nil { - return err - } - kubeenv = []byte(ke) - } else { - logger.Info("fetching kubelet creds from file: %v", config.MetadataFile) - kubeenv, err = ioutil.ReadFile(config.MetadataFile) - if err != nil { - return err - } - } - - err = yaml.Unmarshal(kubeenv, &k) - if err != nil { - return fmt.Errorf("unable to parse YAML from kube-env: %v", err) - } - - logger.Debug("decoding ca cert") - caCert, err := base64.StdEncoding.DecodeString(k.CaCert) - if err != nil { - return fmt.Errorf("unable to decode ca cert: %v", err) - } - logger.Info("writing ca cert to: %v", config.CaCertPath) - err = ioutil.WriteFile(config.CaCertPath, caCert, 0644) - if err != nil { - return fmt.Errorf("unable to write ca cert to file: %v", err) - } - - logger.Debug("decoding kubelet cert") - kubeletCert, err := base64.StdEncoding.DecodeString(k.KubeletCert) - if err != nil { - return fmt.Errorf("unable to decode kubelet cert: %v", err) - } - - logger.Info("writing kubelet cert to: %v", config.KubeletCertPath) - err = ioutil.WriteFile(config.KubeletCertPath, kubeletCert, 0644) - if err != nil { - return fmt.Errorf("unable to write kubelet cert to file: %v", err) - } - - logger.Debug("decoding kubelet key") - kubeletKey, err := base64.StdEncoding.DecodeString(k.KubeletKey) - if err != nil { - return fmt.Errorf("unable to decode kubelet key: %v", err) - } - - logger.Info("writing kubelet key to: %v", config.KubeletKeyPath) - err = ioutil.WriteFile(config.KubeletKeyPath, kubeletKey, 0644) - if err != nil { - return fmt.Errorf("unable to write kubelet key to file: %v", err) - } - - logger.Info("generating bootstrap-kubeconfig file at: %v", config.BootstrapConfig) - kubeconfigData := clientcmdapi.Config{ - // Define a cluster stanza - Clusters: map[string]*clientcmdapi.Cluster{"local": { - Server: "https://" + k.KubeMasterName, - InsecureSkipTLSVerify: false, - CertificateAuthority: config.CaCertPath, - }}, - // Define auth based on the kubelet client cert retrieved - AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubelet": { - ClientCertificate: config.KubeletCertPath, - ClientKey: config.KubeletKeyPath, - }}, - // Define a context and set as current - Contexts: map[string]*clientcmdapi.Context{"service-account-context": { - Cluster: "local", - AuthInfo: "kubelet", - }}, - CurrentContext: "service-account-context", - } - - // Marshal to disk - err = clientcmd.WriteToFile(kubeconfigData, config.BootstrapConfig) - if err != nil { - return fmt.Errorf("unable to write bootstrap-kubeconfig file: %v", err) - } - - logger.Info("wrote bootstrap-kubeconfig") - logger.Info("now generate a new node certificate with: kubeletmein gke generate") - - return err - }, - } - - cmd.Flags().StringVarP(&config.BootstrapConfig, "bootstrap-kubeconfig", "b", "bootstrap-kubeconfig", "The filename to write the bootstrap kubeconfig to") - cmd.Flags().StringVarP(&config.CaCertPath, "ca-cert", "a", "ca-certificates.crt", "The filename to write the apiserver CA cert to") - cmd.Flags().StringVarP(&config.KubeletCertPath, "kubelet-cert", "c", "kubelet.crt", "The filename to write the kubelet cert to") - cmd.Flags().StringVarP(&config.KubeletKeyPath, "kubelet-key", "k", "kubelet.key", "The filename to write the kubelet key to") - cmd.Flags().StringVarP(&config.KubeAPIServer, "server", "s", "", "The k8s api server hostname/IP address. Only needed if skipping discovery.") - cmd.Flags().StringVarP(&config.MetadataFile, "metadata-file", "f", "", "Don't try to parse metadata, load from the specified filename instead.") - - return cmd -} diff --git a/pkg/gke/gke.go b/pkg/gke/gke.go deleted file mode 100644 index 901a607..0000000 --- a/pkg/gke/gke.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright © 2018 Marc Wickenden -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package gke - -import ( - "github.com/spf13/cobra" -) - -// Config holds configuration values for GKE operations -type Config struct { - bootstrapConfig string - caCertPath string - kubeletKeyPath string - kubeletCertPath string - kubeConfig string - certDir string - nodeName string - skipDiscovery bool - kubeAPIServer string -} - -// Command represents the gke command -func Command() *cobra.Command { - - cmd := &cobra.Command{ - Use: "gke", - Short: "Retrieve kubelet creds in GKE", - Run: func(cmd *cobra.Command, args []string) { - - }, - } - - cmd.AddCommand(bootstrapCmd()) - - return cmd - -}