add infra module (#754)

* hotfix(master): add infra module
This commit is contained in:
cuisongliu
2021-12-19 18:38:03 +08:00
committed by GitHub
parent 5fde3d32f7
commit 905ceada4d
83 changed files with 2685 additions and 628 deletions
+1 -8
View File
@@ -2,7 +2,7 @@ name: CI
env:
# Common versions
GO_VERSION: '1.14'
GO_VERSION: '1.16'
on:
push:
@@ -27,10 +27,6 @@ jobs:
go-version: ${{ env.GO_VERSION }}
- name: Run Check License
run: |
wget https://github.com/google/addlicense/releases/download/v1.0.0/addlicense_1.0.0_Linux_x86_64.tar.gz
tar -zxvf addlicense_1.0.0_Linux_x86_64.tar.gz -C $(go env GOPATH)/bin
chmod a+x $(go env GOPATH)/bin/addlicense
rm -rf addlicense_1.0.0_Linux_x86_64.tar.gz
make filelicense
modifyCode=$(git status -s | grep M | wc -l)
git status -s
@@ -52,9 +48,6 @@ jobs:
with:
go-version: ${{ env.GO_VERSION }}
- name: Install go ci lint
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.39.0
- name: Run Linter
run: make lint
+1
View File
@@ -12,3 +12,4 @@ dist
.vscode
test/Note.md
.ossutil_checkpoint
bin
+1 -1
View File
@@ -16,7 +16,7 @@ linters:
enable:
- gofmt
- goimports
- golint
- revive
- stylecheck
- goconst
- gosimple
+3 -3
View File
@@ -14,9 +14,9 @@ builds:
- amd64
- arm64
ldflags:
- -X github.com/linuxsuren/cobra-extension/version.version={{.Version}}
- -X github.com/linuxsuren/cobra-extension/version.commit={{.ShortCommit}}
- -X github.com/linuxsuren/cobra-extension/version.date={{.Date}}
- -X github.com/fanux/sealos/pkg/version.gitVersion={{.Version}}
- -X github.com/fanux/sealos/pkg/version.gitCommit={{.ShortCommit}}
- -X github.com/fanux/sealos/pkg/version.buildDate={{.Date}}
- -s -w
#archives:
# - replacements:
+43 -47
View File
@@ -8,32 +8,36 @@ else
GOBIN=$(shell go env GOBIN)
endif
install-golint: ## check license if not exist install addlicense tools
ifeq (, $(shell which golangci-lint))
@{ \
set -e ;\
o install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.39.0 ;\
}
GOLINT_BIN=$(GOBIN)/golangci-lint
else
GOLINT_BIN=$(shell which golangci-lint)
endif
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
@[ -f $(1) ] || { \
set -e ;\
TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef
GOLINT_BIN = $(shell pwd)/bin/golangci-lint
install-golint: ## check license if not exist install go-lint tools
$(call go-get-tool,$(GOLINT_BIN),github.com/golangci/golangci-lint/cmd/golangci-lint@v1.43.0)
lint: install-golint ## Run go lint against code.
$(GOLINT_BIN) run -v ./...
default: build
install-goreleaser: ## check license if not exist install addlicense tools
ifeq (, $(shell which goreleaser))
@{ \
set -e ;\
go install github.com/goreleaser/goreleaser@latest ;\
}
GORELEASER_BIN=$(GOBIN)/goreleaser
else
GORELEASER_BIN=$(shell which goreleaser)
endif
GORELEASER_BIN = $(shell pwd)/bin/goreleaser
install-goreleaser: ## check license if not exist install go-lint tools
$(call go-get-tool,$(GORELEASER_BIN),github.com/goreleaser/goreleaser@latest)
build: SHELL:=/bin/bash
build: install-goreleaser clean ## build binaries by default
@@ -46,40 +50,22 @@ help: ## this help
clean: ## clean
rm -rf dist
install-addlicense: ## check license if not exist install addlicense tools
ifeq (, $(shell which addlicense))
@{ \
set -e ;\
LICENSE_TMP_DIR=$$(mktemp -d) ;\
cd $$LICENSE_TMP_DIR ;\
go mod init tmp ;\
go get -v github.com/google/addlicense ;\
rm -rf $$LICENSE_TMP_DIR ;\
}
ADDLICENSE_BIN=$(GOBIN)/addlicense
else
ADDLICENSE_BIN=$(shell which addlicense)
endif
ADDLICENSE_BIN = $(shell pwd)/bin/addlicense
install-addlicense: ## check license if not exist install go-lint tools
$(call go-get-tool,$(ADDLICENSE_BIN),github.com/google/addlicense@latest)
filelicense: SHELL:=/bin/bash
filelicense: ## add license
filelicense:
filelicense: install-addlicense
for file in ${Dirs} ; do \
if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \
$(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "sealos." -f hack/template/LICENSE ./$$file ; \
fi \
done
install-ossutil: ## check ossutil if not exist install ossutil tools
ifeq (, $(shell which ossutil))
@{ \
set -e ;\
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\
}
OSSUTIL_BIN=$(GOBIN)/ossutil
else
OSSUTIL_BIN=$(shell which ossutil)
endif
OSSUTIL_BIN = $(shell pwd)/bin/ossutil
install-ossutil: ## check license if not exist install go-lint tools
$(call go-get-tool,$(OSSUTIL_BIN),github.com/aliyun/ossutil@latest)
push-oss:install-ossutil build
$(OSSUTIL_BIN) cp -f dist/sealos_linux_amd64/sealos oss://sealyun-temp/sealos/${COMMIT_ID}/sealos
@@ -87,3 +73,13 @@ push-oss:install-ossutil build
generator-contributors:
git log --format='%aN <%aE>' | sort -uf > CONTRIBUTORS
HEAD_FILE := hack/template/boilerplate.go.txt
INPUT_DIR := github.com/fanux/sealos/pkg/types/v1beta1
deepcopy:
deepcopy-gen \
--input-dirs="$(INPUT_DIR)" \
-O zz_generated.deepcopy \
--go-header-file "$(HEAD_FILE)" \
--output-base "${GOPATH}/src"
+1 -1
View File
@@ -17,7 +17,7 @@ package cmd
import (
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/install"
-74
View File
@@ -1,74 +0,0 @@
// Copyright © 2021 sealos.
//
// 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 cmd
import (
"fmt"
"os"
"github.com/fanux/sealos/pkg/utils"
install "github.com/fanux/sealos/pkg/install"
"github.com/fanux/sealgate/cloud"
"github.com/spf13/cobra"
)
var p bool
// cloudCmd represents the cloud command
var cloudCmd = &cobra.Command{
Use: "cloud",
Short: "sealos on cloud",
Long: `sealos will create vms vpc switch security group on cloud and install kubernetes on it`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("install kubernetes on cloud...")
var key, sec string
if key = os.Getenv("ACCESS_KEY_ID"); key != "" {
install.C.AccessKey = key
}
if sec = os.Getenv("ACCESS_KEY_SECRET"); sec != "" {
install.C.AccessKey = sec
}
install.CloudInstall(&install.C)
},
}
func init() {
rootCmd.AddCommand(cloudCmd)
cloudCmd.Flags().StringVar(&install.C.AccessKey, "accessKey", "", "cloud provider accessKey, like LTAIah2bOOcr0uuT")
cloudCmd.Flags().StringVar(&install.C.AccessSecret, "accessSecret", "", "cloud provider accessSecret, like FN3FcvXUctbudisnHs89bcYlbsZuImh")
cloudCmd.Flags().StringVar(&install.C.Provider, "provider", cloud.ALI, "cloud provider type,current support ali")
cloudCmd.Flags().IntVar(&install.C.Master, "master", 1, "the number of master vms")
cloudCmd.Flags().IntVar(&install.C.Node, "node", 1, "the number of node vms")
cloudCmd.Flags().StringVar(&install.C.Version, "version", "v1.16.0", "kubernetes version")
cloudCmd.Flags().StringVar(&install.C.Flavor, "flavor", "2C4G", "the type of vms")
cloudCmd.Flags().StringVar(&install.C.Name, "name", "sealyun"+utils.RandString(8), "the name of your cluster")
cloudCmd.Flags().StringVar(&install.C.Passwd, "passwd", "Fanux#123", "the passwd of your vm servers")
cloudCmd.Flags().StringVar(&install.C.Region, "region", "cn-hongkong", "cloud provider region")
cloudCmd.Flags().StringVar(&install.C.Zone, "zone", "cn-hongkong-b", "cloud provider region")
cloudCmd.Flags().StringVar(&install.C.Image, "image", "centos_7_04_64_20G_alibase_201701015.vhd", "vm os image")
cloudCmd.Flags().BoolVar(&p, "y", false, "prompt or not")
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// cloudCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// cloudCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
+5 -5
View File
@@ -24,7 +24,7 @@ import (
)
var cniType string
var version string
var cniVersion string
// cniCmd represents the cni command
var cniCmd = &cobra.Command{
@@ -35,15 +35,15 @@ var cniCmd = &cobra.Command{
logger.Error("unsupport cni: ", cniType)
return
}
if version == "" {
logger.Error("cni version should not nil ", version)
if cniVersion == "" {
logger.Error("cni version should not nil ", cniVersion)
return
}
yaml := cni.NewNetwork(cniType, cni.MetaData{
Interface: "interface=eth.*|en.*|em.*",
IPIP: true,
MTU: "1440",
Version: version,
Version: cniVersion,
}).Manifests("")
fmt.Println(yaml)
},
@@ -53,7 +53,7 @@ func init() {
rootCmd.AddCommand(cniCmd)
cniCmd.Flags().StringVarP(&cniType, "cni-type", "t", cni.CALICO, "print cni yaml, cni tpye just like, calico.flannel.cilium")
cniCmd.Flags().StringVarP(&version, "version", "v", "", "calico version")
cniCmd.Flags().StringVarP(&cniVersion, "version", "v", "", "calico version")
// Here you will define your flags and configuration settings.
+1 -1
View File
@@ -17,7 +17,7 @@ package cmd
import (
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
install "github.com/fanux/sealos/pkg/install"
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"os"
"time"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
install "github.com/fanux/sealos/pkg/install"
+1 -1
View File
@@ -17,7 +17,7 @@ package cmd
import (
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/cni"
+4 -4
View File
@@ -17,7 +17,7 @@ package cmd
import (
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
install "github.com/fanux/sealos/pkg/install"
@@ -29,12 +29,12 @@ import (
var (
AppURL string
installExample string = `
installExample = `
# when usr -f flag , you need add something to config file.
# Apply the configuration in values.yaml to a kubernetes Cluster.
# Apply the configuration in values.yaml to a kubernetes Infra.
sealos install --pkg-url /root/dashboard.tar -f values.yaml
# Apply the yaml passed into stdin to a kubenertes Cluster.
# Apply the yaml passed into stdin to a kubenertes Infra.
cat values.yaml | sealos install --pkg-url /root/dashboard.tar -f -
# Set the WorkDir for your Package
+1 -1
View File
@@ -15,7 +15,7 @@
package cmd
import (
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -17,7 +17,7 @@ package cmd
import (
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
install "github.com/fanux/sealos/pkg/install"
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"fmt"
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/logger"
+27 -14
View File
@@ -15,23 +15,36 @@
package cmd
import (
"encoding/json"
"fmt"
"runtime"
"strings"
extver "github.com/linuxsuren/cobra-extension/version"
"github.com/fanux/sealos/pkg/version"
"github.com/spf13/cobra"
)
func init() {
// it's possible to have multiple choices for users to choose GitHub or aliyun as their download source
// see also https://github.com/LinuxSuRen/cobra-extension/issues/6
const name = "sealos"
verCmd := extver.NewVersionCmd("fanux", name, name, func(ver string) string {
if strings.HasPrefix(ver, "v") {
ver = strings.TrimPrefix(ver, "v")
var shortPrint bool
var versionCmd = &cobra.Command{
Use: "version",
Short: "version",
Args: cobra.NoArgs,
Example: `sealer version`,
RunE: func(cmd *cobra.Command, args []string) error {
marshalled, err := json.Marshal(version.Get())
if err != nil {
return err
}
return fmt.Sprintf("https://github.com/fanux/sealos/releases/download/v%s/%s_%s_%s_%s.tar.gz",
ver, name, ver, runtime.GOOS, runtime.GOARCH)
})
rootCmd.AddCommand(verCmd)
if shortPrint {
fmt.Println(version.Get().String())
} else {
fmt.Println(string(marshalled))
}
return nil
},
}
func init() {
rootCmd.AddCommand(versionCmd)
versionCmd.Flags().BoolVar(&shortPrint, "short", false, "If true, print just the cniVersion number.")
}
+5 -3
View File
@@ -1,14 +1,16 @@
module github.com/fanux/sealos
go 1.13
go 1.15
require (
github.com/aliyun/alibaba-cloud-sdk-go v1.61.985
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fanux/sealgate v0.0.5
github.com/google/uuid v1.1.2 // indirect
github.com/linuxsuren/cobra-extension v0.0.8
github.com/mitchellh/go-homedir v1.1.0
github.com/onsi/ginkgo v1.11.0
github.com/onsi/gomega v1.7.0
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.11.0
github.com/prometheus/common v0.13.0 // indirect
+12 -108
View File
@@ -11,7 +11,6 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
@@ -24,35 +23,29 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20191115143122-2863a2c99a71 h1:403lX+Je3enjqcePi8bSN6QWzhuzx71dBViv+PhqHUA=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20191115143122-2863a2c99a71/go.mod h1:mNZkuqaeM5UCiAdkV4r+lrheu8Q5fe/487bRFrGYZ8A=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.985 h1:ETObK47vrphrw9wC+2/SinHL59YQtle2eBtSRucLTRQ=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.985/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible h1:ht2+VfbXtNLGhCsnTMc6/N26nSTBK6qdhktjYyjJQkk=
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
@@ -71,7 +64,6 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
@@ -80,7 +72,6 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -90,11 +81,9 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -111,23 +100,17 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fanux/sealgate v0.0.5 h1:KCBf+x3TdjCEVVNCjdkeMukDE0kZx9QE39Yy2IazkiM=
github.com/fanux/sealgate v0.0.5/go.mod h1:y3141RLsCSgid4+H0O+7CoAqIHDGB0r0mcR8TYnqvps=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -142,7 +125,6 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -159,8 +141,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -183,10 +163,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v29 v29.0.3 h1:IktKCTwU//aFHnpA+2SLIi7Oo9uhAzgsdZNbcAqhgdc=
github.com/google/go-github/v29 v29.0.3/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -213,10 +189,6 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gosuri/uilive v0.0.3 h1:kvo6aB3pez9Wbudij8srWo4iY6SFTTxTKOkb+uRCE8I=
github.com/gosuri/uilive v0.0.3/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw=
github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
@@ -241,7 +213,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -250,7 +221,7 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
@@ -258,11 +229,6 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jenkins-zh/jenkins-cli v0.0.32 h1:q3KyWeYegQ4ncLI6zoPAXFkRXjaAGdjCI2qEc7fmOGk=
github.com/jenkins-zh/jenkins-cli v0.0.32/go.mod h1:uE1mH9PNITrg0sugv6HXuM/CSddg0zxXoYu3w57I3JY=
github.com/jenkins-zh/jenkins-formulas v0.0.5/go.mod h1:zS8fm8u5L6FcjZM0QznXsLV9T2UtSVK+hT6Sm76iUZ4=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
@@ -279,8 +245,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -293,18 +257,10 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/linuxsuren/cobra-extension v0.0.6/go.mod h1:qcEJv7BbL0UpK6MbrTESP/nKf1+z1wQdMAnE1NBl3QQ=
github.com/linuxsuren/cobra-extension v0.0.8 h1:0YGETwoxyz8mfijbhZKnfiyuSeCKA6nQx7d0Fd/7O/k=
github.com/linuxsuren/cobra-extension v0.0.8/go.mod h1:+eJXhTxKdianYLGSU8W58pnedcml6eZrOfXASHWJhRg=
github.com/linuxsuren/http-downloader v0.0.2-0.20201207132639-19888a6beaec/go.mod h1:zRZY9FCDBuYNDxbI2Ny5suasZsMk7J6q9ecQ3V3PIqI=
github.com/linuxsuren/http-downloader v0.0.6 h1:JuCgWVT4/pw8MAhYe+ngE7BwcO575L1aPDc9Fgx+2ig=
github.com/linuxsuren/http-downloader v0.0.6/go.mod h1:xxgh2OE7WGL9TwDE9L8Gh7Lqq9fFPuHbh5tofUitEfE=
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
@@ -312,20 +268,15 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
@@ -351,8 +302,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
@@ -360,18 +309,12 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -384,11 +327,9 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -434,7 +375,6 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
@@ -443,7 +383,6 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
github.com/sealyun/lvscare v1.1.2-alpha.2 h1:SlnEAXOPn5gC6l8tgvbn9fApyJaQ0ecQHSV3cEfvQYY=
github.com/sealyun/lvscare v1.1.2-alpha.2/go.mod h1:FtOEdsXuYtw9Jwd/Jct25K+PcpUFSDemvF4VgNygjj0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -462,7 +401,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
@@ -472,29 +410,22 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
@@ -503,11 +434,9 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/wonderivan/logger v1.0.0 h1:Z6Nz+3SNcizolx3ARH11axdD4DXjFpb2J+ziGUVlv/U=
github.com/wonderivan/logger v1.0.0/go.mod h1:NObMfQ3WOLKfYEZuGeZQfuQfSPE5+QNgRddVMzsAT/k=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/zalando/go-keyring v0.0.0-20200121091418-667557018717/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -537,12 +466,9 @@ go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -589,14 +515,10 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@@ -616,43 +538,31 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -676,7 +586,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -742,6 +651,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -752,9 +662,6 @@ gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
@@ -767,8 +674,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -795,7 +700,6 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
+13
View File
@@ -0,0 +1,13 @@
// Copyright © 2021 sealos.
//
// 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.
+1 -1
View File
@@ -24,7 +24,7 @@ import (
"strings"
"sync"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"fmt"
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
install "github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/logger"
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"fmt"
"io/ioutil"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils/logger"
+28 -28
View File
@@ -84,7 +84,7 @@ spec:
listKind: BGPConfigurationList
plural: bgpconfigurations
singular: bgpconfiguration
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -218,7 +218,7 @@ spec:
listKind: BGPPeerList
plural: bgppeers
singular: bgppeer
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -325,7 +325,7 @@ spec:
listKind: BlockAffinityList
plural: blockaffinities
singular: blockaffinity
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -386,7 +386,7 @@ spec:
listKind: ClusterInformationList
plural: clusterinformations
singular: clusterinformation
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -450,7 +450,7 @@ spec:
listKind: FelixConfigurationList
plural: felixconfigurations
singular: felixconfiguration
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -1013,7 +1013,7 @@ spec:
listKind: GlobalNetworkPolicyList
plural: globalnetworkpolicies
singular: globalnetworkpolicy
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -1784,7 +1784,7 @@ spec:
listKind: GlobalNetworkSetList
plural: globalnetworksets
singular: globalnetworkset
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -1837,7 +1837,7 @@ spec:
listKind: HostEndpointList
plural: hostendpoints
singular: hostendpoint
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -1945,7 +1945,7 @@ spec:
listKind: IPAMBlockList
plural: ipamblocks
singular: ipamblock
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -2026,7 +2026,7 @@ spec:
listKind: IPAMConfigList
plural: ipamconfigs
singular: ipamconfig
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -2082,7 +2082,7 @@ spec:
listKind: IPAMHandleList
plural: ipamhandles
singular: ipamhandle
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -2138,7 +2138,7 @@ spec:
listKind: IPPoolList
plural: ippools
singular: ippool
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -2237,7 +2237,7 @@ spec:
listKind: KubeControllersConfigurationList
plural: kubecontrollersconfigurations
singular: kubecontrollersconfiguration
scope: Cluster
scope: Infra
versions:
- name: v1
schema:
@@ -3653,7 +3653,7 @@ spec:
configMapKeyRef:
name: calico-config
key: calico_backend
# Cluster type to identify the deployment type
# Infra type to identify the deployment type
- name: CLUSTER_TYPE
value: "k8s,bgp"
# Auto-detect the BGP IP address.
@@ -3870,7 +3870,7 @@ metadata:
---
# This manifest creates a Pod Disruption Budget for Controller to allow K8s Cluster Autoscaler to evict
# This manifest creates a Pod Disruption Budget for Controller to allow K8s Infra Autoscaler to evict
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
@@ -3941,7 +3941,7 @@ kind: CustomResourceDefinition
metadata:
name: felixconfigurations.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -3955,7 +3955,7 @@ kind: CustomResourceDefinition
metadata:
name: ipamblocks.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -3970,7 +3970,7 @@ kind: CustomResourceDefinition
metadata:
name: blockaffinities.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -3985,7 +3985,7 @@ kind: CustomResourceDefinition
metadata:
name: ipamhandles.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4000,7 +4000,7 @@ kind: CustomResourceDefinition
metadata:
name: ipamconfigs.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4015,7 +4015,7 @@ kind: CustomResourceDefinition
metadata:
name: bgppeers.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4030,7 +4030,7 @@ kind: CustomResourceDefinition
metadata:
name: bgpconfigurations.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4045,7 +4045,7 @@ kind: CustomResourceDefinition
metadata:
name: ippools.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4060,7 +4060,7 @@ kind: CustomResourceDefinition
metadata:
name: hostendpoints.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4075,7 +4075,7 @@ kind: CustomResourceDefinition
metadata:
name: clusterinformations.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4090,7 +4090,7 @@ kind: CustomResourceDefinition
metadata:
name: globalnetworkpolicies.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4105,7 +4105,7 @@ kind: CustomResourceDefinition
metadata:
name: globalnetworksets.crd.projectcalico.org
spec:
scope: Cluster
scope: Infra
group: crd.projectcalico.org
version: v1
names:
@@ -4484,7 +4484,7 @@ spec:
configMapKeyRef:
name: calico-config
key: calico_backend
# Cluster type to identify the deployment type
# Infra type to identify the deployment type
- name: CLUSTER_TYPE
value: "k8s,bgp"
# Auto-detect the BGP IP address.
+3
View File
@@ -0,0 +1,3 @@
# infra模块
根据Clusterfile里的定义去申请IaaS资源,保障IaaS资源与Clusterfile中的定义保持终态一致
+85
View File
@@ -0,0 +1,85 @@
/*
Copyright 2021 cuisongliu@qq.com.
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 aliyun
import (
"time"
v2 "github.com/fanux/sealos/pkg/types/v1beta1"
)
const (
EnvAccessKey = "ECS_AKID"
EnvAccessSecret = "ECS_AKSK"
EnvRegion = "ECS_REGION"
)
const (
Scheme = "https"
IPProtocol = "tcp"
APIServerPortRange = "6443/6443"
SSHPortRange = "22/22"
SourceCidrIP = "0.0.0.0/0"
CidrBlock = "172.16.0.0/24"
Policy = "accept"
DestinationResource = "InstanceType"
InstanceChargeType = "PostPaid"
InternetChargeType = "PayByTraffic"
defaultImageAmdID = "centos_7_9_x64_20G_alibase_20210927.vhd"
defaultImageArmID = "anolisos_7_7_arm64_20G_anck_alibase_20211118.vhd"
Product = "product"
Role = "role"
Master = "master"
Node = "node"
Stopped = "Stopped"
AvailableTypeStatus = "WithStock"
Bandwidth = "100"
AliDomain = "www.sealyun.com/"
DefaultRegionID = "cn-shanghai"
TryTimes = 10
TrySleepTime = time.Second
JustGetInstanceInfo = 0
)
type ResourceName string
const (
EipID ResourceName = AliDomain + "EipID"
VpcID ResourceName = AliDomain + "VpcID"
VSwitchID ResourceName = AliDomain + "VSwitchID"
SecurityGroupID ResourceName = AliDomain + "SecurityGroupID"
SystemInfo ResourceName = AliDomain + "SystemInfo"
ShouldBeDeleteInstancesIDs ResourceName = "ShouldBeDeleteInstancesIDs"
)
func (r ResourceName) Value(status v2.InfraStatus) string {
var value string
switch r {
case EipID:
value = status.EIPID
case VpcID:
value = status.VpcID
case VSwitchID:
value = status.VSwitchID
case SecurityGroupID:
value = status.SecurityGroupID
case ShouldBeDeleteInstancesIDs:
value = status.ShouldBeDeleteInstancesIDs
default:
}
return value
}
+522
View File
@@ -0,0 +1,522 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 aliyun
import (
"errors"
"fmt"
"os"
"strings"
v2 "github.com/fanux/sealos/pkg/types/v1beta1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/logger"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)
type Instance struct {
CPU int
Memory float64
InstanceID string
PrimaryIPAddress string
}
type EcsManager struct {
}
func (a *AliProvider) RetryEcsRequest(request requests.AcsRequest, response responses.AcsResponse) error {
return a.RetryEcsAction(request, response, TryTimes)
}
func (a *AliProvider) RetryEcsAction(request requests.AcsRequest, response responses.AcsResponse, tryTimes int) error {
return utils.Retry(tryTimes, TrySleepTime, func() error {
err := a.EcsClient.DoAction(request, response)
if err != nil {
return err
}
return nil
})
}
func (a *AliProvider) RetryEcsInstanceType(request requests.AcsRequest, response responses.AcsResponse, instances []string) error {
for i := 0; i < len(instances); i++ {
switch req := request.(type) {
case *ecs.ModifyInstanceSpecRequest:
req.InstanceType = instances[i]
case *ecs.RunInstancesRequest:
req.InstanceType = instances[i]
}
err := a.RetryEcsAction(request, response, 4)
if err == nil {
a.Infra.Spec.Instance.Type = instances[i]
logger.Debug("use SystemInfo type: %s", instances[i])
break
} else if i == len(instances)-1 {
return fmt.Errorf("failed to get ecs SystemInfo type, %v", err)
}
}
return nil
}
func (a *AliProvider) TryGetInstance(request *ecs.DescribeInstancesRequest, response *ecs.DescribeInstancesResponse, expectCount int) error {
return utils.Retry(TryTimes, TrySleepTime, func() error {
err := a.EcsClient.DoAction(request, response)
var ipList []string
if err != nil {
return err
}
instances := response.Instances.Instance
if expectCount == -1 {
return nil
}
if len(instances) != expectCount {
return errors.New("the number of instances is not as expected")
}
for _, instance := range instances {
if instance.NetworkInterfaces.NetworkInterface[0].PrimaryIpAddress == "" {
return errors.New("PrimaryIpAddress cannt nob be nil")
}
if len(ipList) != 0 && !utils.NotIn(instance.NetworkInterfaces.NetworkInterface[0].PrimaryIpAddress, ipList) {
return errors.New("PrimaryIpAddress cannt nob be same")
}
ipList = append(ipList, instance.NetworkInterfaces.NetworkInterface[0].PrimaryIpAddress)
}
return nil
})
}
func (a *AliProvider) InputIPlist(instanceRole string) (ipList []string, err error) {
var hosts *v2.Hosts
switch instanceRole {
case Master:
hosts = &a.Infra.Spec.Masters
case Node:
hosts = a.Infra.Spec.Nodes
}
if hosts == nil {
return nil, err
}
instances, err := a.GetInstancesInfo(instanceRole, hosts.Count)
if err != nil {
return nil, err
}
for _, instance := range instances {
ipList = append(ipList, instance.PrimaryIPAddress)
}
return ipList, nil
}
func (a *AliProvider) GetInstanceStatus(instanceID string) (instanceStatus string, err error) {
request := ecs.CreateDescribeInstanceStatusRequest()
request.Scheme = Scheme
request.InstanceId = &[]string{instanceID}
response := ecs.CreateDescribeInstanceStatusResponse()
err = a.RetryEcsRequest(request, response)
if err != nil {
return "", fmt.Errorf("get SystemInfo status failed %v , error :%v", instanceID, err)
}
if len(response.InstanceStatuses.InstanceStatus) == 0 {
return "", fmt.Errorf("SystemInfo list is empty")
}
return response.InstanceStatuses.InstanceStatus[0].Status, nil
}
func (a *AliProvider) PoweroffInstance(instanceID string) error {
request := ecs.CreateStopInstancesRequest()
request.Scheme = Scheme
request.InstanceId = &[]string{instanceID}
response := ecs.CreateStopInstancesResponse()
return a.RetryEcsRequest(request, response)
}
func (a *AliProvider) StartInstance(instanceID string) error {
request := ecs.CreateStartInstanceRequest()
request.Scheme = Scheme
request.InstanceId = instanceID
response := ecs.CreateStartInstanceResponse()
return a.RetryEcsRequest(request, response)
}
func (a *AliProvider) ChangeInstanceType(instanceID, instanceRole string, cpu int, memory float64) error {
instanceStatus, err := a.GetInstanceStatus(instanceID)
if err != nil {
return err
}
if instanceStatus != Stopped {
err = a.PoweroffInstance(instanceID)
if err != nil {
return err
}
}
expectInstanceType, err := a.GetAvailableResource(instanceRole, cpu, memory)
if err != nil {
return err
}
request := ecs.CreateModifyInstanceSpecRequest()
request.Scheme = Scheme
request.InstanceId = instanceID
//_, err = d.Client.ModifyInstanceSpec(request)
response := ecs.CreateModifyInstanceSpecResponse()
err = a.RetryEcsInstanceType(request, response, expectInstanceType)
if err != nil {
return err
}
return a.StartInstance(instanceID)
}
func (a *AliProvider) GetInstancesInfo(instancesRole string, expectCount int) (instances []Instance, err error) {
var count int
tag := make(map[string]string)
tag[Product] = a.Infra.Name
tag[Role] = instancesRole
if expectCount == 0 {
count = -1
} else {
count = expectCount
}
instancesTags := CreateDescribeInstancesTag(tag)
request := ecs.CreateDescribeInstancesRequest()
request.Scheme = Scheme
request.RegionId = a.Infra.Status.RegionID
request.VSwitchId = a.Infra.Status.VSwitchID
request.SecurityGroupId = a.Infra.Status.SecurityGroupID
request.Tag = &instancesTags
response := ecs.CreateDescribeInstancesResponse()
err = a.TryGetInstance(request, response, count)
if err != nil {
return nil, err
}
for _, i := range response.Instances.Instance {
instances = append(instances,
Instance{
CPU: i.Cpu,
Memory: float64(i.Memory / 1024),
InstanceID: i.InstanceId,
PrimaryIPAddress: i.NetworkInterfaces.NetworkInterface[0].PrimaryIpAddress})
}
return
}
func (a *AliProvider) ReconcileInstances(instanceRole string) error {
var hosts *v2.Hosts
var instances []Instance
var instancesIDs string
var IPList []string
switch instanceRole {
case Master:
hosts = &a.Infra.Spec.Masters
instancesIDs = a.Infra.Status.MasterIDs
if hosts.Count == 0 {
return errors.New("master count not set")
}
case Node:
hosts = a.Infra.Spec.Nodes
instancesIDs = a.Infra.Status.NodeIDs
if hosts == nil {
return nil
}
}
if hosts == nil {
return errors.New("hosts not set")
}
var err error
if instancesIDs != "" {
instances, err = a.GetInstancesInfo(instanceRole, JustGetInstanceInfo)
}
if err != nil {
return err
}
if i := hosts.Count; len(instances) < i {
err = a.RunInstances(instanceRole, i-len(instances))
if err != nil {
return err
}
ipList, err := a.InputIPlist(instanceRole)
if err != nil {
return err
}
IPList = utils.AppendIPList(IPList, ipList)
logger.Info("get scale up IP list %v, append iplist %v, host count %s", ipList, IPList, hosts.Count)
}
for _, instance := range instances {
if instance.CPU != hosts.CPU || instance.Memory != hosts.Memory {
err = a.ChangeInstanceType(instance.InstanceID, instanceRole, hosts.CPU, hosts.Memory)
if err != nil {
return err
}
}
}
if instanceRole == Master {
a.Infra.Status.Masters = IPList
} else {
a.Infra.Status.Nodes = IPList
}
logger.Info("reconcile %s instances success %v ", instanceRole, IPList)
return nil
}
func (a *AliProvider) DeleteInstances() error {
instanceIDs := strings.Split(a.Infra.Status.ShouldBeDeleteInstancesIDs, ",")
if len(instanceIDs) == 0 {
return nil
}
request := ecs.CreateDeleteInstancesRequest()
request.Scheme = Scheme
request.InstanceId = &instanceIDs
request.Force = requests.NewBoolean(true)
//_, err := d.Client.DeleteInstances(request)
response := ecs.CreateDeleteInstancesResponse()
err := a.RetryEcsRequest(request, response)
if err != nil {
return err
}
a.Infra.Status.ShouldBeDeleteInstancesIDs = ""
return nil
}
func CreateDescribeInstancesTag(tags map[string]string) (instanceTags []ecs.DescribeInstancesTag) {
for k, v := range tags {
instanceTags = append(instanceTags, ecs.DescribeInstancesTag{Key: k, Value: v})
}
return
}
func CreateInstanceDataDisk(dataDisks []string, category string) (instanceDisks []ecs.RunInstancesDataDisk) {
for _, v := range dataDisks {
instanceDisks = append(instanceDisks,
ecs.RunInstancesDataDisk{Size: v, Category: category})
}
return
}
type InstanceInfo struct {
InstanceType string
ZoneID string
}
func (a *AliProvider) GetAvailableResourcesForSystem() (instances *InstanceInfo, err error) {
request := ecs.CreateDescribeAvailableResourceRequest()
request.Scheme = Scheme
if a.Infra.Status.ZoneID != "" {
request.ZoneId = a.Infra.Status.ZoneID
}
if a.Infra.Spec.Instance.Type != "" {
request.InstanceType = a.Infra.Spec.Instance.Type
}
request.RegionId = a.Infra.Status.RegionID
request.DestinationResource = DestinationResource
request.InstanceChargeType = InstanceChargeType
request.SystemDiskCategory = a.Infra.Spec.Instance.SystemCategory
request.DataDiskCategory = a.Infra.Spec.Instance.DataCategory
request.SpotStrategy = a.Infra.Status.SpotStrategy
response := ecs.CreateDescribeAvailableResourceResponse()
err = a.EcsClient.DoAction(request, response)
if err != nil {
return nil, err
}
if len(response.AvailableZones.AvailableZone) < 1 {
return nil, fmt.Errorf("resources not find")
}
for _, i := range response.AvailableZones.AvailableZone {
for _, f := range i.AvailableResources.AvailableResource {
for _, r := range f.SupportedResources.SupportedResource {
if r.StatusCategory == AvailableTypeStatus {
return &InstanceInfo{
InstanceType: r.Value,
ZoneID: i.ZoneId,
}, nil
}
}
}
}
return
}
func (a *AliProvider) GetAvailableResource(instanceRole string, cores int, memory float64) (instanceType []string, err error) {
request := ecs.CreateDescribeAvailableResourceRequest()
request.Scheme = Scheme
request.RegionId = a.Infra.Status.RegionID
request.ZoneId = a.Infra.Status.ZoneID
request.DestinationResource = DestinationResource
request.InstanceChargeType = InstanceChargeType
request.Cores = requests.NewInteger(cores)
request.Memory = requests.NewFloat(memory)
response := ecs.CreateDescribeAvailableResourceResponse()
err = a.EcsClient.DoAction(request, response)
if err != nil {
return nil, err
}
if len(response.AvailableZones.AvailableZone) < 1 {
return nil, fmt.Errorf("resources not find")
}
for _, i := range response.AvailableZones.AvailableZone {
for _, f := range i.AvailableResources.AvailableResource {
for _, r := range f.SupportedResources.SupportedResource {
if r.StatusCategory == AvailableTypeStatus {
instanceType = append(instanceType, r.Value)
}
}
}
}
var defaultInstanceType []string
switch instanceRole {
case Master:
defaultInstanceType = []string{a.Infra.Status.MasterInstanceType}
case Node:
defaultInstanceType = []string{a.Infra.Status.NodeInstanceType}
}
instanceType = append(defaultInstanceType, instanceType...)
return
}
func (a *AliProvider) RunInstances(instanceRole string, count int) error {
var hosts *v2.Hosts
switch instanceRole {
case Master:
hosts = &a.Infra.Spec.Masters
case Node:
hosts = a.Infra.Spec.Nodes
}
instances := hosts
if instances == nil {
return errors.New("host not set")
}
systemDiskSize := instances.Disks.System
var instanceType []string
var err error
instanceType, err = a.GetAvailableResource(instanceRole, instances.CPU, instances.Memory)
if err != nil {
return err
}
tag := make(map[string]string)
tag[Product] = a.Infra.Name
tag[Role] = instanceRole
instancesTag := CreateInstanceTag(tag)
dataDisks := instances.Disks.Data
datadisk := CreateInstanceDataDisk(dataDisks, a.Infra.Spec.Instance.DataCategory)
request := ecs.CreateRunInstancesRequest()
request.Scheme = Scheme
request.ImageId = a.Infra.Spec.Instance.ImageID
request.Password = a.Infra.Spec.Auth.Passwd
request.SecurityGroupId = a.Infra.Status.SecurityGroupID
request.VSwitchId = a.Infra.Status.VSwitchID
request.SystemDiskSize = systemDiskSize
request.SystemDiskCategory = a.Infra.Spec.Instance.SystemCategory
request.DataDisk = &datadisk
request.SpotStrategy = a.Infra.Status.SpotStrategy
request.Amount = requests.NewInteger(count)
request.Tag = &instancesTag
//response, err := d.Client.RunInstances(request)
response := ecs.CreateRunInstancesResponse()
err = a.RetryEcsInstanceType(request, response, instanceType)
if err != nil {
return err
}
instancesIDs := strings.Join(response.InstanceIdSets.InstanceIdSet, ",")
switch instanceRole {
case Master:
a.Infra.Status.MasterIDs += instancesIDs
case Node:
a.Infra.Status.NodeIDs += instancesIDs
}
return nil
}
func (a *AliProvider) AuthorizeSecurityGroup(securityGroupID, portRange string) bool {
request := ecs.CreateAuthorizeSecurityGroupRequest()
request.Scheme = Scheme
request.SecurityGroupId = securityGroupID
request.IpProtocol = IPProtocol
request.PortRange = portRange
request.SourceCidrIp = SourceCidrIP
request.Policy = Policy
response := ecs.CreateAuthorizeSecurityGroupResponse()
err := a.RetryEcsRequest(request, response)
if err != nil {
logger.Error("%v", err)
return false
}
return response.BaseResponse.IsSuccess()
}
func (a *AliProvider) CreateSecurityGroup() error {
request := ecs.CreateCreateSecurityGroupRequest()
request.Scheme = Scheme
request.RegionId = a.Infra.Status.RegionID
request.VpcId = a.Infra.Status.VpcID
response := ecs.CreateCreateSecurityGroupResponse()
err := a.RetryEcsRequest(request, response)
if err != nil {
return err
}
if !a.AuthorizeSecurityGroup(response.SecurityGroupId, SSHPortRange) {
return fmt.Errorf("authorize securitygroup ssh port failed")
}
if !a.AuthorizeSecurityGroup(response.SecurityGroupId, APIServerPortRange) {
return fmt.Errorf("authorize securitygroup apiserver port failed")
}
a.Infra.Status.SecurityGroupID = response.SecurityGroupId
return nil
}
func (a *AliProvider) DeleteSecurityGroup() error {
request := ecs.CreateDeleteSecurityGroupRequest()
request.Scheme = Scheme
request.SecurityGroupId = a.Infra.Status.SecurityGroupID
response := ecs.CreateDeleteSecurityGroupResponse()
return a.RetryEcsRequest(request, response)
}
func CreateInstanceTag(tags map[string]string) (instanceTags []ecs.RunInstancesTag) {
for k, v := range tags {
instanceTags = append(instanceTags, ecs.RunInstancesTag{Key: k, Value: v})
}
return
}
func LoadConfig(config *Config) error {
config.AccessKey = os.Getenv(EnvAccessKey)
config.AccessSecret = os.Getenv(EnvAccessSecret)
config.regionID = os.Getenv(EnvRegion)
if config.regionID == "" {
config.regionID = DefaultRegionID
}
if config.AccessKey == "" || config.AccessSecret == "" || config.regionID == "" {
return fmt.Errorf("please set accessKey and accessKeySecret ENV, example: export ACCESSKEYID=xxx export ACCESSKEYSECRET=xxx , how to get AK SK: https://ram.console.aliyun.com/manage/ak")
}
return nil
}
+248
View File
@@ -0,0 +1,248 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 aliyun
import (
"errors"
"strings"
"github.com/fanux/sealos/pkg/types/validation"
v2 "github.com/fanux/sealos/pkg/types/v1beta1"
"github.com/fanux/sealos/pkg/utils/logger"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/aliyun/alibaba-cloud-sdk-go/services/vpc"
)
type ActionName string
const (
CreateVPC ActionName = "CreateVPC"
CreateVSwitch ActionName = "CreateVSwitch"
CreateSecurityGroup ActionName = "CreateSecurityGroup"
ReconcileInstance ActionName = "ReconcileInstance"
BindEIP ActionName = "BindEIP"
ReleaseEIP ActionName = "ReleaseEIP"
ClearInstances ActionName = "ClearInstances"
DeleteVSwitch ActionName = "DeleteVSwitch"
DeleteSecurityGroup ActionName = "DeleteSecurityGroup"
DeleteVPC ActionName = "DeleteVPC"
GetSystemInfo ActionName = "GetSystemInfo"
)
type AliProvider struct {
Config Config
EcsClient ecs.Client
VpcClient vpc.Client
Infra *v2.Infra
}
type Config struct {
AccessKey string
AccessSecret string
regionID string
}
type Alifunc func() error
func (a *AliProvider) ReconcileResource(resourceKey ResourceName, action Alifunc) error {
if resourceKey.Value(a.Infra.Status) != "" {
logger.Warn("create resource exists %s: %s", resourceKey, resourceKey.Value(a.Infra.Status))
return nil
}
if err := action(); err != nil {
logger.Error("reconcile resource %s failed err: %s", resourceKey, err)
return err
}
if resourceKey.Value(a.Infra.Status) != "" {
logger.Info("create resource success %s: %s", resourceKey, resourceKey.Value(a.Infra.Status))
}
return nil
}
func (a *AliProvider) DeleteResource(resourceKey ResourceName, action Alifunc) {
val := resourceKey.Value(a.Infra.Status)
if val == "" {
logger.Warn("delete resource not exists %s", resourceKey)
return
}
if err := action(); err != nil {
logger.Error("delete resource %s failed err: %s", resourceKey, err)
} else {
logger.Info("delete resource Success %s: %s", resourceKey, val)
}
}
var RecocileFuncMap = map[ActionName]func(provider *AliProvider) error{
CreateVPC: func(aliProvider *AliProvider) error {
return aliProvider.ReconcileResource(VpcID, aliProvider.CreateVPC)
},
CreateVSwitch: func(aliProvider *AliProvider) error {
return aliProvider.ReconcileResource(VSwitchID, aliProvider.CreateVSwitch)
},
CreateSecurityGroup: func(aliProvider *AliProvider) error {
return aliProvider.ReconcileResource(SecurityGroupID, aliProvider.CreateSecurityGroup)
},
ReconcileInstance: func(aliProvider *AliProvider) error {
err := aliProvider.ReconcileInstances(Master)
if err != nil {
return err
}
err = aliProvider.ReconcileInstances(Node)
if err != nil {
return err
}
return nil
},
GetSystemInfo: func(aliProvider *AliProvider) error {
return aliProvider.ReconcileResource(SystemInfo, aliProvider.SystemInfo)
},
BindEIP: func(aliProvider *AliProvider) error {
return aliProvider.ReconcileResource(EipID, aliProvider.BindEipForMaster0)
},
}
var DeleteFuncMap = map[ActionName]func(provider *AliProvider){
ReleaseEIP: func(aliProvider *AliProvider) {
aliProvider.DeleteResource(EipID, aliProvider.ReleaseEipAddress)
},
ClearInstances: func(aliProvider *AliProvider) {
var instanceIDs []string
roles := []string{Master, Node}
for _, role := range roles {
instances, err := aliProvider.GetInstancesInfo(role, JustGetInstanceInfo)
if err != nil {
logger.Error("get %s instanceinfo failed %v", role, err)
}
for _, instance := range instances {
instanceIDs = append(instanceIDs, instance.InstanceID)
}
}
if len(instanceIDs) != 0 {
aliProvider.Infra.Status.ShouldBeDeleteInstancesIDs = strings.Join(instanceIDs, ",")
}
aliProvider.DeleteResource(ShouldBeDeleteInstancesIDs, aliProvider.DeleteInstances)
},
DeleteVSwitch: func(aliProvider *AliProvider) {
aliProvider.DeleteResource(VSwitchID, aliProvider.DeleteVSwitch)
},
DeleteSecurityGroup: func(aliProvider *AliProvider) {
aliProvider.DeleteResource(SecurityGroupID, aliProvider.DeleteSecurityGroup)
},
DeleteVPC: func(aliProvider *AliProvider) {
aliProvider.DeleteResource(VpcID, aliProvider.DeleteVPC)
},
}
func (a *AliProvider) NewClient() error {
ecsClient, err := ecs.NewClientWithAccessKey(a.Config.regionID, a.Config.AccessKey, a.Config.AccessSecret)
if err != nil {
return err
}
vpcClient, err := vpc.NewClientWithAccessKey(a.Config.regionID, a.Config.AccessKey, a.Config.AccessSecret)
if err != nil {
return err
}
a.EcsClient = *ecsClient
a.VpcClient = *vpcClient
a.Infra.Status.RegionID = a.Config.regionID
return nil
}
func (a *AliProvider) ClearCluster() {
todolist := []ActionName{
ReleaseEIP,
ClearInstances,
DeleteVSwitch,
DeleteSecurityGroup,
DeleteVPC,
}
for _, name := range todolist {
DeleteFuncMap[name](a)
}
}
func (a *AliProvider) Reconcile() error {
if a.Infra.Annotations == nil {
a.Infra.Annotations = make(map[string]string)
}
if a.Infra.DeletionTimestamp != nil {
logger.Info("DeletionTimestamp not nil Clear Infra")
a.ClearCluster()
return nil
}
todolist := []ActionName{
CreateVPC,
GetSystemInfo,
CreateVSwitch,
CreateSecurityGroup,
ReconcileInstance,
BindEIP,
}
for _, actionname := range todolist {
err := RecocileFuncMap[actionname](a)
if err != nil {
return err
}
}
return nil
}
func (a *AliProvider) Apply() error {
if err := v2.Default(a.Infra, defaultInfra); err != nil {
return err
}
if err := validation.ValidateInfra(a.Infra); len(err) != 0 {
return err.ToAggregate()
}
return a.Reconcile()
}
func defaultInfra(infra *v2.Infra) error {
//https://help.aliyun.com/document_detail/63440.htm?spm=a2c4g.11186623.0.0.f5952752gkxpB7#t9856.html
if infra.Spec.Instance.IsSeize {
infra.Status.SpotStrategy = "SpotAsPriceGo"
} else {
infra.Status.SpotStrategy = "NoSpot"
}
if infra.Spec.Platform == v2.ARM64 {
switch infra.Status.RegionID {
case "cn-shanghai":
infra.Status.ZoneID = "cn-shanghai-l"
case "cn-beijing":
infra.Status.ZoneID = "cn-beijing-k"
case "cn-hangzhou":
infra.Status.ZoneID = "cn-hangzhou-i"
default:
return errors.New("not available ZoneID for arm, support RegionID[cn-shanghai,cn-beijing,cn-hangzhou]")
}
infra.Spec.Instance.ImageID = defaultImageArmID
} else {
infra.Spec.Instance.ImageID = defaultImageAmdID
}
//"cloud_efficiency", "cloud_essd", "cloud_ssd"
if infra.Spec.Instance.SystemCategory == "" {
infra.Spec.Instance.SystemCategory = "cloud_efficiency"
}
if infra.Spec.Instance.DataCategory == "" {
infra.Spec.Instance.DataCategory = "cloud_efficiency"
}
return nil
}
+175
View File
@@ -0,0 +1,175 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 aliyun
import (
"errors"
"github.com/fanux/sealos/pkg/utils/logger"
"github.com/fanux/sealos/pkg/utils"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/vpc"
)
type VpcManager struct {
Config Config
Client *vpc.Client
}
func (a *AliProvider) RetryVpcRequest(request requests.AcsRequest, response responses.AcsResponse) error {
return utils.Retry(TryTimes, TrySleepTime, func() error {
err := a.VpcClient.DoAction(request, response)
if err != nil {
return err
}
return nil
})
}
func (a *AliProvider) CreateVPC() error {
request := vpc.CreateCreateVpcRequest()
request.Scheme = Scheme
request.RegionId = a.Infra.Status.RegionID
//response, err := d.Client.CreateVpc(request)
response := vpc.CreateCreateVpcResponse()
err := a.RetryVpcRequest(request, response)
if err != nil {
return err
}
a.Infra.Status.VpcID = response.VpcId
return nil
}
func (a *AliProvider) DeleteVPC() error {
request := vpc.CreateDeleteVpcRequest()
request.Scheme = Scheme
request.VpcId = a.Infra.Status.VpcID
//response, err := d.Client.DeleteVpc(request)
response := vpc.CreateDeleteVpcResponse()
return a.RetryVpcRequest(request, response)
}
func (a *AliProvider) CreateVSwitch() error {
request := vpc.CreateCreateVSwitchRequest()
request.Scheme = Scheme
request.ZoneId = a.Infra.Status.ZoneID
request.CidrBlock = CidrBlock
request.VpcId = a.Infra.Status.VpcID
request.RegionId = a.Infra.Status.RegionID
//response, err := d.Client.CreateVSwitch(request)
response := vpc.CreateCreateVSwitchResponse()
err := a.RetryVpcRequest(request, response)
if err != nil {
return err
}
a.Infra.Status.VSwitchID = response.VSwitchId
return nil
}
func (a *AliProvider) DeleteVSwitch() error {
request := vpc.CreateDeleteVSwitchRequest()
request.Scheme = Scheme
request.VSwitchId = a.Infra.Status.VSwitchID
response := vpc.CreateDeleteVSwitchResponse()
return a.RetryVpcRequest(request, response)
}
func (a *AliProvider) SystemInfo() error {
availableInstance, err := a.GetAvailableResourcesForSystem()
if err != nil {
return err
}
a.Infra.Spec.Instance.Type = availableInstance.InstanceType
a.Infra.Status.MasterInstanceType = availableInstance.InstanceType
a.Infra.Status.NodeInstanceType = availableInstance.InstanceType
a.Infra.Status.ZoneID = availableInstance.ZoneID
logger.Info("fetch resource success %s: %s", "ZoneID", a.Infra.Status.ZoneID)
logger.Info("fetch resource success %s: %s", "InstanceType", a.Infra.Spec.Instance.Type)
return nil
}
func (a *AliProvider) BindEipForMaster0() error {
instances, err := a.GetInstancesInfo(Master, JustGetInstanceInfo)
if err != nil {
return err
}
if len(instances) == 0 {
return errors.New("can not find master0 ")
}
master0 := instances[0]
eIP, eIPID, err := a.AllocateEipAddress()
if err != nil {
return err
}
err = a.AssociateEipAddress(master0.InstanceID, eIPID)
if err != nil {
return err
}
a.Infra.Status.EIP = eIP
a.Infra.Status.EIPID = eIPID
a.Infra.Status.Master0ID = master0.InstanceID
a.Infra.Status.Master0InternalIP = master0.PrimaryIPAddress
return nil
}
func (a *AliProvider) AllocateEipAddress() (eIP, eIPID string, err error) {
request := vpc.CreateAllocateEipAddressRequest()
request.Scheme = Scheme
request.Bandwidth = Bandwidth
request.InternetChargeType = InternetChargeType
response := vpc.CreateAllocateEipAddressResponse()
err = a.RetryVpcRequest(request, response)
if err != nil {
return "", "", err
}
return response.EipAddress, response.AllocationId, nil
}
func (a *AliProvider) AssociateEipAddress(instanceID, eipID string) error {
request := vpc.CreateAssociateEipAddressRequest()
request.Scheme = Scheme
request.InstanceId = instanceID
request.AllocationId = eipID
response := vpc.CreateAssociateEipAddressResponse()
return a.RetryVpcRequest(request, response)
}
func (a *AliProvider) UnassociateEipAddress() error {
request := vpc.CreateUnassociateEipAddressRequest()
request.Scheme = Scheme
request.AllocationId = a.Infra.Status.EIPID
request.Force = requests.NewBoolean(true)
response := vpc.CreateUnassociateEipAddressResponse()
return a.RetryVpcRequest(request, response)
}
func (a *AliProvider) ReleaseEipAddress() error {
err := a.UnassociateEipAddress()
if err != nil {
return err
}
request := vpc.CreateReleaseEipAddressRequest()
request.Scheme = Scheme
request.AllocationId = a.Infra.Status.EIPID
response := vpc.CreateReleaseEipAddressResponse()
return a.RetryVpcRequest(request, response)
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 infra
import (
"fmt"
"github.com/fanux/sealos/pkg/infra/aliyun"
v2 "github.com/fanux/sealos/pkg/types/v1beta1"
)
type Interface interface {
// Apply apply iaas resources and save metadata info like vpc instance id to cluster status
// https://github.com/fanux/sealgate/tree/master/cloud
Apply() error
}
func newAliProvider(infra *v2.Infra) (Interface, error) {
config := new(aliyun.Config)
err := aliyun.LoadConfig(config)
if err != nil {
return nil, err
}
aliProvider := new(aliyun.AliProvider)
aliProvider.Config = *config
aliProvider.Infra = infra
err = aliProvider.NewClient()
if err != nil {
return nil, err
}
return aliProvider, nil
}
func NewDefaultProvider(infra *v2.Infra) (Interface, error) {
switch infra.Spec.Provider {
case v2.AliyunProvider:
return newAliProvider(infra)
default:
return nil, fmt.Errorf("the provider is invalid, please set the provider correctly")
}
}
+123
View File
@@ -0,0 +1,123 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 infra
import (
"fmt"
"os"
"testing"
"time"
"sigs.k8s.io/yaml"
v2 "github.com/fanux/sealos/pkg/types/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestApply(t *testing.T) {
//setup infra
password := os.Getenv("SealosPassword")
infra := v2.Infra{
TypeMeta: metav1.TypeMeta{
Kind: "Infra",
APIVersion: v2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "my-infra",
},
Spec: v2.InfraSpec{
Instance: v2.Instance{
IsSeize: true,
Type: "ecs.c6r.large",
},
Platform: v2.ARM64,
Masters: v2.Hosts{
Count: 1,
CPU: 2,
Memory: 4,
Disks: v2.Disks{
System: "100",
Data: []string{"100"},
},
},
Nodes: &v2.Hosts{
Count: 1,
CPU: 2,
Memory: 4,
Disks: v2.Disks{
System: "100",
Data: []string{"100"},
},
},
Provider: v2.AliyunProvider,
Auth: v2.Auth{
Passwd: password,
},
},
}
aliProvider, err := NewDefaultProvider(&infra)
if err != nil {
fmt.Printf("%v", err)
} else {
fmt.Printf("%v", aliProvider.Apply())
}
t.Run("modify instance type", func(t *testing.T) {
infra.Spec.Masters.CPU = 4
infra.Spec.Masters.Memory = 8
infra.Spec.Nodes.CPU = 4
infra.Spec.Nodes.Memory = 8
fmt.Printf("%v", aliProvider.Apply())
})
t.Run("add instance count", func(t *testing.T) {
infra.Spec.Masters.Count = 5
infra.Spec.Nodes.Count = 5
fmt.Printf("%v", aliProvider.Apply())
fmt.Printf("%v \n", infra.Spec.Masters)
fmt.Printf("%v \n", infra.Spec.Nodes)
})
t.Run("reduce instance count", func(t *testing.T) {
infra.Spec.Masters.Count = 1
infra.Spec.Nodes.Count = 1
fmt.Printf("%v", aliProvider.Apply())
})
t.Run("modify instance type & count both", func(t *testing.T) {
infra.Spec.Masters.CPU = 8
infra.Spec.Masters.Memory = 16
infra.Spec.Nodes.CPU = 8
infra.Spec.Nodes.Memory = 16
infra.Spec.Masters.Count = 5
infra.Spec.Nodes.Count = 5
fmt.Printf("%v", aliProvider.Apply())
})
// todo
t.Run("modify instance system disk", func(t *testing.T) {
})
j, _ := yaml.Marshal(&infra)
t.Log("output yaml:", string(j))
//teardown
time.Sleep(20 * time.Second)
now := metav1.Now()
infra.ObjectMeta.DeletionTimestamp = &now
t.Log(fmt.Sprintf("%v", aliProvider.Apply()))
}
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"fmt"
"os"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/cni"
+1 -1
View File
@@ -20,7 +20,7 @@ import (
"strings"
"sync"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
-202
View File
@@ -1,202 +0,0 @@
// Copyright © 2021 sealos.
//
// 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 install
import (
"fmt"
"os"
"strings"
v1 "github.com/fanux/sealos/pkg/types/v1"
"github.com/fanux/sealos/pkg/utils/logger"
"github.com/fanux/sealgate/cloud"
extver "github.com/linuxsuren/cobra-extension/version"
)
//VersionURL is base64 encode k8s version and offline package url
var (
VersionURL string
URLMap map[string]string
DefaultURL = "https://sealyun.oss-cn-beijing.aliyuncs.com/37374d999dbadb788ef0461844a70151-1.16.0/kube1.16.0.tar.gz"
)
//Flags is command line paras
type Flags struct {
Master int
MasterType string
Node int
NodeType string
Version string
Flavor string
Passwd string
Zone string
Interaction bool
Image string
}
// Cluster is cluster metadata
type Cluster struct {
cloud.Config
Flags
Name string
Masters []cloud.VM
Nodes []cloud.VM
VPCID string
SwitchID string
SecuretyGroupID string
}
var C Cluster
var ClusterDir = v1.DefaultConfigPath + "/clusters/"
// 2019.11.28 今天刚修完陪产假,在新装修的公寓中写代码,刚配的眼镜感觉带着有点不舒服,看屏幕不是很清楚
/*
配眼镜的人也不是很专业,二宝还是个女儿,非常可爱而且非常乖,不像大宝那么吵。 一直很想写日记但是不知道往哪里写合适
既然github要把代码存两千年那为啥不写到代码里,如此这便成为我第一篇代码日记。
碳纤维地暖开了半天还是冰凉的,感觉是被忽悠了。
一写代码就精神万分,一搞管理上的杂事就效率很低,所以做技术还是要专注些。
*/
func CloudInstall(c *Cluster) {
URLMap = make(map[string]string)
URLMap["v1.16.0"] = DefaultURL
config := c.Config
p := cloud.NewProvider(config)
_ = v1.Dump(fmt.Sprintf("%s%s.yaml", ClusterDir, c.Name), c)
//TODO concurrence create master and nodes vms, should not create two vpcs
/*
var wg sync.WaitGroup
wg.Add(2)
go func() {
// create masters vms
res, err := p.Create(newRequest(c, "master", true, c.Master))
if err != nil {
logger.Error("init cluster failed: %s", err)
return
}
c.Masters = res.VMs
c.VPCID = res.VPCID
c.SwitchID = res.SwitchID
c.SecuretyGroupID = res.SecuretyGroupID
wg.Done()
}()
go func() {
// create nodes vms
res, err := p.Create(newRequest(c, "node", false, c.Node))
if err != nil {
logger.Error("init cluster failed: %s", err)
return
}
c.Nodes = res.VMs
wg.Done()
}()
wg.Wait()
*/
// create masters vms
res, err := p.Create(newRequest(c, "master", true, c.Master))
if err != nil {
logger.Error("init cluster failed: %s", err)
return
}
c.Masters = res.VMs
c.VPCID = res.VPCID
c.SwitchID = res.SwitchID
c.SecuretyGroupID = res.SecuretyGroupID
// create nodes vms
res, err = p.Create(newRequest(c, "node", false, c.Node))
if err != nil {
logger.Error("init cluster failed: %s", err)
return
}
c.Nodes = res.VMs
//TODO wget package on master0 and scp to other nodes
logger.Info("wait few minute for download offline package on master0...")
cmd := newWgetCommand(c)
CmdWorkSpace(c.Masters[0].FIP, cmd, "/root")
// exec sealos init on master0
cmd = newCommand(c)
CmdWorkSpace(c.Masters[0].FIP, cmd, "/root")
}
func getURL(version string) string {
url, ok := URLMap[version]
if !ok {
logger.Error("version offline package not found: %s", version)
os.Exit(1)
return DefaultURL
}
return url
}
func getLocalURL(version string) string {
return fmt.Sprintf("/root/kube%s.tar.gz", version[1:])
}
func newCommand(c *Cluster) string {
//TODO should download it on master0 and copy to other nodes
version := extver.GetVersion()
if strings.HasPrefix(version, "v") {
version = strings.TrimPrefix(version, "v")
}
releaseURL := fmt.Sprintf("https://github.com/fanux/sealos/releases/download/v%s/sealos_%s_linux_amd64.tar.gz",
version, version)
cmd := fmt.Sprintf("wget %s -O -| tar -xz && chmod +x sealos", releaseURL)
cmd += fmt.Sprintf(" && ./sealos init --passwd %s --pkg-url %s --version %s", c.Passwd, getLocalURL(c.Version), c.Version)
for _, master := range c.Masters {
cmd += fmt.Sprintf(" --master %s", master.IP)
}
for _, node := range c.Nodes {
cmd += fmt.Sprintf(" --node %s", node.IP)
}
return cmd
}
func newWgetCommand(c *Cluster) string {
cmd := fmt.Sprintf("cd /root && wget %s", getURL(c.Version))
return cmd
}
func newRequest(c *Cluster, namePrefix string, fip bool, num int) cloud.Request {
r := cloud.Request{
Num: num,
Image: c.Flags.Image,
NamePrefix: namePrefix,
FIP: fip,
Flavor: c.Flags.Flavor,
Passwd: c.Flags.Passwd,
ZoneID: c.Flags.Zone,
VPCID: c.VPCID,
SwitchID: c.SwitchID,
SecuretyGroupID: c.SecuretyGroupID,
}
return r
}
// CmdWorkSpace exec cmd on specified workdir.
func CmdWorkSpace(node, cmd, workdir string) {
command := fmt.Sprintf("cd %s && %s", workdir, cmd)
_ = v1.SSHConfig.CmdAsync(node, command)
}
+1 -1
View File
@@ -22,7 +22,7 @@ import (
"sync"
"time"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+1 -1
View File
@@ -23,7 +23,7 @@ import (
"sync"
"time"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+8 -1
View File
@@ -15,11 +15,12 @@
package install
import (
"fmt"
"os"
"strings"
"sync"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/kubernetes/nodeclient"
@@ -154,3 +155,9 @@ func (e *ExecFlag) execByNodeIP() {
}
wg.Wait()
}
// CmdWorkSpace exec cmd on specified workdir.
func CmdWorkSpace(node, cmd, workdir string) {
command := fmt.Sprintf("cd %s && %s", workdir, cmd)
_ = v1.SSHConfig.CmdAsync(node, command)
}
+1 -1
View File
@@ -15,7 +15,7 @@
package install
import (
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/logger"
)
+1 -1
View File
@@ -20,7 +20,7 @@ import (
"strings"
"text/template"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/logger"
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"reflect"
"testing"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+1 -1
View File
@@ -24,7 +24,7 @@ import (
"path/filepath"
"strings"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"strings"
"sync"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"fmt"
"strings"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/cni"
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"fmt"
"path"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
)
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"os"
"time"
v1 "github.com/fanux/sealos/pkg/types/v1"
v1 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
nodeclient2 "github.com/fanux/sealos/pkg/kubernetes/nodeclient"
-37
View File
@@ -1,37 +0,0 @@
/*
Copyright 2014 The Kubernetes 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 version
// Info contains versioning information.
// TODO: Add []string of api versions supported? It's still unclear
// how we'll want to distribute that information.
type Info struct {
Major string `json:"major"`
Minor string `json:"minor"`
GitVersion string `json:"gitVersion"`
GitCommit string `json:"gitCommit"`
GitTreeState string `json:"gitTreeState"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
}
// String returns info as a human-friendly version string.
func (info Info) String() string {
return info.GitVersion
}
+1 -1
View File
@@ -228,7 +228,7 @@ func validateKubeConfig(outDir, filename string, config *clientcmdapi.Config) er
}
currentCluster := currentCtx.Cluster
if currentConfig.Clusters[currentCluster] == nil {
return errors.Errorf("failed to find the given CurrentContext Cluster in Clusters of the kubeconfig file %s", kubeConfigFilePath)
return errors.Errorf("failed to find the given CurrentContext Infra in Clusters of the kubeconfig file %s", kubeConfigFilePath)
}
// Make sure the compared CAs are whitespace-trimmed. The function clientcmd.LoadFromFile() just decodes
+1 -1
View File
@@ -16,7 +16,7 @@ package kubeconfig
import clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
// GetClusterFromKubeConfig returns the default Cluster of the specified KubeConfig
// GetClusterFromKubeConfig returns the default Infra of the specified KubeConfig
func GetClusterFromKubeConfig(config *clientcmdapi.Config) *clientcmdapi.Cluster {
// If there is an unnamed cluster object, use it
if config.Clusters[""] != nil {
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"fmt"
"time"
v12 "github.com/fanux/sealos/pkg/types/v1"
v12 "github.com/fanux/sealos/pkg/types/v1alpha1"
"github.com/fanux/sealos/pkg/utils"
v1 "k8s.io/api/core/v1"
@@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package v1
package v1alpha1
import (
"fmt"
"io/ioutil"
"os"
"sigs.k8s.io/yaml"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/cni"
"github.com/fanux/sealos/pkg/utils/logger"
v2 "gopkg.in/yaml.v2"
)
const (
@@ -44,40 +44,40 @@ type Metadata struct {
// SealConfig for ~/.sealos/config.yaml
type SealConfig struct {
Masters []string
Nodes []string
Masters []string `json:"masters"`
Nodes []string `json:"nodes"`
//config from kubeadm.cfg. ex. cluster.local
DNSDomain string
APIServerCertSANs []string
DNSDomain string `json:"dnsdomain"`
APIServerCertSANs []string `json:"apiservercertsans"`
//SSHConfig
User string
Passwd string
PrivateKey string
PkPassword string
User string `json:"user"`
Passwd string `json:"passwd"`
PrivateKey string `json:"privatekey"`
PkPassword string `json:"pkpassword"`
//ApiServer ex. apiserver.cluster.local
APIServerDomain string
Network string
VIP string
PkgURL string
Version string
Repo string
PodCIDR string
SvcCIDR string
APIServerDomain string `json:"apiserverdomain"`
Network string `json:"network"`
VIP string `json:"vip"`
PkgURL string `json:"pkgurl"`
Version string `json:"version"`
Repo string `json:"repo"`
PodCIDR string `json:"podcidr"`
SvcCIDR string `json:"svccidr"`
//certs location
CertPath string
CertEtcdPath string
CertPath string `json:"certpath"`
CertEtcdPath string `json:"certetcdpath"`
//lvscare images
LvscareName string
LvscareTag string
AliOss
LvscareName string `json:"lvscarename"`
LvscareTag string `json:"lvscaretag"`
AliOss `json:"alioss"`
}
type AliOss struct {
OssEndpoint string
AccessKeyID string
AccessKeySecrets string
BucketName string
ObjectPath string
OssEndpoint string `json:"ossendpoint"`
AccessKeyID string `json:"accesskeyid"`
AccessKeySecrets string `json:"accesskeysecrets"`
BucketName string `json:"bucketname"`
ObjectPath string `json:"objectpath"`
}
//Dump is
@@ -115,7 +115,7 @@ func (c *SealConfig) Dump(path string) {
c.AliOss.OssEndpoint = OssEndpoint
c.AliOss.BucketName = BucketName
c.AliOss.ObjectPath = ObjectPath
y, err := v2.Marshal(c)
y, err := yaml.Marshal(c)
if err != nil {
logger.Error("dump config file failed: %s", err)
}
@@ -131,7 +131,7 @@ func (c *SealConfig) Dump(path string) {
}
func Dump(path string, content interface{}) error {
y, err := v2.Marshal(content)
y, err := yaml.Marshal(content)
if err != nil {
logger.Error("dump config file failed: %s", err)
return err
@@ -157,7 +157,7 @@ func (c *SealConfig) Load(path string) (err error) {
return fmt.Errorf("read config file %s failed %w", path, err)
}
err = v2.Unmarshal(y, c)
err = yaml.Unmarshal(y, c)
if err != nil {
return fmt.Errorf("unmarshal config file failed: %w", err)
}
@@ -203,7 +203,7 @@ func Load(path string, content interface{}) error {
os.Exit(0)
}
err = v2.Unmarshal(y, content)
err = yaml.Unmarshal(y, content)
if err != nil {
logger.Error("unmarshal config file failed: %s", err)
}
@@ -231,7 +231,7 @@ func (c *SealConfig) ShowDefaultConfig() {
c.LvscareName = "fanux/lvscare"
c.LvscareTag = "latest"
y, err := v2.Marshal(c)
y, err := yaml.Marshal(c)
if err != nil {
logger.Error("marshal config file failed: %s", err)
}
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package v1
package v1alpha1
import (
"strconv"
+67
View File
@@ -0,0 +1,67 @@
/*
Copyright 2021 cuisongliu@qq.com.
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 v1beta1
import (
"math/rand"
"time"
)
func Default(infra *Infra, fn func(infra *Infra) error) error {
if string(infra.Spec.Platform) == "" {
infra.Spec.Platform = AMD64
}
if infra.Spec.Auth.User == "" {
infra.Spec.Auth.User = "root"
}
if infra.Spec.Masters.CPU <= 0 {
infra.Spec.Masters.CPU = 2
}
if infra.Spec.Masters.Memory <= 0 {
infra.Spec.Masters.Memory = 4
}
if len(infra.Spec.Masters.Disks.System) == 0 {
infra.Spec.Masters.Disks.System = "40"
}
if infra.Spec.Auth.Passwd == "" {
infra.Spec.Auth.Passwd = createPassword()
}
return fn(infra)
}
const (
digits = "0123456789"
specials = "~=+%^*/()[]{}/!@#$?|"
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
passwordLength = 16
)
func createPassword() string {
rand.Seed(time.Now().UnixNano())
all := digits + specials + letter
length := passwordLength
buf := make([]byte, length)
buf[0] = digits[rand.Intn(len(digits))]
buf[1] = specials[rand.Intn(len(specials))]
for i := 2; i < length; i++ {
buf[i] = all[rand.Intn(len(all))]
}
rand.Shuffle(len(buf), func(i, j int) {
buf[i], buf[j] = buf[j], buf[i]
})
return string(buf)
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright © 2021 sealos.
//
// 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.
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=false
// +k8s:defaulter-gen=TypeMeta
// +groupName=apps.sealyun.com
package v1beta1
+25
View File
@@ -0,0 +1,25 @@
// Copyright © 2021 sealos.
//
// 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 v1beta1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "apps.sealyun.com"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
+123
View File
@@ -0,0 +1,123 @@
// Copyright © 2021 sealos.
//
// 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 v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
type Provider string
const (
AliyunProvider Provider = "AliyunProvider"
)
type Platform string
const (
AMD64 Platform = "amd64"
ARM64 Platform = "arm64"
)
type Auth struct {
User string `json:"user,omitempty"`
Passwd string `json:"passwd,omitempty"`
}
type Hosts struct {
CPU int `json:"cpu,omitempty"`
Memory float64 `json:"memory,omitempty"`
Count int `json:"count,omitempty"`
Disks Disks `json:"disks"`
}
type Disks struct {
System string `json:"system,omitempty"`
Data []string `json:"data,omitempty"`
}
type Instance struct {
SystemCategory string `json:"systemCategory,omitempty"`
DataCategory string `json:"dataCategory,omitempty"`
Type string `json:"type,omitempty"`
IsSeize bool `json:"isSeize,omitempty"`
ImageID string `json:"imageID,omitempty"`
}
// InfraSpec defines the desired state of Infra
type InfraSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of Infra
// Important: Run "make" to regenerate code after modifying this file
Instance Instance `json:"instance"`
// Foo is an example field of Infra. Edit types.go to remove/update
Provider Provider `json:"provider,omitempty"`
Platform Platform `json:"platform,omitempty"`
Auth Auth `json:"auth,omitempty"`
Masters Hosts `json:"masters,omitempty"`
Nodes *Hosts `json:"nodes,omitempty"`
}
// InfraStatus defines the observed state of Infra
type InfraStatus struct {
ZoneID string `json:"zoneID,omitempty"`
RegionID string `json:"regionID,omitempty"`
VpcID string `json:"vpcID,omitempty"`
VSwitchID string `json:"vSwitchID,omitempty"`
SecurityGroupID string `json:"securityGroupID,omitempty"`
Master0ID string `json:"master0ID,omitempty"`
Master0InternalIP string `json:"master0InternalIP,omitempty"`
EIP string `json:"eip,omitempty"`
EIPID string `json:"eipID,omitempty"`
MasterIDs string `json:"masterIDs,omitempty"`
NodeIDs string `json:"nodeIDs,omitempty"`
Masters []string `json:"masters,omitempty"`
Nodes []string `json:"nodes,omitempty"`
MasterInstanceType string `json:"masterInstanceType,omitempty"`
NodeInstanceType string `json:"nodeInstanceType,omitempty"`
SpotStrategy string `json:"spotStrategy,omitempty"`
ShouldBeDeleteInstancesIDs string `json:"shouldBeDeleteInstancesIDs,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Infra is the Schema for the Infras API
type Infra struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec InfraSpec `json:"spec,omitempty"`
Status InfraStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// InfraList contains a list of Infra
type InfraList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Infra `json:"items"`
}
+204
View File
@@ -0,0 +1,204 @@
// +build !ignore_autogenerated
// Copyright © 2021 sealos.
//
// 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.
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1beta1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Auth) DeepCopyInto(out *Auth) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth.
func (in *Auth) DeepCopy() *Auth {
if in == nil {
return nil
}
out := new(Auth)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Disks) DeepCopyInto(out *Disks) {
*out = *in
if in.Data != nil {
in, out := &in.Data, &out.Data
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Disks.
func (in *Disks) DeepCopy() *Disks {
if in == nil {
return nil
}
out := new(Disks)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Hosts) DeepCopyInto(out *Hosts) {
*out = *in
in.Disks.DeepCopyInto(&out.Disks)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Hosts.
func (in *Hosts) DeepCopy() *Hosts {
if in == nil {
return nil
}
out := new(Hosts)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Infra) DeepCopyInto(out *Infra) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Infra.
func (in *Infra) DeepCopy() *Infra {
if in == nil {
return nil
}
out := new(Infra)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Infra) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfraList) DeepCopyInto(out *InfraList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Infra, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfraList.
func (in *InfraList) DeepCopy() *InfraList {
if in == nil {
return nil
}
out := new(InfraList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *InfraList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfraSpec) DeepCopyInto(out *InfraSpec) {
*out = *in
out.Instance = in.Instance
out.Auth = in.Auth
in.Masters.DeepCopyInto(&out.Masters)
if in.Nodes != nil {
in, out := &in.Nodes, &out.Nodes
*out = new(Hosts)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfraSpec.
func (in *InfraSpec) DeepCopy() *InfraSpec {
if in == nil {
return nil
}
out := new(InfraSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfraStatus) DeepCopyInto(out *InfraStatus) {
*out = *in
if in.Masters != nil {
in, out := &in.Masters, &out.Masters
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Nodes != nil {
in, out := &in.Nodes, &out.Nodes
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfraStatus.
func (in *InfraStatus) DeepCopy() *InfraStatus {
if in == nil {
return nil
}
out := new(InfraStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Instance) DeepCopyInto(out *Instance) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance.
func (in *Instance) DeepCopy() *Instance {
if in == nil {
return nil
}
out := new(Instance)
in.DeepCopyInto(out)
return out
}
+94
View File
@@ -0,0 +1,94 @@
// Copyright © 2021 sealos.
//
// 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 validation
import (
"github.com/fanux/sealos/pkg/types/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// ValidateInfraName validates that the given name can be used as a infra name.
var ValidateInfraName = apimachineryvalidation.NameIsDNSSubdomain
func validateHosts(hosts *v1beta1.Hosts, fldPath *field.Path) field.ErrorList {
allErrors := field.ErrorList{}
if hosts.Count == 0 {
allErrors = append(allErrors, field.Invalid(fldPath.Key("count"), hosts.Count,
"hosts count not set"))
}
if hosts.CPU == 0 {
allErrors = append(allErrors, field.Invalid(fldPath.Key("cpu"), hosts.Count,
"hosts cpu not set"))
}
if hosts.Memory == 0 {
allErrors = append(allErrors, field.Invalid(fldPath.Key("memory"), hosts.Count,
"hosts memory not set"))
}
if len(hosts.Disks.System) == 0 {
allErrors = append(allErrors, field.Invalid(fldPath.Child("disks").Key("system"), hosts.Count,
"hosts system disk not set"))
}
return allErrors
}
func ValidateInfra(infra *v1beta1.Infra) field.ErrorList {
allErrors := apimachineryvalidation.ValidateObjectMeta(&infra.ObjectMeta, false, ValidateInfraName, field.NewPath("metadata"))
allErrors = append(allErrors, validateInfraSpec(&infra.Spec, field.NewPath("spec"))...)
return allErrors
}
func validateInfraSpec(spec *v1beta1.InfraSpec, fldPath *field.Path) field.ErrorList {
allErrors := field.ErrorList{}
allErrors = append(allErrors, validateHosts(&spec.Masters, fldPath.Child("masters"))...)
if spec.Nodes != nil {
allErrors = append(allErrors, validateHosts(spec.Nodes, fldPath.Child("nodes"))...)
}
switch spec.Platform {
case v1beta1.ARM64:
case v1beta1.AMD64:
default:
allErrors = append(allErrors, field.Invalid(fldPath.Key("platform"), spec.Platform,
"spec platform not support"))
}
return allErrors
}
func ValidateInfraUpdate(infra, oldInfra *v1beta1.Infra) field.ErrorList {
allErrs := apimachineryvalidation.ValidateObjectMetaUpdate(&infra.ObjectMeta, &oldInfra.ObjectMeta, field.NewPath("metadata"))
newInfraClone := infra.DeepCopy()
if newInfraClone.Spec.Provider != oldInfra.Spec.Provider {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Key("provider"), "fields can't modify are forbidden"))
}
if newInfraClone.Spec.Platform != oldInfra.Spec.Platform {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Key("platform"), "fields can't modify are forbidden"))
}
if !apiequality.Semantic.DeepEqual(newInfraClone.Spec.Auth, oldInfra.Spec.Auth) {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Key("auth"), "fields can't modify are forbidden"))
}
if !apiequality.Semantic.DeepEqual(newInfraClone.Spec.Masters.Disks, oldInfra.Spec.Masters.Disks) {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Child("masters").Key("disks"), "fields can't modify are forbidden"))
}
if newInfraClone.Spec.Nodes != nil && oldInfra.Spec.Nodes != nil {
if !apiequality.Semantic.DeepEqual(newInfraClone.Spec.Nodes.Disks, oldInfra.Spec.Nodes.Disks) {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Child("nodes").Key("disks"), "fields can't modify are forbidden"))
}
}
return allErrs
}
+6 -10
View File
@@ -17,13 +17,11 @@ package utils
import (
"fmt"
"os"
"github.com/fanux/sealos/pkg/utils/logger"
)
const md5sumCmd = "md5sum %s | cut -d\" \" -f1"
func FromLocal(localPath string) string {
func Md5File(localPath string) string {
cmd := fmt.Sprintf(md5sumCmd, localPath)
return BashEval(cmd)
}
@@ -37,13 +35,11 @@ func UserHomeDir() string {
return home
}
func FileExist(filename string) bool {
_, err := os.Stat(filename)
if !os.IsNotExist(err) {
if err == nil {
return true
}
logger.Warn(err)
func FileExist(path string) bool {
_, err := os.Stat(path)
if err == nil || os.IsExist(err) {
return true
}
return false
}
+195
View File
@@ -0,0 +1,195 @@
// Copyright © 2021 sealos.
//
// 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 utils
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"strings"
"github.com/fanux/sealos/pkg/utils/logger"
)
type HostFile struct {
Path string
Hosts map[string]*Hostname
}
type Hostname struct {
Comment string
Domain string
IP string
}
func NewHostname(comment string, domain string, ip string) *Hostname {
return &Hostname{comment, domain, ip}
}
func (h *HostFile) Add(host *Hostname) {
if h.Hosts == nil {
h.Hosts = make(map[string]*Hostname)
}
h.Hosts[host.Domain] = host
}
func (h *HostFile) Delete(host string) {
delete(h.Hosts, host)
}
func getHostPath() string {
path := os.Getenv("GOHOST_FILE")
if path == "" {
path = "/etc/hosts"
}
return path
}
func (h *Hostname) toString() string {
if len(h.Comment) > 0 {
h.Comment += "\n"
}
return h.Comment + h.IP + " " + h.Domain + "\n"
}
func appendToFile(filePath string, hostname *Hostname) {
fp, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
logger.Warn("failed opening file %s : %s\n", filePath, err)
return
}
defer fp.Close()
_, err = fp.WriteString(hostname.toString())
if err != nil {
logger.Warn("failed append string: %s: %s\n", filePath, err)
return
}
}
func (h *HostFile) ParseHostFile(path string) (map[string]*Hostname, error) {
if !FileExist(path) {
logger.Warn("path %s is not exists", path)
return nil, errors.New("path %s is not exists")
}
fp, fpErr := os.Open(path)
if fpErr != nil {
logger.Warn("open file '%s' failed\n", path)
return nil, fmt.Errorf("open file '%s' failed ", path)
}
defer fp.Close()
br := bufio.NewReader(fp)
hostnameMap := make(map[string]*Hostname)
curComment := ""
for {
str, rErr := br.ReadString('\n')
if rErr == io.EOF {
break
}
if len(str) == 0 || str == "\r\n" || IsEmptyLine(str) {
continue
}
if str[0] == '#' {
// 处理注释
curComment += str
continue
}
tmpHostnameArr := strings.Fields(str)
curDomain := TrimWS(tmpHostnameArr[1])
if !CheckDomain(curDomain) {
return hostnameMap, errors.New(" file contain error domain" + curDomain)
}
curIP := TrimWS(tmpHostnameArr[0])
checkIP := CheckIP(curIP)
if !checkIP {
return hostnameMap, nil
}
tmpHostname := NewHostname(curComment, curDomain, curIP)
hostnameMap[tmpHostname.Domain] = tmpHostname
curComment = ""
}
return hostnameMap, nil
}
func (h *HostFile) AppendHost(domain string, ip string) {
if domain == "" || ip == "" {
return
}
hostname := NewHostname("", domain, ip)
appendToFile(getHostPath(), hostname)
}
func (h *HostFile) writeToFile(hostnameMap map[string]*Hostname, path string) {
if !FileExist(path) {
logger.Warn("path %s is not exists", path)
return
}
fp, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
logger.Warn("open file '%s' failed: %v", path, err)
return
}
defer fp.Close()
for _, mapVal := range hostnameMap {
_, writeErr := fp.WriteString(mapVal.toString())
if writeErr != nil {
logger.Warn(writeErr)
return
}
}
}
func (h *HostFile) DeleteDomain(domain string) {
if domain == "" {
return
}
currHostsMap, parseErr := h.ParseHostFile(getHostPath())
if parseErr != nil {
logger.Warn("parse file failed" + parseErr.Error())
return
}
if len(currHostsMap) == 0 || currHostsMap[domain] == nil {
logger.Warn("domain %s not exist\n", domain)
return
}
delete(currHostsMap, domain)
h.writeToFile(currHostsMap, getHostPath())
}
func (h *HostFile) ListCurrentHosts() {
currHostsMap, parseErr := h.ParseHostFile(getHostPath())
if parseErr != nil {
logger.Warn("parse file failed" + parseErr.Error())
return
}
if len(currHostsMap) == 0 {
return
}
for _, mapVal := range currHostsMap {
fmt.Println(mapVal.toString())
}
}
+1 -1
View File
@@ -32,7 +32,7 @@ func DownloadFile(location string) (filePATH, md5 string) {
location = absPATH
}
//file md5
md5 = FromLocal(location)
md5 = Md5File(location)
return location, md5
}
+28 -13
View File
@@ -20,7 +20,7 @@ import (
"fmt"
"math/big"
"net"
"os"
"net/url"
"strings"
"github.com/fanux/sealos/pkg/utils/logger"
@@ -87,24 +87,34 @@ func AssemblyIPList(args *string) error {
*args = result
return nil
}
func CheckIP(i string) bool {
if !strings.Contains(i, ":") {
return net.ParseIP(i) != nil
}
if _, err := net.ResolveTCPAddr("tcp", i); err != nil {
func CheckIP(ipStr string) bool {
host, _, err := net.SplitHostPort(ipStr)
if err != nil {
return false
}
return true
ip := net.ParseIP(host)
if _, err = net.ResolveTCPAddr("tcp", ipStr); err != nil {
return false
}
return ip != nil
}
//IPFormat is
func IPFormat(host string) string {
ipAndPort := strings.Split(host, ":")
if len(ipAndPort) != 2 {
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22", host)
os.Exit(1)
func IPFormat(ipStr string) string {
ip := net.ParseIP(ipStr)
if ip == nil {
host, _, err := net.SplitHostPort(ipStr)
if err != nil {
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22.error: %s", ipStr, err)
return ""
}
ip = net.ParseIP(host)
}
return ipAndPort[0]
if ip == nil {
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22", ipStr)
return ""
}
return ip.String()
}
func HostnameAndIP(node []string) ([]string, []string) {
@@ -166,3 +176,8 @@ func RemoveDeduplicate(a []string) []string {
}
return res
}
func CheckDomain(domain string) bool {
_, errURL := url.Parse(domain)
return errURL == nil
}
-1
View File
@@ -41,7 +41,6 @@ func (c *connLogger) Init(jsonConfig string) error {
if len(jsonConfig) == 0 {
return nil
}
fmt.Printf("consoleWriter Init:%s\n", jsonConfig)
err := json.Unmarshal([]byte(jsonConfig), c)
if err != nil {
return err
-2
View File
@@ -16,7 +16,6 @@ package logger
import (
"encoding/json"
"fmt"
"os"
"runtime"
"sync"
@@ -59,7 +58,6 @@ func (c *consoleLogger) Init(jsonConfig string) error {
if len(jsonConfig) == 0 {
return nil
}
fmt.Printf("consoleWriter Init:%s\n", jsonConfig)
err := json.Unmarshal([]byte(jsonConfig), c)
if runtime.GOOS == "windows" {
c.Colorful = false
+1 -1
View File
@@ -153,7 +153,7 @@ func (r *LocalLogger) SetLogger(adapterName string, configs ...string) error {
}
config := append(configs, "{}")[0]
var num int = -1
var num = -1
var i int
var l *nameLogger
for i, l = range r.outputs {
+33
View File
@@ -0,0 +1,33 @@
// Copyright © 2021 Alibaba Group Holding Ltd.
//
// 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 utils
import (
"fmt"
"time"
)
func Retry(tryTimes int, trySleepTime time.Duration, action func() error) error {
var err error
for i := 0; i < tryTimes; i++ {
err = action()
if err == nil {
return nil
}
time.Sleep(trySleepTime * time.Duration(2*i+1))
}
return fmt.Errorf("retry action timeout: %v", err)
}
+3 -3
View File
@@ -39,7 +39,7 @@ func (ss *SSH) CopyForMD5(host, localFilePath, remoteFilePath, md5 string) bool
//如果有md5则可以验证
//如果没有md5则拿到本地数据后验证
if md5 == "" {
md5 = utils.FromLocal(localFilePath)
md5 = utils.Md5File(localFilePath)
}
logger.Debug("[ssh]source file md5 value is %s", md5)
ss.Copy(host, localFilePath, remoteFilePath)
@@ -362,7 +362,7 @@ func (ss *SSH) copyLocalFileToRemote(host string, sshClient *ssh.Client, sftpCli
func (ss *SSH) isCopyMd5Success(sshClient *ssh.Client, localFile, remoteFile string) bool {
cmd := fmt.Sprintf("md5sum %s | cut -d\" \" -f1", remoteFile)
localMd5 := utils.FromLocal(localFile)
localMd5 := utils.Md5File(localFile)
sshSession, err := sshClient.NewSession()
if err != nil {
return false
@@ -399,7 +399,7 @@ func (ss *SSH) isCopyMd5Success(sshClient *ssh.Client, localFile, remoteFile str
}
func (ss *SSH) ValidateMd5sumLocalWithRemote(host, localFile, remoteFile string) bool {
localMd5 := utils.FromLocal(localFile)
localMd5 := utils.Md5File(localFile)
return localMd5 == ss.Md5Sum(host, remoteFile)
}
+3 -1
View File
@@ -14,7 +14,9 @@
package ssh
import "time"
import (
"time"
)
type SSH struct {
User string
+12 -1
View File
@@ -20,6 +20,7 @@ import (
"bytes"
"math/rand"
"net"
"regexp"
"sort"
"strings"
"time"
@@ -110,7 +111,7 @@ func ContainList(list []string, toComplete string) (containerList []string) {
// RandString 生成随机字符串
func RandString(len int) string {
var r *rand.Rand = rand.New(rand.NewSource(time.Now().Unix()))
var r = rand.New(rand.NewSource(time.Now().Unix()))
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := r.Intn(26) + 65
@@ -118,3 +119,13 @@ func RandString(len int) string {
}
return string(bytes)
}
func IsEmptyLine(str string) bool {
re := regexp.MustCompile(`^\s*$`)
return re.MatchString(str)
}
func TrimWS(str string) string {
return strings.Trim(str, " \n\t")
}
+30
View File
@@ -108,3 +108,33 @@ func VersionToIntAll(version string) int {
}
return 0
}
//VersionCompare is version compare
// if v1 >= v2 return true, else return false
func VersionCompare(v1, v2 string) bool {
v1 = strings.Replace(v1, "v", "", -1)
v2 = strings.Replace(v2, "v", "", -1)
v1 = strings.Split(v1, "-")[0]
v2 = strings.Split(v2, "-")[0]
v1List := strings.Split(v1, ".")
v2List := strings.Split(v2, ".")
if len(v1List) != 3 || len(v2List) != 3 {
logger.Error("error version format %s %s", v1, v2)
return false
}
if v1List[0] > v2List[0] {
return true
} else if v1List[0] < v2List[0] {
return false
}
if v1List[1] > v2List[1] {
return true
} else if v1List[1] < v2List[1] {
return false
}
if v1List[2] > v2List[2] {
return true
}
return true
}
+52
View File
@@ -0,0 +1,52 @@
// Copyright © 2021 sealos.
//
// 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 version
// Base version information.
//
// This is the fallback data used when version information from git is not
// provided via go ldflags. It provides an approximation of the Kubernetes
// version for ad-hoc builds (e.g. `go build`) that cannot get the version
// information from git.
//
// If you are looking at these fields in the git tree, they look
// strange. They are modified on the fly by the build process. The
// in-tree values are dummy values used for "git archive", which also
// works for GitHub tar downloads.
//
// When releasing a new Kubernetes version, this file is updated by
// build/mark_new_version.sh to reflect the new version, and then a
// git annotated tag (using format vX.Y where X == Major version and Y
// == Minor version) is created to point to the commit that updates
// component-base/version/base.go
var (
// semantic version, derived by build scripts (see
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/release/versioning.md
// for a detailed discussion of this field)
//
// TODO: This field is still called "gitVersion" for legacy
// reasons. For prerelease versions, the build metadata on the
// semantic version is a git hash, but the version itself is no
// longer the direct output of "git describe", but a slight
// translation to be semver compliant.
// NOTE: The $Format strings are replaced during 'git archive' thanks to the
// companion .gitattributes file containing 'export-subst' in this same
// directory. See also https://git-scm.com/docs/gitattributes
gitVersion = "latest"
gitCommit = "" // sha1 from git, output of $(git rev-parse HEAD)
buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
)
+32
View File
@@ -0,0 +1,32 @@
// Copyright © 2021 sealos.
//
// 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 version
// Info contains versioning information.
// TODO: Add []string of api versions supported? It's still unclear
// how we'll want to distribute that information.
type Info struct {
GitVersion string `json:"gitVersion"`
GitCommit string `json:"gitCommit,omitempty"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
}
// String returns info as a human-friendly version string.
func (info Info) String() string {
return info.GitVersion
}
+35
View File
@@ -0,0 +1,35 @@
// Copyright © 2021 sealos.
//
// 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 version
import (
"fmt"
"runtime"
)
// Get returns the overall codebase version. It's for detecting
// what code a binary was built from.
func Get() Info {
// These variables typically come from -ldflags settings and in
// their absence fallback to the settings in ./base.go
return Info{
GitVersion: gitVersion,
GitCommit: gitCommit,
BuildDate: buildDate,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
}
}
View File
View File
+50
View File
@@ -0,0 +1,50 @@
// Copyright © 2021 sealos.
//
// 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 testhelper
import (
"errors"
"fmt"
"io"
"os/exec"
"github.com/fanux/sealos/test/testhelper/settings"
"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
)
// Start sealos cmd and return *gexec.Session
func Start(cmdLine string) (*gexec.Session, error) {
if cmdLine == "" {
return nil, errors.New("failed to start cmd, line is empty")
}
cmdLine = fmt.Sprintf("sudo -E %s", cmdLine)
execCmd := exec.Command("/bin/bash", "-c", cmdLine) // #nosec
_, err := io.WriteString(ginkgo.GinkgoWriter, fmt.Sprintf("%s\n", cmdLine))
if err != nil {
return nil, err
}
return gexec.Start(execCmd, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
}
// RunCmdAndCheckResult start cmd and check expectedCode
func RunCmdAndCheckResult(cmdLine string, expectedCode int) *gexec.Session {
sess, err := Start(cmdLine)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Eventually(sess, settings.MaxWaiteTime).Should(gexec.Exit(expectedCode))
return sess
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright © 2021 sealos.
//
// 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 settings
import (
"os"
"path/filepath"
"time"
"github.com/mitchellh/go-homedir"
)
const (
SealerBinPath = "/usr/local/bin/sealos"
SubCmdInitOfSealos = "init"
DefaultSSHPassword = "Sealos123"
)
const (
FileMode0755 = 0755
FileMode0644 = 0644
)
var (
DefaultPollingInterval time.Duration
MaxWaiteTime time.Duration
DefaultWaiteTime time.Duration
DefaultSealosBin = ""
DefaultTestEnvDir = ""
AccessKey = os.Getenv("ACCESSKEYID")
AccessSecret = os.Getenv("ACCESSKEYSECRET")
)
func GetWorkDir() string {
home, err := homedir.Dir()
if err != nil {
return ""
}
return filepath.Join(home, ".sealos")
}
+42
View File
@@ -0,0 +1,42 @@
// Copyright © 2021 sealos.
//
// 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 settings
import (
"os"
"time"
)
// init test params and settings
func init() {
defaultWaiteTime := os.Getenv("DEFAULT_WAITE_TIME")
if defaultWaiteTime == "" {
DefaultWaiteTime = 300 * time.Second
} else {
DefaultWaiteTime, _ = time.ParseDuration(defaultWaiteTime)
}
maxWaiteTime := os.Getenv("MAX_WAITE_TIME")
if maxWaiteTime == "" {
MaxWaiteTime = 2400 * time.Second
} else {
MaxWaiteTime, _ = time.ParseDuration(maxWaiteTime)
}
pollingInterval := os.Getenv("DEFAULT_POLLING_INTERVAL")
if pollingInterval == "" {
DefaultPollingInterval = 10
}
}
+155
View File
@@ -0,0 +1,155 @@
// Copyright © 2021 sealos.
//
// 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 testhelper
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/fanux/sealos/pkg/types/v1beta1"
"github.com/fanux/sealos/pkg/utils"
"github.com/fanux/sealos/pkg/utils/ssh"
"github.com/fanux/sealos/test/testhelper/settings"
"github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
"sigs.k8s.io/yaml"
)
func GetPwd() string {
pwd, err := os.Getwd()
CheckErr(err)
return pwd
}
func CreateTempFile() string {
dir := os.TempDir()
file, err := ioutil.TempFile(dir, "tmpfile")
CheckErr(err)
defer CheckErr(file.Close())
return file.Name()
}
func RemoveTempFile(file string) {
CheckErr(os.Remove(file))
}
func WriteFile(fileName string, content []byte) error {
dir := filepath.Dir(fileName)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err = os.MkdirAll(dir, settings.FileMode0755); err != nil {
return err
}
}
if err := ioutil.WriteFile(fileName, content, settings.FileMode0644); err != nil {
return err
}
return nil
}
type SSHClient struct {
RemoteHostIP string
SSH *ssh.SSH
}
func NewSSHClientByInfra(infra *v1beta1.Infra) *SSHClient {
config := &ssh.SSH{
User: infra.Spec.Auth.User,
Password: infra.Spec.Auth.Passwd,
Timeout: nil,
}
return &SSHClient{
RemoteHostIP: infra.Status.EIP,
SSH: config,
}
}
func IsFileExist(filename string) bool {
_, err := os.Stat(filename)
return !os.IsNotExist(err)
}
func UnmarshalYamlFile(file string, obj interface{}) error {
data, err := ioutil.ReadFile(filepath.Clean(file))
if err != nil {
return err
}
err = yaml.Unmarshal(data, obj)
return err
}
func MarshalYamlToFile(file string, obj interface{}) error {
data, err := yaml.Marshal(obj)
if err != nil {
return err
}
if err = WriteFile(file, data); err != nil {
return err
}
return nil
}
// GetFileDataLocally get file data for cloud apply
func GetFileDataLocally(filePath string) string {
cmd := fmt.Sprintf("sudo -E cat %s", filePath)
result, _, err := utils.BashWithStdout(cmd)
CheckErr(err)
return result
}
// DeleteFileLocally delete file for cloud apply
func DeleteFileLocally(filePath string) {
cmd := fmt.Sprintf("sudo -E rm -rf %s", filePath)
_, err := utils.Bash(cmd)
CheckErr(err)
}
func CheckErr(err error) {
gomega.Expect(err).NotTo(gomega.HaveOccurred())
}
func CheckNotNil(obj interface{}) {
gomega.Expect(obj).NotTo(gomega.BeNil())
}
func CheckEqual(obj1 interface{}, obj2 interface{}) {
gomega.Expect(obj1).To(gomega.Equal(obj2))
}
func CheckNotEqual(obj1 interface{}, obj2 interface{}) {
gomega.Expect(obj1).NotTo(gomega.Equal(obj2))
}
func CheckExit0(sess *gexec.Session, waitTime time.Duration) {
gomega.Eventually(sess, waitTime).Should(gexec.Exit(0))
}
func CheckNotExit0(sess *gexec.Session, waitTime time.Duration) {
gomega.Eventually(sess, waitTime).ShouldNot(gexec.Exit(0))
}
func CheckFuncBeTrue(f func() bool, t time.Duration) {
gomega.Eventually(f(), t).Should(gomega.BeTrue())
}
func CheckBeTrue(b bool) {
gomega.Eventually(b).Should(gomega.BeTrue())
}
func CheckNotBeTrue(b bool) {
gomega.Eventually(b).ShouldNot(gomega.BeTrue())
}