github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/util/provider.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package util
    21  
    22  import (
    23  	"context"
    24  	"regexp"
    25  	"strings"
    26  
    27  	corev1 "k8s.io/api/core/v1"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/client-go/kubernetes"
    30  )
    31  
    32  type K8sProvider string
    33  
    34  const (
    35  	EKSProvider     K8sProvider = "EKS"
    36  	GKEProvider     K8sProvider = "GKE"
    37  	AKSProvider     K8sProvider = "AKS"
    38  	ACKProvider     K8sProvider = "ACK"
    39  	TKEProvider     K8sProvider = "TKE"
    40  	UnknownProvider K8sProvider = "unknown"
    41  )
    42  
    43  func (p K8sProvider) IsCloud() bool {
    44  	return p != UnknownProvider
    45  }
    46  
    47  var (
    48  	/*
    49  		EKS version info:
    50  		WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
    51  		Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
    52  		Kustomize Version: v4.5.7
    53  		Server Version: version.Info{Major:"1", Minor:"24+", GitVersion:"v1.24.10-eks-48e63af", GitCommit:"9176fb99b52f8d5ff73d67fea27f3a638f679f8a", GitTreeState:"clean", BuildDate:"2023-01-24T19:17:48Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"linux/amd64"}
    54  		WARNING: version difference between client (1.26) and server (1.24) exceeds the supported minor version skew of +/-1
    55  
    56  		GKE version info:
    57  		WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
    58  		Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
    59  		Kustomize Version: v4.5.7
    60  		Server Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.9-gke.3200", GitCommit:"92ea556d4e7418d0e7b5db1ee576a73f8fc47e91", GitTreeState:"clean", BuildDate:"2023-01-20T09:29:29Z", GoVersion:"go1.18.9b7", Compiler:"gc", Platform:"linux/amd64"}
    61  		WARNING: version difference between client (1.26) and server (1.24) exceeds the supported minor version skew of +/-1
    62  
    63  		ACK version info:
    64  		WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
    65  		Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
    66  		Kustomize Version: v4.5.7
    67  		Server Version: version.Info{Major:"1", Minor:"24+", GitVersion:"v1.24.6-aliyun.1", GitCommit:"e0e067a81f9fa91d46792937d79ec41ec79762eb", GitTreeState:"clean", BuildDate:"2023-02-28T12:15:08Z", GoVersion:"go1.18.6", Compiler:"gc", Platform:"linux/amd64"}
    68  		WARNING: version difference between client (1.26) and server (1.24) exceeds the supported minor version skew of +/-1
    69  
    70  		TKE version info:
    71  		WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
    72  		Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
    73  		Kustomize Version: v4.5.7
    74  		Server Version: version.Info{Major:"1", Minor:"24+", GitVersion:"v1.24.4-tke.5", GitCommit:"c52d4f7343b73cbdf73e5bf0ca82ccdc2d54a07a", GitTreeState:"clean", BuildDate:"2023-02-07T01:40:47Z", GoVersion:"go1.18.8", Compiler:"gc", Platform:"linux/amd64"}
    75  		WARNING: version difference between client (1.26) and server (1.24) exceeds the supported minor version skew of +/-1
    76  	*/
    77  	k8sVersionRegex = map[K8sProvider]string{
    78  		EKSProvider: "v.*-eks-.*",
    79  		GKEProvider: "v.*-gke.*",
    80  		ACKProvider: "v.*-aliyun.*",
    81  		TKEProvider: "v.*-tke.*",
    82  	}
    83  )
    84  
    85  // GetK8sProvider returns the k8s provider
    86  func GetK8sProvider(version string, client kubernetes.Interface) (K8sProvider, error) {
    87  	// get provider from version first
    88  	provider := GetK8sProviderFromVersion(version)
    89  	if provider != UnknownProvider {
    90  		return provider, nil
    91  	}
    92  
    93  	// if provider is unknown, get provider from node
    94  	nodes, err := client.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
    95  	if err != nil {
    96  		return UnknownProvider, err
    97  	}
    98  	return GetK8sProviderFromNodes(nodes), nil
    99  }
   100  
   101  // GetK8sProviderFromNodes get k8s provider from node.spec.providerID
   102  func GetK8sProviderFromNodes(nodes *corev1.NodeList) K8sProvider {
   103  	for _, node := range nodes.Items {
   104  		parts := strings.SplitN(node.Spec.ProviderID, ":", 2)
   105  		if len(parts) != 2 {
   106  			continue
   107  		}
   108  		switch parts[0] {
   109  		case "aws":
   110  			return EKSProvider
   111  		case "azure":
   112  			return AKSProvider
   113  		case "gce":
   114  			return GKEProvider
   115  		case "qcloud":
   116  			return TKEProvider
   117  		}
   118  	}
   119  	return UnknownProvider
   120  }
   121  
   122  // GetK8sProviderFromVersion gets k8s provider from field GitVersion in cluster server version
   123  func GetK8sProviderFromVersion(version string) K8sProvider {
   124  	for provider, reg := range k8sVersionRegex {
   125  		match, err := regexp.Match(reg, []byte(version))
   126  		if err != nil {
   127  			continue
   128  		}
   129  		if match {
   130  			return provider
   131  		}
   132  	}
   133  	return UnknownProvider
   134  }
   135  
   136  func GetK8sSemVer(version string) string {
   137  	removeFirstChart := func(v string) string {
   138  		if len(v) == 0 {
   139  			return v
   140  		}
   141  		if v[0] == 'v' {
   142  			return v[1:]
   143  		}
   144  		return v
   145  	}
   146  
   147  	if len(version) == 0 {
   148  		return version
   149  	}
   150  
   151  	strArr := strings.Split(version, "-")
   152  	if len(strArr) == 0 {
   153  		return ""
   154  	}
   155  	return removeFirstChart(strArr[0])
   156  }