From ac3eaf290248c19d877c6e55e0c172bd0834ed64 Mon Sep 17 00:00:00 2001 From: huiwq1990 Date: Thu, 9 Jun 2022 00:05:35 +0800 Subject: [PATCH] support yurtadm token subcommand Signed-off-by: huiwq1990 --- go.mod | 1 + go.sum | 4 +- pkg/yurtadm/cmd/cmd.go | 2 + pkg/yurtadm/cmd/token/token.go | 129 +++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 pkg/yurtadm/cmd/token/token.go diff --git a/go.mod b/go.mod index 2cfdca64bef..4fb796093b3 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/BurntSushi/toml v0.4.1 // indirect + github.com/Masterminds/semver/v3 v3.1.1 github.com/Microsoft/go-winio v0.4.15 github.com/aliyun/alibaba-cloud-sdk-go v1.61.579 github.com/daviddengcn/go-colortext v1.0.0 diff --git a/go.sum b/go.sum index cb4cc9cc255..d60bc3822d2 100644 --- a/go.sum +++ b/go.sum @@ -65,6 +65,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc= github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -1229,4 +1231,4 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZa sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= \ No newline at end of file +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/yurtadm/cmd/cmd.go b/pkg/yurtadm/cmd/cmd.go index 009fd99856c..2d1628ccab1 100644 --- a/pkg/yurtadm/cmd/cmd.go +++ b/pkg/yurtadm/cmd/cmd.go @@ -28,6 +28,7 @@ import ( "github.com/openyurtio/openyurt/pkg/projectinfo" "github.com/openyurtio/openyurt/pkg/yurtadm/cmd/join" "github.com/openyurtio/openyurt/pkg/yurtadm/cmd/reset" + "github.com/openyurtio/openyurt/pkg/yurtadm/cmd/token" "github.com/openyurtio/openyurt/pkg/yurtadm/cmd/yurtinit" ) @@ -46,6 +47,7 @@ func NewYurtadmCommand() *cobra.Command { cmds.AddCommand(yurtinit.NewCmdInit()) cmds.AddCommand(join.NewCmdJoin(os.Stdout, nil)) cmds.AddCommand(reset.NewCmdReset(os.Stdin, os.Stdout, nil)) + cmds.AddCommand(token.NewCmdToken(os.Stdin, os.Stdout, os.Stderr)) klog.InitFlags(nil) // goflag.Parse() diff --git a/pkg/yurtadm/cmd/token/token.go b/pkg/yurtadm/cmd/token/token.go new file mode 100644 index 00000000000..a6eb1f3d4fe --- /dev/null +++ b/pkg/yurtadm/cmd/token/token.go @@ -0,0 +1,129 @@ +/* +Copyright 2022 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package token + +import ( + "encoding/json" + "fmt" + "io" + "os" + "os/exec" + "runtime" + + "github.com/Masterminds/semver/v3" + "github.com/spf13/cobra" + "k8s.io/klog/v2" + + "github.com/openyurtio/openyurt/pkg/yurtadm/constants" + "github.com/openyurtio/openyurt/pkg/yurtadm/util" + "github.com/openyurtio/openyurt/pkg/yurtadm/util/edgenode" +) + +const ( + TmpDownloadDir = "/tmp" + + KubeadmUrlFormat = "https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubeadm" + DefaultKubeadmVersion = "v1.22.3" + + MiniumKubeadmVersion = "v1.22.3" +) + +func NewCmdToken(in io.Reader, out io.Writer, outErr io.Writer) *cobra.Command { + + cmd := &cobra.Command{ + Use: "token", + Short: "Run this command in order to manage openyurt joint token", + FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, + RunE: func(cmd *cobra.Command, args []string) error { + + if err := CheckAndInstallKubeadm(); err != nil { + return err + } + + klog.V(2).InfoS("kubeadm command exec", "args", os.Args[1:]) + + kubeadmCmd := exec.Command("kubeadm", os.Args[1:]...) + kubeadmCmd.Stdout = out + kubeadmCmd.Stderr = outErr + if err := kubeadmCmd.Run(); err != nil { + return err + } + return nil + }, + } + + return cmd +} + +type kubeadmVersion struct { + ClientVersion clientVersion `json:"clientVersion"` +} +type clientVersion struct { + GitVersion string `json:"gitVersion"` +} + +func CheckAndInstallKubeadm() error { + klog.V(2).Infof("Check and install kubeadm") + kubeadmExist := false + + if _, err := exec.LookPath("kubeadm"); err == nil { + if b, err := exec.Command("kubeadm", "version", "-o", "json").CombinedOutput(); err == nil { + klog.V(2).InfoS("kubeadm", "version", string(b)) + info := kubeadmVersion{} + if err := json.Unmarshal(b, &info); err != nil { + return fmt.Errorf("Can't get the existing kubeadm version: %w", err) + } + kubeadmVersion := info.ClientVersion.GitVersion + + c, err := semver.NewConstraint(fmt.Sprintf(">= %s", MiniumKubeadmVersion)) + if err != nil { + return fmt.Errorf("kubeadm version constraint build fail, err: %s", err.Error()) + } + v, err := semver.NewVersion(kubeadmVersion) + if err != nil { + return fmt.Errorf("current kubeadm version build fail, err: %s", err.Error()) + } + + if c.Check(v) { + klog.V(2).Infof("Kubeadm %s already exist, skip install.", kubeadmVersion) + kubeadmExist = true + } else { + return fmt.Errorf("The existing kubeadm version %s is not supported, please clean it. Valid server versions are %v.", kubeadmVersion, MiniumKubeadmVersion) + } + } else { + klog.ErrorS(err, "kubeadm version fail") + } + } else { + klog.ErrorS(err, "kubeadm look path fail") + } + + if !kubeadmExist { + // download and install kubeadm + packageUrl := fmt.Sprintf(KubeadmUrlFormat, DefaultKubeadmVersion, runtime.GOARCH) + savePath := fmt.Sprintf("%s/kubeadm", TmpDownloadDir) + klog.V(2).Infof("Download kubeadm from: %s", packageUrl) + if err := util.DownloadFile(packageUrl, savePath, 3); err != nil { + return fmt.Errorf("Download kubeadm fail: %w", err) + } + comp := "kubeadm" + target := fmt.Sprintf("/usr/bin/%s", comp) + if err := edgenode.CopyFile(TmpDownloadDir+"/"+comp, target, constants.DirMode); err != nil { + return err + } + } + return nil +}