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  }