github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/test/testutils/utils.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 testutils 21 22 import ( 23 "context" 24 "io" 25 "net/http" 26 "sync" 27 "time" 28 29 corev1 "k8s.io/api/core/v1" 30 apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 31 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 apiruntime "k8s.io/apimachinery/pkg/runtime" 33 "k8s.io/apimachinery/pkg/runtime/schema" 34 "k8s.io/cli-runtime/pkg/genericclioptions" 35 "k8s.io/client-go/dynamic" 36 "k8s.io/client-go/kubernetes/scheme" 37 "k8s.io/client-go/rest" 38 "k8s.io/klog/v2" 39 cmdutil "k8s.io/kubectl/pkg/cmd/util" 40 "sigs.k8s.io/controller-runtime/pkg/client" 41 42 "github.com/1aal/kubeblocks/pkg/configuration/core" 43 viper "github.com/1aal/kubeblocks/pkg/viperx" 44 ) 45 46 const ( 47 K8sCoreAPIVersion = "v1" 48 ResourceConfigmaps = "configmaps" 49 ) 50 51 // Extensions API group 52 const ( 53 ExtensionsAPIGroup = "extensions.kubeblocks.io" 54 ExtensionsAPIVersion = "v1alpha1" 55 ResourceAddons = "addons" 56 ) 57 58 // The purpose of this package is to remove the dependency of the KubeBlocks project on 'pkg/cli'. 59 var ( 60 // KubeBlocksRepoName helm repo name for kubeblocks 61 KubeBlocksRepoName = "kubeblocks" 62 63 // KubeBlocksChartName helm chart name for kubeblocks 64 KubeBlocksChartName = "kubeblocks" 65 66 // KubeBlocksReleaseName helm release name for kubeblocks 67 KubeBlocksReleaseName = "kubeblocks" 68 69 // KubeBlocksChartURL the helm chart repo for installing kubeblocks 70 KubeBlocksChartURL = "https://apecloud.github.io/helm-charts" 71 72 // GitLabHelmChartRepo the helm chart repo in GitLab 73 GitLabHelmChartRepo = "https://jihulab.com/api/v4/projects/85949/packages/helm/stable" 74 75 // CfgKeyHelmRepoURL the helm repo url key 76 CfgKeyHelmRepoURL = "HELM_REPO_URL" 77 ) 78 79 func ConfigmapGVR() schema.GroupVersionResource { 80 return schema.GroupVersionResource{Group: corev1.GroupName, Version: K8sCoreAPIVersion, Resource: ResourceConfigmaps} 81 } 82 83 func AddonGVR() schema.GroupVersionResource { 84 return schema.GroupVersionResource{Group: ExtensionsAPIGroup, Version: ExtensionsAPIVersion, Resource: ResourceAddons} 85 } 86 87 var addToScheme sync.Once 88 89 func NewFactory() cmdutil.Factory { 90 configFlags := NewConfigFlagNoWarnings() 91 // Add CRDs to the scheme. They are missing by default. 92 addToScheme.Do(func() { 93 if err := apiextv1.AddToScheme(scheme.Scheme); err != nil { 94 // This should never happen. 95 panic(err) 96 } 97 }) 98 return cmdutil.NewFactory(configFlags) 99 } 100 101 // NewConfigFlagNoWarnings returns a ConfigFlags that disables warnings. 102 func NewConfigFlagNoWarnings() *genericclioptions.ConfigFlags { 103 configFlags := genericclioptions.NewConfigFlags(true) 104 configFlags.WrapConfigFn = func(c *rest.Config) *rest.Config { 105 c.WarningHandler = rest.NoWarnings{} 106 return c 107 } 108 return configFlags 109 } 110 111 // GetResourceObjectFromGVR queries the resource object using GVR. 112 func GetResourceObjectFromGVR(gvr schema.GroupVersionResource, key client.ObjectKey, client dynamic.Interface, k8sObj interface{}) error { 113 unstructuredObj, err := client. 114 Resource(gvr). 115 Namespace(key.Namespace). 116 Get(context.TODO(), key.Name, metav1.GetOptions{}) 117 if err != nil { 118 return core.WrapError(err, "failed to get resource[%v]", key) 119 } 120 return apiruntime.DefaultUnstructuredConverter.FromUnstructured(unstructuredObj.Object, k8sObj) 121 } 122 123 // GetHelmChartRepoURL gets helm chart repo, chooses one from GitHub and GitLab based on the IP location 124 func GetHelmChartRepoURL() string { 125 126 // if helm repo url is specified by config or environment, use it 127 url := viper.GetString(CfgKeyHelmRepoURL) 128 if url != "" { 129 klog.V(1).Infof("Using helm repo url set by config or environment: %s", url) 130 return url 131 } 132 133 // if helm repo url is not specified, choose one from GitHub and GitLab based on the IP location 134 // if location is CN, or we can not get location, use GitLab helm chart repo 135 repo := KubeBlocksChartURL 136 location, _ := GetIPLocation() 137 if location == "CN" || location == "" { 138 repo = GitLabHelmChartRepo 139 } 140 klog.V(1).Infof("Using helm repo url: %s", repo) 141 return repo 142 } 143 144 func GetIPLocation() (string, error) { 145 client := &http.Client{Timeout: 10 * time.Second} 146 req, err := http.NewRequest("GET", "https://ifconfig.io/country_code", nil) 147 if err != nil { 148 return "", err 149 } 150 resp, err := client.Do(req) 151 if err != nil { 152 return "", err 153 } 154 defer resp.Body.Close() 155 location, err := io.ReadAll(resp.Body) 156 if len(location) == 0 || err != nil { 157 return "", err 158 } 159 160 // remove last "\n" 161 return string(location[:len(location)-1]), nil 162 }