github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/playground/util.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 playground 21 22 import ( 23 "encoding/json" 24 "fmt" 25 "io" 26 "os" 27 "path/filepath" 28 "strings" 29 30 "github.com/pkg/errors" 31 "k8s.io/cli-runtime/pkg/genericclioptions" 32 "k8s.io/client-go/dynamic" 33 "k8s.io/client-go/kubernetes" 34 35 cp "github.com/1aal/kubeblocks/pkg/cli/cloudprovider" 36 "github.com/1aal/kubeblocks/pkg/cli/spinner" 37 "github.com/1aal/kubeblocks/pkg/cli/util" 38 "github.com/1aal/kubeblocks/version" 39 ) 40 41 func playgroundDir() (string, error) { 42 cliPath, err := util.GetCliHomeDir() 43 if err != nil { 44 return "", err 45 } 46 return filepath.Join(cliPath, "playground"), nil 47 } 48 49 // cloudProviderRepoDir cloud provider repo directory 50 func cloudProviderRepoDir(v string) (string, error) { 51 dir, err := playgroundDir() 52 if err != nil { 53 return "", err 54 } 55 if v == "" { 56 v = version.Version 57 } 58 major := strings.Split(v, "-")[0] 59 cpDir := cp.GitRepoName 60 if major != "" { 61 cpDir = fmt.Sprintf("%s-%s", cp.GitRepoName, major) 62 } 63 return filepath.Join(dir, cpDir), err 64 } 65 66 func initPlaygroundDir() (string, error) { 67 dir, err := playgroundDir() 68 if err != nil { 69 return "", err 70 } 71 72 if _, err = os.Stat(dir); err != nil && os.IsNotExist(err) { 73 err = os.MkdirAll(dir, 0750) 74 } 75 return dir, err 76 } 77 78 // writeClusterInfo writes the cluster info to a state file 79 func writeClusterInfo(path string, info *cp.K8sClusterInfo) error { 80 f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640) 81 if err != nil { 82 return err 83 } 84 defer f.Close() 85 86 if err = json.NewEncoder(f).Encode(info); err != nil { 87 // if we fail to write the state file, we should remove it 88 if e := os.Remove(path); e != nil { 89 return errors.Wrap(err, e.Error()) 90 } 91 return err 92 } 93 return nil 94 } 95 96 func removeStateFile(path string) error { 97 _, err := os.Stat(path) 98 if err == nil { 99 return os.Remove(path) 100 } 101 if os.IsNotExist(err) { 102 return nil 103 } 104 return err 105 } 106 107 // readClusterInfoFromFile reads the kubernetes cluster info from a state file 108 func readClusterInfoFromFile(path string) (*cp.K8sClusterInfo, error) { 109 f, err := os.Open(path) 110 if err != nil { 111 if os.IsNotExist(err) { 112 return nil, nil 113 } 114 return nil, err 115 } 116 defer f.Close() 117 118 var info cp.K8sClusterInfo 119 if err = json.NewDecoder(f).Decode(&info); err != nil { 120 return nil, err 121 } 122 return &info, nil 123 } 124 125 func writeAndUseKubeConfig(kubeConfig string, kubeConfigPath string, out io.Writer) error { 126 s := spinner.New(out, spinnerMsg("Write kubeconfig to "+kubeConfigPath)) 127 defer s.Fail() 128 if err := kubeConfigWrite(kubeConfig, kubeConfigPath, writeKubeConfigOptions{ 129 UpdateExisting: true, 130 UpdateCurrentContext: true, 131 OverwriteExisting: true}); err != nil { 132 return err 133 } 134 135 // use the new kubeconfig file 136 if err := util.SetKubeConfig(kubeConfigPath); err != nil { 137 return err 138 } 139 140 s.Success() 141 return nil 142 } 143 144 // getKubeClient returns a kubernetes dynamic client and check if the cluster is reachable 145 func getKubeClient() (kubernetes.Interface, dynamic.Interface, error) { 146 f := util.NewFactory() 147 client, err := f.KubernetesClientSet() 148 errMsg := kubeClusterUnreachableErr.Error() 149 if errors.Is(err, genericclioptions.ErrEmptyConfig) { 150 return nil, nil, kubeClusterUnreachableErr 151 } 152 if err != nil { 153 return nil, nil, errors.Wrap(err, errMsg) 154 } 155 156 if _, err = client.ServerVersion(); err != nil { 157 return nil, nil, errors.Wrap(err, errMsg) 158 } 159 160 dynamic, err := f.DynamicClient() 161 if err != nil { 162 return nil, nil, errors.Wrap(err, errMsg) 163 } 164 return client, dynamic, nil 165 }