github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cloud/iks/clusters.go (about) 1 package iks 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "os/user" 10 "path/filepath" 11 "strings" 12 13 ibmcloud "github.com/IBM-Cloud/bluemix-go" 14 "github.com/IBM-Cloud/bluemix-go/api/container/containerv1" 15 "github.com/IBM-Cloud/bluemix-go/client" 16 "github.com/IBM-Cloud/bluemix-go/helpers" 17 "github.com/IBM-Cloud/bluemix-go/session" 18 "github.com/IBM-Cloud/bluemix-go/trace" 19 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 20 "k8s.io/client-go/kubernetes" 21 "k8s.io/client-go/tools/clientcmd" 22 ) 23 24 type Clusters interface { 25 GetClusterConfig(name string, target containerv1.ClusterTargetHeader) (string, error) 26 } 27 type clusters struct { 28 *client.Client 29 } 30 31 // This name is the name known to cruiser 32 type ClusterConfig struct { 33 ClusterID string `json:"cluster_id"` 34 ClusterName string `json:"cluster_name"` 35 ClusterType string `json:"cluster_type"` 36 ClusterPayTier string `json:"cluster_pay_tier"` 37 Datacenter string `json:"datacenter"` 38 AccountID string `json:"account_id"` 39 Created string `json:"created"` 40 } 41 42 func newClusterAPI(c *client.Client) Clusters { 43 return &clusters{ 44 Client: c, 45 } 46 } 47 48 func ComputeClusterConfigDir(name string) (string, error) { 49 usr, err := user.Current() 50 if err != nil { 51 return "", err 52 } 53 resultDir := filepath.Join(usr.HomeDir, ".bluemix", "plugins", "container-service", "clusters", name) 54 return resultDir, nil 55 } 56 57 func (r *clusters) GetClusterConfig(name string, target containerv1.ClusterTargetHeader) (string, error) { 58 rawURL := fmt.Sprintf("/v1/clusters/%s/config", name) 59 resultDir, err := ComputeClusterConfigDir(name) 60 if err != nil { 61 return "", fmt.Errorf("Error computing directory to download the cluster config") 62 } 63 64 err = os.MkdirAll(resultDir, 0755) 65 if err != nil { 66 return "", fmt.Errorf("Error creating directory to download the cluster config") 67 } 68 downloadPath := filepath.Join(resultDir, "config.zip") 69 trace.Logger.Println("Will download the kubeconfig at", downloadPath) 70 71 var out *os.File 72 if out, err = os.Create(downloadPath); err != nil { 73 return "", err 74 } 75 defer out.Close() //nolint:errcheck 76 defer helpers.RemoveFile(downloadPath) //nolint:errcheck 77 _, err = r.Client.Get(rawURL, out, target.ToMap()) 78 if err != nil { 79 return "", err 80 } 81 trace.Logger.Println("Downloaded the kubeconfig at", downloadPath) 82 if err = helpers.Unzip(downloadPath, resultDir); err != nil { 83 return "", err 84 } 85 defer helpers.RemoveFilesWithPattern(resultDir, "[^(.yml)|(.pem)]$") //nolint:errcheck 86 var kubedir, kubeyml string 87 files, _ := ioutil.ReadDir(resultDir) 88 for _, f := range files { 89 if f.IsDir() && strings.HasPrefix(f.Name(), "kube") { 90 kubedir = filepath.Join(resultDir, f.Name()) 91 files, _ := ioutil.ReadDir(kubedir) 92 for _, f := range files { 93 old := filepath.Join(kubedir, f.Name()) 94 new := filepath.Join(kubedir, "../", f.Name()) 95 if strings.HasSuffix(f.Name(), ".yml") { 96 kubeyml = new 97 } 98 err := os.Rename(old, new) 99 if err != nil { 100 return "", fmt.Errorf("Couldn't rename: %q", err) 101 } 102 } 103 break 104 } 105 } 106 if kubedir == "" { 107 return "", errors.New("Unable to locate kube config in zip archive") 108 } 109 return filepath.Abs(kubeyml) 110 } 111 112 func GetClusterName() (string, error) { 113 config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( 114 clientcmd.NewDefaultClientConfigLoadingRules(), 115 &clientcmd.ConfigOverrides{}, 116 ).ConfigAccess().GetStartingConfig() 117 if err != nil { 118 return "", err 119 } 120 return config.Contexts[config.CurrentContext].Cluster, nil 121 122 } 123 124 func GetClusterID() (string, error) { 125 126 // we can also get this from kubeconfig 127 //token := 128 c := new(ibmcloud.Config) 129 accountID, err := ConfigFromJSON(c) 130 if err != nil { 131 return "", err 132 } 133 134 s, err := session.New(c) 135 if err != nil { 136 return "", err 137 } 138 139 clusterAPI, err := containerv1.New(s) 140 if err != nil { 141 return "", err 142 } 143 144 clusterIF := clusterAPI.Clusters() 145 clusterName, err := GetClusterName() 146 if err != nil { 147 return "", err 148 } 149 150 target := containerv1.ClusterTargetHeader{ 151 Region: c.Region, 152 AccountID: accountID, 153 } 154 155 clusterID, err := clusterIF.Find(clusterName, target) 156 157 if err != nil { 158 return "", err 159 } 160 return clusterID.ID, nil 161 } 162 163 func GetKubeClusterID(kubeClient kubernetes.Interface) (string, error) { 164 165 clusterConfigCM, err := kubeClient.CoreV1().ConfigMaps("kube-system").Get("cluster-info", metav1.GetOptions{}) 166 if err != nil { 167 return "", err 168 } 169 clusterConfig := &ClusterConfig{} 170 err = json.Unmarshal(clusterConfigCM.BinaryData["cluster-config.json"], clusterConfig) 171 return clusterConfig.ClusterID, nil 172 } 173 174 func GetKubeClusterRegion(kubeClient kubernetes.Interface) (string, error) { 175 176 clusterConfigCM, err := kubeClient.CoreV1().ConfigMaps("kube-system").Get("crn-info-ibmc", metav1.GetOptions{}) 177 if err != nil { 178 return "", err 179 } 180 return clusterConfigCM.Data["CRN_REGION"], nil 181 }