github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/install/kubeconfig.go (about) 1 package install 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "fmt" 7 "html/template" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 12 "github.com/apprenda/kismatic/pkg/util" 13 ) 14 15 const kubeconfigFilename = "kubeconfig" 16 const dashboardAdminKubeconfigFilename = "dashboard-admin-kubeconfig" 17 18 // ConfigOptions sds 19 type ConfigOptions struct { 20 CA string 21 Server string 22 Cluster string 23 User string 24 Context string 25 Cert string 26 Key string 27 Token string 28 } 29 30 var kubeconfigTemplate = `apiVersion: v1 31 clusters: 32 - cluster: 33 certificate-authority-data: {{.CA}} 34 server: {{.Server}} 35 name: {{.Cluster}} 36 contexts: 37 - context: 38 cluster: {{.Cluster}} 39 user: {{.User}} 40 name: {{.Context}} 41 current-context: {{.Context}} 42 kind: Config 43 preferences: {} 44 users: 45 - name: {{.User}} 46 user: 47 client-certificate-data: {{.Cert}} 48 client-key-data: {{.Key}} 49 token: {{.Token}} 50 ` 51 52 // GenerateKubeconfig generate a kubeconfig file for a specific user 53 func GenerateKubeconfig(p *Plan, generatedAssetsDir string) error { 54 user := "admin" 55 server := "https://" + p.Master.LoadBalancedFQDN + ":6443" 56 cluster := p.Cluster.Name 57 context := p.Cluster.Name + "-" + user 58 59 certsDir := filepath.Join(generatedAssetsDir, "keys") 60 61 // Base64 encoded ca 62 caEncoded, err := util.Base64String(filepath.Join(certsDir, "ca.pem")) 63 if err != nil { 64 return fmt.Errorf("error reading ca file for kubeconfig: %v", err) 65 } 66 // Base64 encoded cert 67 certEncoded, err := util.Base64String(filepath.Join(certsDir, user+".pem")) 68 if err != nil { 69 return fmt.Errorf("error reading certificate file for kubeconfig: %v", err) 70 } 71 // Base64 encoded key 72 keyEncoded, err := util.Base64String(filepath.Join(certsDir, user+"-key.pem")) 73 if err != nil { 74 return fmt.Errorf("error reading certificate key file for kubeconfig: %v", err) 75 } 76 77 configOptions := ConfigOptions{caEncoded, server, cluster, user, context, certEncoded, keyEncoded, ""} 78 79 return writeTemplate(configOptions, filepath.Join(generatedAssetsDir, kubeconfigFilename)) 80 } 81 82 func GenerateDashboardAdminKubeconfig(base64token string, p *Plan, generatedAssetsDir string) error { 83 user := "admin" 84 server := "https://" + p.Master.LoadBalancedFQDN + ":6443" 85 cluster := p.Cluster.Name 86 context := p.Cluster.Name + "-" + "dashboard-admin" 87 88 certsDir := filepath.Join(generatedAssetsDir, "keys") 89 90 // Base64 encoded ca 91 caEncoded, err := util.Base64String(filepath.Join(certsDir, "ca.pem")) 92 if err != nil { 93 return fmt.Errorf("error reading ca file for kubeconfig: %v", err) 94 } 95 96 token, err := base64.StdEncoding.DecodeString(base64token) 97 if err != nil { 98 return fmt.Errorf("error decoding token: %v", err) 99 } 100 configOptions := ConfigOptions{caEncoded, server, cluster, user, context, "", "", string(token)} 101 102 return writeTemplate(configOptions, filepath.Join(generatedAssetsDir, dashboardAdminKubeconfigFilename)) 103 } 104 105 func writeTemplate(conf ConfigOptions, file string) error { 106 // Process template file 107 tmpl, err := template.New("kubeconfig").Parse(kubeconfigTemplate) 108 if err != nil { 109 return fmt.Errorf("error reading config template: %v", err) 110 } 111 112 var kubeconfig bytes.Buffer 113 err = tmpl.Execute(&kubeconfig, conf) 114 if err != nil { 115 return fmt.Errorf("error processing config template: %v", err) 116 } 117 // Write config file 118 err = ioutil.WriteFile(file, kubeconfig.Bytes(), 0644) 119 if err != nil { 120 return fmt.Errorf("error writing kubeconfig file: %v", err) 121 } 122 return nil 123 } 124 125 // RegenerateKubeconfig backs up the old kubeconfig file if it exists. Returns 126 // true if the new kubeconfig file is different than the previous one. 127 // Otherwise returns false. 128 func RegenerateKubeconfig(p *Plan, generatedAssetsDir string) (bool, error) { 129 kubeconfigFile := filepath.Join(generatedAssetsDir, kubeconfigFilename) 130 kubeconfigBackup := filepath.Join(generatedAssetsDir, kubeconfigFilename) + ".bak" 131 132 err := os.Rename(kubeconfigFile, kubeconfigBackup) 133 if os.IsNotExist(err) { 134 // Nothing else to do as the old kubeconfig does not exist 135 return false, GenerateKubeconfig(p, generatedAssetsDir) 136 } 137 if err != nil { 138 return false, fmt.Errorf("error backing up existing kubeconfig file: %v", err) 139 } 140 141 if err := GenerateKubeconfig(p, generatedAssetsDir); err != nil { 142 return false, err 143 } 144 145 // Check if the new kubeconfig is different than the previous one 146 old, err := ioutil.ReadFile(kubeconfigBackup) 147 if err != nil { 148 return false, fmt.Errorf("error reading file %q: %v", kubeconfigBackup, err) 149 } 150 new, err := ioutil.ReadFile(kubeconfigFile) 151 if err != nil { 152 return false, fmt.Errorf("error reading file %q: %v", kubeconfigFile, err) 153 } 154 if bytes.Equal(old, new) { 155 os.Remove(kubeconfigBackup) 156 return false, nil 157 } 158 159 return true, nil 160 }