mirror of
https://github.com/labring/sealos.git
synced 2026-09-01 15:38:06 +08:00
@@ -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
|
||||
|
||||
|
||||
@@ -12,3 +12,4 @@ dist
|
||||
.vscode
|
||||
test/Note.md
|
||||
.ossutil_checkpoint
|
||||
bin
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ linters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- revive
|
||||
- stylecheck
|
||||
- goconst
|
||||
- gosimple
|
||||
|
||||
+3
-3
@@ -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:
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# infra模块
|
||||
|
||||
根据Clusterfile里的定义去申请IaaS资源,保障IaaS资源与Clusterfile中的定义保持终态一致
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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()))
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
|
||||
@@ -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
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"}
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
|
||||
package ssh
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type SSH struct {
|
||||
User string
|
||||
|
||||
+12
-1
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
Reference in New Issue
Block a user