diff --git a/cmd/app/app.go b/cmd/app/app.go index 704162e..a21476a 100644 --- a/cmd/app/app.go +++ b/cmd/app/app.go @@ -17,7 +17,8 @@ package app import ( "fmt" - "github.com/99nil/diplomat/core/assistant" + "github.com/99nil/diplomat/pkg/common" + mgtAgent "github.com/99nil/diplomat/core/mgt/agent" mgtServer "github.com/99nil/diplomat/core/mgt/server" "github.com/99nil/diplomat/pkg/k8s" @@ -25,7 +26,6 @@ import ( "github.com/99nil/gopkg/ctr" "github.com/99nil/gopkg/server" - "github.com/docker/docker/client" "github.com/spf13/cobra" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" @@ -33,43 +33,34 @@ import ( ) func NewAssistant() *cobra.Command { + // TODO 二进制安装待测试 use := "assistant" - opt := NewOption(use) + opt := common.NewGlobalOption(use) cmd := &cobra.Command{ - Use: opt.Module, - Short: "Assistant", - SilenceUsage: true, - RunE: func(_ *cobra.Command, _ []string) error { - cfg := assistant.Environ(opt.EnvPrefix) - if err := server.ParseConfigWithEnv(opt.Config, cfg, opt.EnvPrefix); err != nil { - return fmt.Errorf("parse config failed: %v", err) - } - cfg.Complete() - if err := cfg.Validate(); err != nil { - return fmt.Errorf("validate config failed: %v", err) - } - loggerIns := logr.NewLogrusInstance(&cfg.Logger) - logr.SetDefault(loggerIns) - - logr.Infof("logger level: %v", logr.Level()) - logr.Debugf("%#v", cfg) - - dockerClient, err := client.NewClientWithOpts(client.FromEnv) - if err != nil { - return err - } - - return assistant.Run(cfg, dockerClient) - }, + Use: opt.Module, + Short: "Assistant", } + cmd.AddCommand( + NewAssistantInitCommand(opt), + NewAssistantJoinCommand(opt), + // TODO 优化,合并reset + NewAssistantCloudResetCommand(opt), + NewAssistantEdgeResetCommand(opt), + NewAssistantGetTokenCommand(opt), + NewVersionCommand(opt), + ) opt.CompleteFlags(cmd) + cmd.PersistentFlags().StringVar(&opt.KubeConfig, "kubeconfig", "/root/.kube/config", + "Use this key to set the Kubernetes config path") + cmd.PersistentFlags().BoolVarP(&opt.Verbose, "verbose", "v", true, + "verbose output") return cmd } func NewMgtServer() *cobra.Command { use := "mgt-server" - opt := NewOption(use) + opt := common.NewGlobalOption(use) cmd := &cobra.Command{ Use: opt.Module, Short: "Management Server", @@ -113,7 +104,7 @@ func NewMgtServer() *cobra.Command { func NewMgtAgent() *cobra.Command { use := "mgt-agent" - opt := NewOption(use) + opt := common.NewGlobalOption(use) cmd := &cobra.Command{ Use: opt.Module, Short: "Management Agent", diff --git a/cmd/app/gettoken.go b/cmd/app/gettoken.go new file mode 100644 index 0000000..0819a6e --- /dev/null +++ b/cmd/app/gettoken.go @@ -0,0 +1,58 @@ +// Copyright © 2022 99nil. +// +// 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 app + +import ( + "context" + "fmt" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/common" + + "github.com/spf13/cobra" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/flowcontrol" +) + +// NewAssistantGetTokenCommand Get token to join edge node to cloud +func NewAssistantGetTokenCommand(globalOpt *common.GlobalOption) *cobra.Command { + cmd := &cobra.Command{ + Use: "gettoken", + Short: "Get token to join edge node to cloud", + RunE: func(cmd *cobra.Command, args []string) error { + // init client + restConfig, err := clientcmd.BuildConfigFromFlags("", globalOpt.KubeConfig) + if err != nil { + return err + } + restConfig.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(1000, 1000) + kubeClient, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("init kubernetes client failed: %v", err) + } + + secret, err := kubeClient.CoreV1().Secrets(constants.SystemNamespace). + Get(context.Background(), constants.TokenSecretName, metaV1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get token, err: %v", err) + } + fmt.Println(string(secret.Data[constants.TokenDataName])) + return nil + }, + } + return cmd +} diff --git a/cmd/app/init.go b/cmd/app/init.go new file mode 100644 index 0000000..6be06a4 --- /dev/null +++ b/cmd/app/init.go @@ -0,0 +1,132 @@ +// Copyright © 2022 99nil. +// +// 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 app + +import ( + "context" + "fmt" + "strings" + + "github.com/99nil/diplomat/core/assistant" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/pkg/k8s" + "github.com/99nil/diplomat/pkg/logr" + "github.com/99nil/diplomat/static" + "github.com/99nil/gopkg/server" + + "github.com/spf13/cobra" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/flowcontrol" +) + +func NewAssistantInitCommand(globalOpt *common.GlobalOption) *cobra.Command { + opt := &common.InitOption{} + cmd := &cobra.Command{ + Use: "init", + Short: "Initial installation", + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + // parse config + cfg := assistant.Environ(globalOpt.EnvPrefix) + if err := server.ParseConfigWithEnv(globalOpt.Config, cfg, globalOpt.EnvPrefix); err != nil { + return fmt.Errorf("parse config failed: %v", err) + } + cfg.Complete() + if err := cfg.Validate(); err != nil { + return fmt.Errorf("validate config failed: %v", err) + } + loggerIns := logr.NewLogrusInstance(&cfg.Logger) + logr.SetDefault(loggerIns) + + // init client + restConfig, err := clientcmd.BuildConfigFromFlags("", globalOpt.KubeConfig) + if err != nil { + return err + } + restConfig.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(1000, 1000) + kubeClient, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("init kubernetes client failed: %v", err) + } + dynamicClient, err := dynamic.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("init dynamic client failed: %v", err) + } + //dockerClient, err := client.NewClientWithOpts(client.FromEnv) + //if err != nil { + // return err + //} + + kubeEdgeResources, err := k8s.ParseAllYamlToObject(static.KubeEdgeYaml) + if err != nil { + return err + } + ravenResources, err := k8s.ParseAllYamlToObject(static.RavenYaml) + if err != nil { + return err + } + + cfg.KubeEdgeResources = kubeEdgeResources + cfg.RavenResources = ravenResources + + advAddrs := strings.Split(opt.AdvertiseAddress, ",") + advAddr := advAddrs[0] + if len(advAddr) > 0 { + opt.CurrentIP = advAddr + } else { + // 获取IP地址 + hostInter, err := utilnet.ChooseHostInterface() + if err != nil { + return fmt.Errorf("get host interface failed: %v", err) + } + opt.CurrentIP = hostInter.String() + if opt.AdvertiseAddress == "" { + opt.AdvertiseAddress = opt.CurrentIP + } + } + + logr.Infof("logger level: %v", logr.Level()) + logr.Debugf("%#v", cfg) + + inst := assistant.NewInitInstance(globalOpt, opt, cfg, kubeClient, dynamicClient) + return inst.Run(context.Background()) + }, + } + initAssistantFlags(cmd, globalOpt, opt) + return cmd +} + +func initAssistantFlags(cmd *cobra.Command, globalOpt *common.GlobalOption, opt *common.InitOption) { + cmd.Flags().StringVar(&opt.Type, "type", common.TypeContainer, "Install KubeEdge Type: binary、container") + cmd.Flags().StringVar(&opt.Env, "env", common.EnvDev, "Install Env: dev、prod") + cmd.Flags().StringVar(&opt.Domain, "domain", "", "set domain names,eg: www.99nil.com,www.baidu.com") + + cmd.Flags().StringVar(&opt.AdvertiseAddress, "advertise-address", "", + "set IPs in cloudcore's certificate SubAltNames field,eg: 10.10.102.78,10.10.102.79") + + cmd.Flags().StringArrayVar(&opt.Disable, "disable", nil, + "Components that need to be disabled, if there are multiple components separated by commas. eg: CloudStream") + + cmd.Flags().StringVar(&opt.K8sCertPath, "k8s-cert-path", "/etc/kubernetes/pki", + "Use this key to set the Kubernetes certificate path, eg: /etc/kubernetes/pki; If not provide, will not generate certificate") + + cmd.Flags().StringVar(&opt.ImageRepository, "image-repository", "", + "Choose a container registry to pull control plane images from (default \"docker.io/99nil\")") + cmd.Flags().StringVar(&opt.ImageRepositoryUsername, "image-repository-username", "", "Choose a container registry username") + cmd.Flags().StringVar(&opt.ImageRepositoryPassword, "image-repository-password", "", "Choose a container registry password") +} diff --git a/cmd/app/join.go b/cmd/app/join.go new file mode 100644 index 0000000..2813e4f --- /dev/null +++ b/cmd/app/join.go @@ -0,0 +1,113 @@ +// Copyright © 2022 99nil. +// +// 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 app + +import ( + "context" + "fmt" + + "github.com/99nil/diplomat/global/constants" + + "github.com/99nil/diplomat/core/assistant" + + "github.com/99nil/diplomat/pkg/common" + "github.com/spf13/cobra" +) + +const ( + edgeJoinLongDescription = ` +"assistant join" command bootstraps Edge's worker node (at the edge) component. +It will also connect with cloud component to receive +further instructions and forward telemetry data from +devices to cloud +` + edgeJoinExample = ` +assistant join --cloudcore-ipport= --edgenode-name= + + - For this command --cloudcore-ipport flag is a required option + - This command will download and install the default version of pre-requisites and Edge + +assistant join --cloudcore-ipport=10.20.30.40:10000 --edgenode-name=testing123 +` +) + +func NewAssistantJoinCommand(globalOpt *common.GlobalOption) *cobra.Command { + opt := newOption() + cmd := &cobra.Command{ + Use: "join", + Short: "Bootstraps edge component. Checks and install (if required) the pre-requisites. Execute it on any edge node machine you wish to join", + Long: edgeJoinLongDescription, + Example: edgeJoinExample, + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + ins := assistant.NewJoinInstance(globalOpt, opt) + return ins.Run(context.Background()) + }, + } + addJoinOtherFlags(cmd, globalOpt, opt) + return cmd +} + +func addJoinOtherFlags(cmd *cobra.Command, globalOpt *common.GlobalOption, opt *common.JoinOption) { + cmd.Flags().StringVarP(&opt.CloudCoreIPPort, constants.CloudCoreIPPort, "e", opt.CloudCoreIPPort, + "IP:Port address of Edge CloudCore") + + if err := cmd.MarkFlagRequired(constants.CloudCoreIPPort); err != nil { + fmt.Printf("mark flag required failed with error: %v\n", err) + } + + cmd.Flags().StringVarP(&opt.EdgeNodeName, constants.EdgeNodeName, "i", opt.EdgeNodeName, + "Edge Node unique identification string, If flag not used then the command will generate a unique id on its own") + + cmd.Flags().StringVar(&opt.Namespace, "namespace", opt.Namespace, + "Set to the edge node of the specified namespace") + + cmd.Flags().StringSliceVar(&opt.Labels, constants.Labels, opt.Labels, + "Set to the edge node of the specified labels") + + cmd.Flags().StringVar(&opt.CGroupDriver, constants.CGroupDriver, opt.CGroupDriver, + "CGroupDriver that uses to manipulate cgroups on the host (cgroupfs or systemd), the default value is cgroupfs") + + cmd.Flags().StringVar(&opt.CertPath, constants.CertPath, opt.CertPath, + fmt.Sprintf("The certPath used by edgecore, the default value is %s", constants.DefaultCertPath)) + + cmd.Flags().StringVarP(&opt.RuntimeType, constants.RuntimeType, "r", opt.RuntimeType, + "Container runtime type") + + cmd.Flags().StringVarP(&opt.RemoteRuntimeEndpoint, constants.RemoteRuntimeEndpoint, "p", opt.RemoteRuntimeEndpoint, + "KubeEdge Edge Node RemoteRuntimeEndpoint string, If flag not set, it will use unix:///var/run/dockershim.sock") + + cmd.Flags().StringVarP(&opt.Token, constants.Token, "t", opt.Token, + "Used for edge to apply for the certificate") + + cmd.Flags().StringVarP(&opt.CertPort, constants.CertPort, "s", opt.CertPort, + "The port where to apply for the edge certificate") + + cmd.Flags().BoolVar(&opt.WithMQTT, "with-mqtt", opt.WithMQTT, + `Use this key to set whether to install and start MQTT Broker by default`) + + cmd.Flags().StringVar(&opt.ImageRepository, constants.ImageRepository, opt.ImageRepository, + `Use this key to decide which image repository to pull images from.`, + ) +} + +func newOption() *common.JoinOption { + joinOptions := &common.JoinOption{} + joinOptions.WithMQTT = true + joinOptions.CGroupDriver = constants.CGroupDriverCGroupFS + joinOptions.CertPath = constants.DefaultCertPath + joinOptions.RuntimeType = constants.DockerContainerRuntime + return joinOptions +} diff --git a/cmd/app/reset.go b/cmd/app/reset.go new file mode 100644 index 0000000..f55c759 --- /dev/null +++ b/cmd/app/reset.go @@ -0,0 +1,69 @@ +// Copyright © 2022 99nil. +// +// 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 app + +import ( + "context" + + "github.com/99nil/diplomat/core/assistant" + "github.com/99nil/diplomat/pkg/common" + + "github.com/spf13/cobra" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/flowcontrol" +) + +func NewAssistantEdgeResetCommand(globalOpt *common.GlobalOption) *cobra.Command { + opt := &common.ResetOption{} + cmd := &cobra.Command{ + Use: "reset-edge", + Short: "Reset diplomat edge side", + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + ins := assistant.NewEdgeResetInstance(globalOpt, opt) + return ins.Run(context.Background()) + }, + } + + cmd.Flags().BoolVar(&opt.Force, "force", false, "Reset the node without prompting for confirmation") + return cmd +} + +func NewAssistantCloudResetCommand(globalOpt *common.GlobalOption) *cobra.Command { + opt := &common.ResetOption{} + cmd := &cobra.Command{ + Use: "reset-cloud", + Short: "Reset diplomat cloud side", + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + restConfig, err := clientcmd.BuildConfigFromFlags("", globalOpt.KubeConfig) + if err != nil { + return err + } + restConfig.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(1000, 1000) + kubeClient, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return err + } + + ins := assistant.NewCloudResetInstance(globalOpt, opt, kubeClient) + return ins.Run(context.Background()) + }, + } + + cmd.Flags().BoolVar(&opt.Force, "force", false, "Reset the node without prompting for confirmation") + return cmd +} diff --git a/cmd/app/upgrade.go b/cmd/app/upgrade.go new file mode 100644 index 0000000..f51a6c7 --- /dev/null +++ b/cmd/app/upgrade.go @@ -0,0 +1,15 @@ +// Copyright © 2022 99nil. +// +// 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 app diff --git a/cmd/app/option.go b/cmd/app/version.go similarity index 51% rename from cmd/app/option.go rename to cmd/app/version.go index 715d377..529330e 100644 --- a/cmd/app/option.go +++ b/cmd/app/version.go @@ -15,32 +15,22 @@ package app import ( - "os" - "strings" + "fmt" - "github.com/spf13/cobra" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/pkg/version" - "github.com/99nil/diplomat/global/constants" + "github.com/spf13/cobra" ) -type Option struct { - Module string - EnvPrefix string - Config string -} - -func (o *Option) CompleteFlags(cmd *cobra.Command) { - cfgPathEnv := os.Getenv(o.EnvPrefix + "_CONFIG") - if cfgPathEnv == "" { - cfgPathEnv = "config/config.yaml" +func NewVersionCommand(globalOpt *common.GlobalOption) *cobra.Command { + cmd := &cobra.Command{ + Use: "version", + Short: "diplomat assistant version", + SilenceUsage: true, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version.Get()) + }, } - cmd.Flags().StringVarP(&o.Config, "config", "c", cfgPathEnv, - "config file (default is $HOME/config.yaml)") -} - -func NewOption(module string) *Option { - opt := &Option{Module: module} - module = strings.ReplaceAll(module, "-", "_") - opt.EnvPrefix = strings.ToUpper(constants.ProjectName + "_" + module) - return opt + return cmd } diff --git a/cmd/assistant/main.go b/cmd/assistant/main.go index 2ef1ff7..e1106f1 100644 --- a/cmd/assistant/main.go +++ b/cmd/assistant/main.go @@ -18,10 +18,19 @@ import ( "os" _ "time/tzdata" + "github.com/sirupsen/logrus" + "github.com/99nil/diplomat/cmd/app" ) func main() { + logrus.SetFormatter(&logrus.TextFormatter{ + ForceColors: true, + DisableLevelTruncation: true, + PadLevelText: true, + FullTimestamp: true, + TimestampFormat: "2006/01/02 15:04:05", + }) if err := app.NewAssistant().Execute(); err != nil { os.Exit(1) } diff --git a/config/config.yaml b/config/config.yaml index 29d1af6..6478008 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -8,4 +8,6 @@ logger: server: host: http://localhost:3000 agent: - name: node-70-35 \ No newline at end of file + name: node-70-35 +assistant: + part: a \ No newline at end of file diff --git a/core/assistant/assistant.go b/core/assistant/assistant.go index 33b055f..7bb7c1c 100644 --- a/core/assistant/assistant.go +++ b/core/assistant/assistant.go @@ -15,12 +15,142 @@ package assistant import ( - dockerclient "github.com/docker/docker/client" + "context" + + "github.com/99nil/diplomat/core/component" + "github.com/99nil/diplomat/pkg/common" + + "github.com/zc2638/aide" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" ) -func Run(cfg *Config, dockerClient *dockerclient.Client) error { +func Run(cfg *Config) error { // TODO 支持插件的升级及重启 // TODO 支持自升级 // TODO 监听插件的健康状态 return nil } + +func NewInitInstance( + globalOpt *common.GlobalOption, + opt *common.InitOption, + cfg *Config, + kubeClient kubernetes.Interface, + dynamicClient dynamic.Interface, +) *aide.Instance { + ri := component.RavenInstallTool{ + Ctx: context.Background(), + Resources: cfg.RavenResources, + KubeClient: kubeClient, + DynamicClient: dynamicClient, + } + imageSet := common.NewCloudImageSet() + portSet := common.NewPortOption() + + ins := aide.New(aide.WithVerboseOption(globalOpt.Verbose)) + checkStage := aide.NewStage("check") + { + checkStage.AddStepFunc("port check", CheckPort(append(cfg.KubeEdgeResources, cfg.RavenResources...), opt, portSet)) + checkStage.AddStepFunc("k8s check", CheckK8s()) + checkStage.AddStepFunc("cloud check", CheckCloud(kubeClient)) + checkStage.AddStepFunc("raven check", func(sc *aide.StepContext) { + if err := ri.PreInstall(ri.Ctx); err != nil { + sc.Errorf("Check raven failed, err: %v", err) + } + }) + } + + initStage := aide.NewStage("init resource") + { + initStage.AddStepFunc("prepare in advance", Advance()) + initStage.AddStepFunc("namespace in advance", AdvanceNS(kubeClient)) + initStage.AddStepFunc("secret in advance", AdvanceSecret(kubeClient, opt, imageSet)) + initStage.AddStepFunc("generate certs", GenerateCerts(opt)) + initStage.AddStepFunc("apply kubeedge resource", ApplyResource(globalOpt, opt, cfg.KubeEdgeResources, kubeClient, dynamicClient, portSet, imageSet)) + initStage.AddStepFunc("kubeedge install", KubeEdgeInstall(globalOpt, opt)) + initStage.AddStepFunc("raven install", func(sc *aide.StepContext) { + if err := ri.Install(ri.Ctx); err != nil { + sc.Errorf("install raven failed, err: %v", err) + } + }) + } + + healthStage := aide.NewStage("health check") + { + healthStage.AddStepFunc("cloud health", HealthCheck(opt.Type)) + } + + ins.AddStages(checkStage, initStage, healthStage) + + return ins +} + +func NewJoinInstance( + globalOpt *common.GlobalOption, + opt *common.JoinOption, +) *aide.Instance { + imageSet := common.NewEdgeImageSet() + ins := aide.New(aide.WithVerboseOption(globalOpt.Verbose)) + + checkStage := aide.NewStage("check").AddSteps( + CheckEdge().Step("check dependency"), + ) + joinStage := aide.NewStage("join").AddSteps( + Advance().Step("prepare in advance"), + Request(opt, imageSet).Step("prepare images"), + StartMQTT(opt, imageSet).Step("start MQTT"), + JoinEdge(opt).Step("join cloud"), + ) + + ins.AddStages(checkStage, joinStage) + return ins +} + +func NewUpgradeInstance( + globalOpt *common.GlobalOption, + opt *common.InitOption, + cfg *Config, + kubeClient kubernetes.Interface, + dynamicClient dynamic.Interface, +) *aide.Instance { + // TODO cloudcore, raven, edgecore... + return nil +} + +func NewCloudResetInstance( + globalOpt *common.GlobalOption, + opt *common.ResetOption, + kubeClient kubernetes.Interface, +) *aide.Instance { + ins := aide.New(aide.WithVerboseOption(globalOpt.Verbose)) + if !opt.Force { + chooseStage := aide.NewStage("choose") + chooseStage.AddStepFunc("reset confirm", ChooseResetConfirm(false)) + ins.AddStages(chooseStage) + } + + resetStage := aide.NewStage("reset") + resetStage.AddStepFunc("reset cloudcore", ResetCloud(kubeClient)) + ins.AddStages(resetStage) + + return ins +} + +func NewEdgeResetInstance( + globalOpt *common.GlobalOption, + opt *common.ResetOption, +) *aide.Instance { + ins := aide.New(aide.WithVerboseOption(globalOpt.Verbose)) + if !opt.Force { + chooseStage := aide.NewStage("choose") + chooseStage.AddStepFunc("reset confirm", ChooseResetConfirm(true)) + ins.AddStages(chooseStage) + } + + resetStage := aide.NewStage("reset") + resetStage.AddStepFunc("reset edgecore", ResetEdge()) + ins.AddStages(resetStage) + + return ins +} diff --git a/core/assistant/check.go b/core/assistant/check.go new file mode 100644 index 0000000..b9d5875 --- /dev/null +++ b/core/assistant/check.go @@ -0,0 +1,142 @@ +// Copyright © 2022 99nil. +// +// 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 assistant + +import ( + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "k8s.io/client-go/kubernetes" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/pkg/exec" + + "github.com/zc2638/aide" + coreV1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + pkgruntime "k8s.io/apimachinery/pkg/runtime" +) + +func CheckPort(resources [][]unstructured.Unstructured, opt *common.InitOption, portSet *common.PortSet) aide.StepFunc { + return func(sc *aide.StepContext) { + sc.Log("Start to check port conflict") + if opt.Env == common.EnvDev { + sc.Log("Check port conflict Skipped") + return + } + + // 读取所有service yaml + if err := generateAllPortsByResource(resources, opt, portSet); err != nil { + sc.Errorf("Generate All ports failed: %v", err) + } + + format := "[ \"$(netstat -nl | awk '{if($4 ~ /^.*:%v/){print $0;}}')\" == '' ]" + portSet.Range(func(name string, port int32) bool { + if err := sc.Bash(fmt.Sprintf(format, port)); err != nil { + sc.Logfl(aide.WarnLevel, "Check %s service port %d conflict, random port will be used", name, port) + portSet.Remove(name) + } else { + sc.Logf("Check %s service port %d success", name, port) + } + return true + }) + sc.Log("Check port conflict completed") + } +} + +func CheckK8s() aide.StepFunc { + return func(sc *aide.StepContext) { + sc.Log("Start to check k8s status") + if err := sc.Shell("kubectl get node"); err != nil { + sc.Error(err) + } + sc.Log("K8s is running") + } +} + +func generateAllPortsByResource(src [][]unstructured.Unstructured, opt *common.InitOption, portSet *common.PortSet) error { + for _, resources := range src { + if err := fillPort(resources, opt, portSet); err != nil { + return err + } + } + return nil +} + +func fillPort(resources []unstructured.Unstructured, opt *common.InitOption, portSet *common.PortSet) error { + for _, obj := range resources { + if obj.GetKind() != constants.KindService { + continue + } + var svc coreV1.Service + if err := pkgruntime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &svc); err != nil { + return fmt.Errorf("convert unstructured object to Service failed: %v", err) + } + + // 禁用NodePort + isSpecial := common.IsSpecialName(svc.Name) + for _, port := range svc.Spec.Ports { + if opt.Env != common.EnvDev && !isSpecial { + portSet.Remove(port.Name) + continue + } + if port.NodePort > 0 { + portSet.Add(port.Name, port.NodePort) + } + } + } + return nil +} + +func CheckCloud(kubeClient kubernetes.Interface) aide.StepFunc { + return func(sc *aide.StepContext) { + // check cloudcore for container deploy + _, err := kubeClient.AppsV1().Deployments(constants.SystemNamespace). + Get(sc.Context(), constants.CloudComponent, metaV1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + sc.Errorf("Check cloud container failed: %v", err) + } + } else { + sc.Errorf("KubeEdge cloudcore container is already running on this node, please run reset to clean up first") + } + + // check cloudcore process + running, err := isProcessRunning(constants.CloudComponent) + if err != nil { + sc.Errorf("Check cloud process failed: %v", err) + } + if running { + sc.Errorf("KubeEdge cloudcore is already running on this node, please run reset to clean up first") + } + sc.Log("Check cloud process successful") + } +} + +// isProcessRunning checks if the given process is running or not +func isProcessRunning(proc string) (bool, error) { + cmd := exec.NewCommand(fmt.Sprintf("pidof %s 2>&1", proc)) + err := cmd.Exec() + + if cmd.ExitCode == 0 { + return true, nil + } else if cmd.ExitCode == 1 { + return false, nil + } + return false, err +} diff --git a/core/assistant/config.go b/core/assistant/config.go index ad20604..cbcc591 100644 --- a/core/assistant/config.go +++ b/core/assistant/config.go @@ -15,8 +15,10 @@ package assistant import ( + "github.com/99nil/diplomat/pkg/k8s" "github.com/99nil/diplomat/pkg/logr" "github.com/spf13/viper" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) const ( @@ -33,8 +35,12 @@ func Environ(envPrefix string) *Config { } type Config struct { - Logger logr.Config `json:"logger,omitempty"` - Part string `json:"part"` + Kubernetes *k8s.Config `json:"kubernetes,omitempty"` + Logger logr.Config `json:"logger,omitempty"` + Part string `json:"part"` + // TODO 优化,避免多个组件yaml导致添加更多的字段 + KubeEdgeResources [][]unstructured.Unstructured + RavenResources [][]unstructured.Unstructured } func (c *Config) Complete() { diff --git a/core/assistant/init.go b/core/assistant/init.go new file mode 100644 index 0000000..18c9f18 --- /dev/null +++ b/core/assistant/init.go @@ -0,0 +1,665 @@ +// Copyright © 2022 99nil. +// +// 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 assistant + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + "time" + + keutil "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" + + "github.com/99nil/diplomat/pkg/edgeconfig" + + "github.com/99nil/diplomat/pkg/util" + + "github.com/99nil/diplomat/pkg/exec" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/static" + + "github.com/zc2638/aide" + "golang.org/x/sync/errgroup" + "gopkg.in/yaml.v3" + appsV1 "k8s.io/api/apps/v1" + coreV1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + pkgruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/restmapper" +) + +func Advance() aide.StepFunc { + return func(sc *aide.StepContext) { + // 创建管理目录 + if err := os.MkdirAll(constants.RootDir, os.ModePerm); err != nil { + sc.Errorf("Create diplomat management directory `%s` failed: %v", constants.RootDir, err) + } + if err := os.MkdirAll(constants.ResourceDir, os.ModePerm); err != nil { + sc.Errorf("Create diplomat management directory `%s` failed: %v", constants.ResourceDir, err) + } + if err := os.MkdirAll(constants.ConfigDir, os.ModePerm); err != nil { + sc.Errorf("Create diplomat management directory `%s` failed: %v", constants.ConfigDir, err) + } + if err := os.MkdirAll(constants.DefaultCertPath, os.ModePerm); err != nil { + sc.Errorf("Create diplomat management directory `%s` failed: %v", constants.DefaultCertPath, err) + } + if err := os.MkdirAll(constants.LogDir, os.ModePerm); err != nil { + sc.Errorf("Create diplomat management directory `%s` failed: %v", constants.LogDir, err) + } + sc.Log("Init diplomat management directory successful.") + } +} + +func AdvanceNS(kubeClient kubernetes.Interface) aide.StepFunc { + return func(sc *aide.StepContext) { + ns := &coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: constants.DefaultNamespace, + }, + } + _, err := kubeClient.CoreV1().Namespaces().Create(sc.Context(), ns, metav1.CreateOptions{}) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + sc.Errorf("Init default namespace failed: %v", err) + } + sc.Log("Default namespace already exist, skipped") + } else { + sc.Log("Init default namespace successful") + } + + ns.Name = constants.SystemNamespace + _, err = kubeClient.CoreV1().Namespaces().Create(sc.Context(), ns, metav1.CreateOptions{}) + if err == nil { + sc.Log("Init system namespace successful") + return + } + if apierrors.IsAlreadyExists(err) { + sc.Log("System namespace already exist, skipped") + return + } + + sc.Errorf("Init system namespace failed: %v", err) + } +} + +func compileNewImage(src, registry string) (string, error) { + ss := strings.Split(src, "/") + if len(ss) < 3 { + return "", fmt.Errorf("split image path error:%s", src) + } + return registry + "/" + ss[2], nil +} + +func buildImgPullSecretData(registry, username, password string) map[string]string { + auth := struct { + Username string `json:"username"` + Password string `json:"password"` + Auth string `json:"auth"` + }{ + Username: username, + Password: password, + Auth: base64.StdEncoding.EncodeToString([]byte(username + ":" + password)), + } + encode, err := json.Marshal(auth) + if err != nil { + return nil + } + + arr := strings.Split(registry, "/") + data := make(map[string]string) + src := "{\"auths\":{\"" + arr[0] + "\":" + string(encode) + "}}" + data[".dockerconfigjson"] = src + return data +} + +func AdvanceSecret(kubeClient kubernetes.Interface, opt *common.InitOption, imageSet map[string]string) aide.StepFunc { + return func(sc *aide.StepContext) { + sc.Log("Start to init secret") + if opt.ImageRepository == "" { + sc.Log("init secret successful") + return + } + + for k, v := range imageSet { + image, err := compileNewImage(v, opt.ImageRepository) + if err != nil { + sc.Error(err) + return + } + imageSet[k] = image + } + + if opt.ImageRepositoryUsername == "" || opt.ImageRepositoryPassword == "" { + sc.Logf("Use custom image repository (%s), generate secret skipped", opt.ImageRepository) + return + } + + secret := &coreV1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: constants.DefaultNamespace, + Name: opt.ImageRepository, + }, + Data: nil, + StringData: buildImgPullSecretData(opt.ImageRepository, opt.ImageRepositoryUsername, opt.ImageRepositoryPassword), + Type: coreV1.SecretTypeDockerConfigJson, + } + _, err := kubeClient.CoreV1().Secrets(secret.Namespace).Create(sc.Context(), secret, metav1.CreateOptions{}) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + sc.Errorf("Create image secret failed: %s", err) + } + sc.Logl(aide.WarnLevel, "Custom image secret %s has already exists", secret.Name) + return + } + sc.Logf("Use custom image repository (%s), generate secret successful", opt.ImageRepository) + } +} + +func GenerateCerts(opt *common.InitOption) aide.StepFunc { + return func(sc *aide.StepContext) { + // admission cert + targetPath := filepath.Join(constants.RootDir, "gen-admission-cert.sh") + if err := os.WriteFile(targetPath, static.AdmissionCertScript, os.ModePerm); err != nil { + sc.Errorf("Generate admission certificate script failed: %v", err) + } + if err := sc.Shell(targetPath); err != nil { + sc.Errorf("Generate admission certificate failed: %v", err) + } + sc.Log("Generate admission certificate successful") + + // cloudcore cert + targetPath = filepath.Join(constants.RootDir, "gen-cloudcore-secret.sh") + if err := os.WriteFile(targetPath, static.CoreCertScript, os.ModePerm); err != nil { + sc.Errorf("Generate cloudcore certificate script failed: %v", err) + } + if err := sc.Shell(fmt.Sprintf("IP=%s %s", opt.AdvertiseAddress, targetPath)); err != nil { + sc.Errorf("Generate cloudcore certificate failed: %v", err) + } + sc.Log("Generate cloudcore certificate successful") + + // cloud stream cert + targetPath = filepath.Join(constants.RootDir, "gen-stream-secret.sh") + if err := os.WriteFile(targetPath, static.StreamCertScript, os.ModePerm); err != nil { + sc.Errorf("Generate cloudcore stream certificate script failed: %v", err) + } + advAddr := strings.Join(strings.Split(opt.AdvertiseAddress, ","), " ") + var domain string + cmd := fmt.Sprintf( + "CLOUDCOREIPS=\"%s\" %s stream -c true -p %s", + advAddr, targetPath, opt.K8sCertPath) + if opt.Domain != "" { + domains := strings.Split(opt.Domain, ",") + domain = domains[0] + if len(domains) > 1 { + for i := 1; i < len(domains); i++ { + domain += " " + domains[i] + } + } + cmd = fmt.Sprintf("CLOUDCORE_DOMAINS=\"%s\" "+cmd, domain) + } + sc.Logfl(aide.InfoLevel, "cloud stream cert cmd: %s", cmd) + if err := sc.Shell(cmd); err != nil { + sc.Errorf("Generate stream certificate failed: %v", err) + } + sc.Log("Generate cloud stream certificate successful") + } +} + +func ApplyResource( + globalOpt *common.GlobalOption, + opt *common.InitOption, + resourceSet [][]unstructured.Unstructured, + kubeClient kubernetes.Interface, + dynamicClient dynamic.Interface, + portSet *common.PortSet, + imageOption map[string]string, +) aide.StepFunc { + return func(sc *aide.StepContext) { + // TODO 检查版本适应 + + gr, err := restmapper.GetAPIGroupResources(kubeClient.Discovery()) + if err != nil { + sc.Errorf("Get API group resources failed: %v", err) + } + mapping := restmapper.NewDiscoveryRESTMapper(gr) + + for _, resources := range resourceSet { + wg, ctx := errgroup.WithContext(sc.Context()) + for _, obj := range resources { + currentObj := obj.DeepCopy() + wg.Go(func() error { + gvk := currentObj.GroupVersionKind() + sc.Logf("Apply resource %s %s", gvk, currentObj.GetName()) + + restMapping, err := mapping.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return err + } + + var resourceInter dynamic.ResourceInterface + if restMapping.Scope.Name() == meta.RESTScopeNameNamespace { + if currentObj.GetNamespace() == "" { + currentObj.SetNamespace(constants.DefaultNamespace) + } + resourceInter = dynamicClient.Resource(restMapping.Resource).Namespace(currentObj.GetNamespace()) + } else { + resourceInter = dynamicClient.Resource(restMapping.Resource) + } + + // 自定义修改 + switch currentObj.GetKind() { + case constants.KindService: + if currentObj.GetName() == constants.CloudComponent && opt.Type != common.TypeContainer { + return nil + } + return ApplyService(ctx, kubeClient, currentObj, portSet, opt) + case constants.KindConfigMap: + if currentObj.GetName() == constants.CloudComponent && opt.Type != common.TypeContainer { + return nil + } + return applyConfigMap(ctx, kubeClient, resourceInter, currentObj, portSet, opt.CurrentIP, opt.AdvertiseAddress) + case constants.KindDeployment: + if currentObj.GetName() == constants.CloudComponent && opt.Type != common.TypeContainer { + return nil + } + return applyDeployment(ctx, kubeClient, resourceInter, currentObj, opt, imageOption) + case constants.KindDaemonSet: + return applyDaemonSet(ctx, kubeClient, resourceInter, currentObj, portSet, imageOption, opt.CurrentIP) + default: + return common.ApplyResource(ctx, resourceInter, currentObj) + } + }) + } + if err := wg.Wait(); err != nil { + sc.Errorf("Apply resource failed: %v", err) + } + } + sc.Log("Apply resource successful") + } +} + +func applyConfigMap( + ctx context.Context, + kubeClient kubernetes.Interface, + resourceInter dynamic.ResourceInterface, + obj *unstructured.Unstructured, + portSet *common.PortSet, + hostIP string, + advertiseAddress string, +) error { + var cm coreV1.ConfigMap + if err := pkgruntime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &cm); err != nil { + return fmt.Errorf("convert unstructured object %s to ConfigMap failed: %v", obj.GetName(), err) + } + + switch obj.GetName() { + case "cloudcore": + data, ok := cm.Data["cloudcore.yaml"] + if !ok { + return fmt.Errorf("meta resource ConfigMap %s not found config.yaml", obj.GetName()) + } + var cmMap map[string]interface{} + if err := yaml.Unmarshal([]byte(data), &cmMap); err != nil { + return err + } + + // TODO 优化,获取字段有点恶心 + v1, ok := getMap(cmMap, "modules") + if !ok { + return fmt.Errorf("configmap field not found") + } + v2, ok := getMap(v1, "cloudHub") + if !ok { + return fmt.Errorf("configmap field not found") + } + // for testing + //values, ok := v2["advertiseAddress"].([]interface{}) + //if !ok { + // return fmt.Errorf("configmap field not found") + //} + //values = []interface{}{strings.Split(advertiseAddress, ",")} + + v2["advertiseAddress"] = strings.Split(advertiseAddress, ",") + v1["cloudHub"] = v2 + cmMap["modules"] = v1 + + marshal, err := yaml.Marshal(cmMap) + if err != nil { + return err + } + cm.Data["cloudcore.yaml"] = string(marshal) + } + + toUnstructured, err := pkgruntime.DefaultUnstructuredConverter.ToUnstructured(&cm) + if err != nil { + return err + } + obj.SetUnstructuredContent(toUnstructured) + return common.ApplyResource(ctx, resourceInter, obj) +} + +//nolint +func setCurrentToMap(data map[string]interface{}, current map[string]interface{}, keys ...string) { + for _, k := range keys { + if v, ok := current[k]; ok { + data[k] = v + } + } +} + +func getMap(src map[string]interface{}, name string) (map[string]interface{}, bool) { + if m, ok := src[name]; ok { + if v, ok := m.(map[string]interface{}); ok { + return v, true + } + } + return nil, false +} + +func ApplyService( + ctx context.Context, + kubeClient kubernetes.Interface, + obj *unstructured.Unstructured, + portSet *common.PortSet, + opt *common.InitOption, +) error { + var svc coreV1.Service + if err := pkgruntime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &svc); err != nil { + return fmt.Errorf("convert unstructured object %s to Service failed: %v", obj.GetName(), err) + } + + // 禁用NodePort + isSpecial := common.IsSpecialName(svc.Name) + if opt.Env != common.EnvDev && !isSpecial { + svc.Spec.Type = coreV1.ServiceTypeClusterIP + } + + ports := make([]coreV1.ServicePort, 0, len(svc.Spec.Ports)) + for _, port := range svc.Spec.Ports { + switch svc.Spec.Type { + case coreV1.ServiceTypeNodePort: + port.NodePort = portSet.Get(port.Name) + case coreV1.ServiceTypeClusterIP: + port.NodePort = 0 + default: + } + ports = append(ports, port) + } + svc.Spec.Ports = ports + + var current *coreV1.Service + serviceInter := kubeClient.CoreV1().Services(obj.GetNamespace()) + found, err := serviceInter.Get(ctx, svc.Name, metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + current, err = serviceInter.Create(ctx, &svc, metav1.CreateOptions{}) + } else { + // 更新操作的话,使用运行中的ports,不影响原有配置 + currentPorts := make([]coreV1.ServicePort, 0, len(svc.Spec.Ports)) + for _, port := range ports { + var existPort *coreV1.ServicePort + for _, v := range found.Spec.Ports { + if v.Name == port.Name { + existPort = &v + break + } + } + if existPort != nil { + port = *existPort + } + currentPorts = append(currentPorts, port) + } + found.Spec.Ports = currentPorts + + rv, _ := strconv.ParseInt(found.GetResourceVersion(), 10, 64) + found.SetResourceVersion(strconv.FormatInt(rv, 10)) + current, err = serviceInter.Update(ctx, found, metav1.UpdateOptions{}) + } + if err != nil { + return err + } + setCurrentPorts(portSet, current) + return nil +} + +func setCurrentPorts(portSet *common.PortSet, svc *coreV1.Service) { + for _, port := range svc.Spec.Ports { + portSet.Add(port.Name, port.NodePort) + } +} + +func applyDeployment( + ctx context.Context, + kubeClient kubernetes.Interface, + resourceInter dynamic.ResourceInterface, + obj *unstructured.Unstructured, + opt *common.InitOption, + imageOption map[string]string, +) error { + name := obj.GetName() + // 修改镜像版本 + var deploy appsV1.Deployment + err := pkgruntime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &deploy) + if err != nil { + return fmt.Errorf("convert unstructured object %s to Deployment failed: %v", obj.GetName(), err) + } + + image, ok := imageOption[name] + if !ok { + image = deploy.Spec.Template.Spec.Containers[0].Image + } + deploy.Spec.Template.Spec.Containers[0].Image = image + + current, err := kubeClient.AppsV1().Deployments(deploy.GetNamespace()).Get(ctx, deploy.GetName(), metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } else { + current.Spec.Template.Spec.Containers[0].Image = image + deploy = *current + } + + toUnstructured, err := pkgruntime.DefaultUnstructuredConverter.ToUnstructured(&deploy) + if err != nil { + return err + } + obj.SetUnstructuredContent(toUnstructured) + return common.ApplyResource(ctx, resourceInter, obj) +} + +func applyDaemonSet( + ctx context.Context, + kubeClient kubernetes.Interface, + resourceInter dynamic.ResourceInterface, + obj *unstructured.Unstructured, + portSet *common.PortSet, + imageSet map[string]string, + hostIP string, +) error { + var ds appsV1.DaemonSet + if err := pkgruntime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &ds); err != nil { + return fmt.Errorf("convert unstructured object %s to DaemonSet failed: %v", obj.GetName(), err) + } + + if len(ds.Spec.Template.Spec.Containers) == 0 { + return fmt.Errorf("meta resource DaemonSet %s not found container", obj.GetName()) + } + container := ds.Spec.Template.Spec.Containers[0] + if image, ok := imageSet[ds.Name]; ok { + container.Image = image + } + + current, err := kubeClient.AppsV1().DaemonSets(obj.GetNamespace()).Get(ctx, obj.GetName(), metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } else { + // 存在情况:只更新镜像版本及不存在的环境变量 + currentContainer := current.Spec.Template.Spec.Containers[0] + var envs []coreV1.EnvVar + for _, v := range container.Env { + var existEnv *coreV1.EnvVar + for _, cv := range currentContainer.Env { + if v.Name == cv.Name { + existEnv = &cv + break + } + } + if existEnv != nil { + envs = append(envs, *existEnv) + } else { + envs = append(envs, v) + } + } + currentContainer.Image = container.Image + currentContainer.Env = envs + current.Spec.Template.Spec.Containers[0] = currentContainer + ds = *current + } + + toUnstructured, err := pkgruntime.DefaultUnstructuredConverter.ToUnstructured(&ds) + if err != nil { + return err + } + obj.SetUnstructuredContent(toUnstructured) + return common.ApplyResource(ctx, resourceInter, obj) +} + +func KubeEdgeInstall( + globalOpt *common.GlobalOption, + opt *common.InitOption, +) aide.StepFunc { + return func(sc *aide.StepContext) { + switch opt.Type { + case common.TypeContainer: + sc.Log("Already apply cloudcore resource") + case common.TypeBinary: + // 创建默认配置 + cfg := edgeconfig.NewDefaultCloudCoreConfig(constants.RootDir, constants.ResourceDir) + cfg.Modules.CloudHub.AdvertiseAddress = strings.Split(opt.AdvertiseAddress, ",") + + if globalOpt.KubeConfig != "" { + cfg.KubeAPIConfig.KubeConfig = globalOpt.KubeConfig + } + if err := util.WriteToFile(filepath.Join(constants.ConfigDir, constants.CloudComponent+".yaml"), cfg); err != nil { + sc.Errorf("Init Diplomat Cloud config failed: %v", err) + } + // 下载云端二进制执行程序 + // TODO 需要提供一个下载地址 + downloadCloudResource(sc, "https://github.com/kubeedge/kubeedge/releases/download/v1.11.2") + + // 检查是否存在systemd + systemdExists := keutil.HasSystemd() + // 创建systemd管理文件,并启动程序 + if systemdExists { + sc.Log("Systemd found") + + if err := util.GenerateServiceFile(constants.ConfigDir, constants.ExecDir, constants.CloudComponent); err != nil { + sc.Errorf("Init diplomat Cloud Systemd failed: %v", err) + } + if err := sc.Shell(fmt.Sprintf("sudo systemctl daemon-reload && sudo systemctl enable %s && sudo systemctl start %s", + constants.CloudComponent, constants.CloudComponent)); err != nil { + sc.Errorf("Init diplomat Cloud Systemd failed: %v", err) + } + sc.Log("Diplomat Cloud is running, For logs visit: journalctl -u cloudcore.service -b") + } else { + sc.Logl(aide.WarnLevel, "Systemd not found") + + logPath := filepath.Join(constants.LogDir, "cloudcore.log") + if err := sc.Shell(fmt.Sprintf("%s > %s 2>&1 &", + filepath.Join(constants.ExecDir, constants.CloudComponent), logPath)); err != nil { + sc.Errorf("Init diplomat Cloud Systemd failed: %v", err) + } + sc.Log("Diplomat Cloud is running, For logs visit: ", logPath) + } + default: + sc.Errorf("invalid install type %s", opt.Type) + } + } +} + +func downloadCloudResource(sc *aide.StepContext, addr string) { + // 适配amd64、arm环境的下载 + //edgeFileCleanName := "kubeedge-linux-" + runtime.GOARCH + edgeFileCleanName := "kubeedge-v1.11.2-linux-" + runtime.GOARCH + edgeFileName := edgeFileCleanName + ".tar.gz" + + // https://github.com/kubeedge/kubeedge/releases/download/v1.11.2 / kubeedge-v1.11.2-linux-amd64.tar.gz + // 下载资源包 + if err := sc.Shell(fmt.Sprintf( + "wget -k --no-check-certificate --progress=bar:force %s/%s -O %s", + addr, edgeFileName, filepath.Join(constants.RootDir, edgeFileName))); err != nil { + sc.Errorf("Download diplomat Cloud resource failed: %v", err) + } + + // 解压并将执行程序移动到exec目录 + if err := sc.Shell(fmt.Sprintf( + "cd %s && tar -C %s -xvzf %s && cp -f %s %s/", + constants.RootDir, constants.RootDir, edgeFileName, + filepath.Join(constants.RootDir, edgeFileCleanName, "cloud", "cloudcore", constants.CloudComponent), constants.ExecDir)); err != nil { + sc.Errorf("Process diplomat Cloud executor file failed: %v", err) + } +} + +func HealthCheck(t string) aide.StepFunc { + return func(sc *aide.StepContext) { + var isRunning bool + switch t { + case common.TypeContainer: + // TODO 检查容器部署的cloudcore + isRunning = true + sc.Log("please use `kubectl get pod -n kubeedge cloudcore' to check pod is it not healthy.") + case common.TypeBinary: + for i := 0; i < 5; i++ { + cmd := exec.NewCommand("pidof cloudcore 2>&1") + err := cmd.Exec() + if cmd.ExitCode == 0 { + isRunning = true + } else if cmd.ExitCode == 1 { + isRunning = false + } + if err != nil { + isRunning = false + sc.Log(aide.WarnLevel, err) + } + time.Sleep(time.Second * 2) + } + default: + sc.Errorf("invalid install type %s", t) + } + + if !isRunning { + sc.Errorf("Service startup exception, please contact the administrator for troubleshooting") + } + sc.Log("Health is ok") + } +} diff --git a/core/assistant/join.go b/core/assistant/join.go new file mode 100644 index 0000000..8b6376f --- /dev/null +++ b/core/assistant/join.go @@ -0,0 +1,313 @@ +// Copyright © 2022 99nil. +// +// 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 assistant + +import ( + "fmt" + "net" + "os" + "path/filepath" + "strings" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/pkg/edgeconfig" + "github.com/99nil/diplomat/pkg/exec" + "github.com/99nil/diplomat/pkg/hash" + "github.com/99nil/diplomat/pkg/util" + + keutil "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" + "github.com/sirupsen/logrus" + "github.com/zc2638/aide" + "sigs.k8s.io/yaml" +) + +func CheckEdge() aide.StepFunc { + return func(sc *aide.StepContext) { + if err := sc.Shell("docker version"); err != nil { + sc.Errorf("Check docker failed: %v", err) + } + sc.Log("Check container runtime successful") + + running, err := isProcessRunning(constants.EdgeComponent) + if err != nil { + sc.Errorf("Check edge process failed: %v", err) + } + if running { + sc.Errorf("Diplomat edgecore is already running on this node, please run reset to clean up first") + } + sc.Log("Check edge process successful") + + port := 1883 + format := "[ \"$(netstat -nl | awk '{if($4 ~ /^.*:%v/){print $0;}}')\" == '' ]" + if err := sc.Bash(fmt.Sprintf(format, port)); err != nil { + sc.Errorf("Check MQTT service port %d conflict, please check it. error: %v", port, err) + } + sc.Logf("Check MQTT service port %d successful", port) + } +} + +func Request(opt *common.JoinOption, imageSet map[string]string) aide.StepFunc { + return func(sc *aide.StepContext) { + images := make([]string, 0, len(imageSet)) + for _, v := range imageSet { + images = append(images, v) + } + + ctnRuntime, err := keutil.NewContainerRuntime(opt.RuntimeType, opt.RemoteRuntimeEndpoint) + if err != nil { + sc.Errorf("Create container runtime client failed, err: %v", err) + } + + sc.Log("Pull Images") + if err := ctnRuntime.PullImages(images); err != nil { + sc.Errorf("Pull Images failed: %v", err) + } + + sc.Log("Copy resources from the image to the management directory") + dirs := map[string]string{ + constants.RootDir: filepath.Join(constants.TmpPath, "data"), + } + files := map[string]string{ + filepath.Join(constants.UsrBinPath, constants.EdgeComponent): filepath.Join(constants.TmpPath, "bin", constants.EdgeComponent), + } + if err := ctnRuntime.CopyResources(imageSet[common.InstallationPackageName], dirs, files); err != nil { + sc.Errorf("copy resources failed: %v", err) + } + } +} + +func StartMQTT(opt *common.JoinOption, imageSet map[string]string) aide.StepFunc { + return func(sc *aide.StepContext) { + if !opt.WithMQTT { + sc.Log("set without MQTT tag, continue to init MQTT service") + return + } + sc.Log("Start to init MQTT service") + + content := `persistence true +persistence_location /mosquitto/data +log_dest file /mosquitto/log/mosquitto.log +` + dir := filepath.Join(constants.RootDir, "mosquitto", "config") + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + sc.Errorf("Create MQTT config dir %s failed: %s", dir, err) + } + if err := os.WriteFile(filepath.Join(dir, "mosquitto.conf"), []byte(content), os.ModePerm); err != nil { + sc.Errorf("Create MQTT config file failed: %s", err) + } + + image, ok := imageSet[constants.MQTTName] + if !ok { + image = "eclipse-mosquitto:1.6.15" + } + + if err := sc.Shell(fmt.Sprintf( + "docker run --name %s -d -p 1883:1883 -v /etc/diplomat/mosquitto:/mosquitto --restart unless-stopped %s", + constants.MQTTName, + image, + )); err != nil { + sc.Errorf("Start MQTT service failed: %s", err) + } + sc.Log("Start MQTT service successful") + } +} + +func JoinEdge(opt *common.JoinOption) aide.StepFunc { + return func(sc *aide.StepContext) { + // use 'installation-package' image to install Edge + sc.Log("Generate EdgeCore default configuration") + if err := createEdgeConfigFiles(opt); err != nil { + sc.Errorf("Create edge config file failed: %v", err) + } + + sc.Log("Generate systemd service file") + if err := util.GenerateServiceFile(constants.ConfigDir, constants.UsrBinPath, constants.EdgeComponent); err != nil { + sc.Errorf("Create systemd service file failed: %v", err) + } + + sc.Log("Run EdgeCore daemon") + if err := runEdgeCore(); err != nil { + sc.Errorf("Start EdgeCore failed: %v", err) + } + } +} + +func customEdgeConfig(opt *common.JoinOption, cfg *edgeconfig.EdgeCore) error { + host, _, err := net.SplitHostPort(opt.CloudCoreIPPort) + if err != nil { + return err + } + cfg.Modules.EdgeHub.HTTPServer = "https://" + net.JoinHostPort(host, "10002") + cfg.Modules.EdgeStream.TunnelServer = net.JoinHostPort(host, "10004") + cfg.Modules.EdgeHub.Token = opt.Token + cfg.Modules.EdgeHub.WebSocket.Server = opt.CloudCoreIPPort + + // 如果未定义节点名称,默认为自动注册 + if opt.EdgeNodeName != "" { + cfg.Modules.Edged.HostnameOverride = opt.EdgeNodeName + cfg.Modules.Edged.RegisterNode = false + return nil + } + + // 名称长度不能超过63个字符,mac地址默认占用18位,hash占用10位,限制34位 + hostnameOverride := cfg.Modules.Edged.HostnameOverride + if len(hostnameOverride) > 34 { + hostnameOverride = hostnameOverride[:33] + } + interfaces, err := net.Interfaces() + var hardware string + if err == nil { + for _, inter := range interfaces { + if inter.Name != "docker0" { + continue + } + if inter.HardwareAddr.String() != "" { + hardware = inter.HardwareAddr.String() + break + } + } + } + if hardware != "" { + hostnameOverride += "." + strings.ReplaceAll(hardware, ":", "-") + } + cfg.Modules.Edged.HostnameOverride = hash.BuildNodeName(opt.Namespace, hostnameOverride) + cfg.Modules.Edged.Annotations = map[string]string{ + "diplomat.99nil.com/ether": hardware, + } + cfg.Modules.Edged.Labels = map[string]string{ + "diplomat.99nil.com/auto": "node", + "app-offline.kubeedge.io": "autonomy", + "diplomat.99nil.com/namespace": opt.Namespace, + "diplomat.99nil.com/edge": hostnameOverride, + } + for _, v := range opt.Labels { + va := strings.Split(v, "=") + if len(va) != 2 { + continue + } + cfg.Modules.Edged.Labels[va[0]] = va[1] + } + return nil +} + +func createEdgeConfigFiles(opt *common.JoinOption) error { + var edgeCoreConfig *edgeconfig.EdgeCore + + configFilePath := filepath.Join(constants.ConfigDir, "edgecore.yaml") + _, err := os.Stat(configFilePath) + if err == nil || os.IsExist(err) { + // Read existing configuration file + b, err := os.ReadFile(configFilePath) + if err != nil { + return err + } + if err := yaml.Unmarshal(b, &edgeCoreConfig); err != nil { + return err + } + } + if edgeCoreConfig == nil { + // The configuration does not exist or the parsing fails, and the default configuration is generated + edgeCoreConfig = edgeconfig.NewDefaultEdgeCoreConfig(constants.RootDir, constants.ResourceDir) + } + + if err = customEdgeConfig(opt, edgeCoreConfig); err != nil { + return fmt.Errorf("config edge custom configuration failed, err: %v", err) + } + + edgeCoreConfig.Modules.EdgeHub.WebSocket.Server = opt.CloudCoreIPPort + if opt.Token != "" { + edgeCoreConfig.Modules.EdgeHub.Token = opt.Token + } + if opt.EdgeNodeName != "" { + edgeCoreConfig.Modules.Edged.HostnameOverride = opt.EdgeNodeName + } + if opt.RuntimeType != "" { + edgeCoreConfig.Modules.Edged.RuntimeType = opt.RuntimeType + } + + switch opt.CGroupDriver { + case constants.CGroupDriverSystemd: + edgeCoreConfig.Modules.Edged.CGroupDriver = constants.CGroupDriverSystemd + case constants.CGroupDriverCGroupFS: + edgeCoreConfig.Modules.Edged.CGroupDriver = constants.CGroupDriverCGroupFS + default: + return fmt.Errorf("unsupported CGroupDriver: %s", opt.CGroupDriver) + } + edgeCoreConfig.Modules.Edged.CGroupDriver = opt.CGroupDriver + + if opt.RemoteRuntimeEndpoint != "" { + edgeCoreConfig.Modules.Edged.RemoteRuntimeEndpoint = opt.RemoteRuntimeEndpoint + edgeCoreConfig.Modules.Edged.RemoteImageEndpoint = opt.RemoteRuntimeEndpoint + } + + host, _, err := net.SplitHostPort(opt.CloudCoreIPPort) + if err != nil { + return fmt.Errorf("get current host and port failed: %v", err) + } + if opt.CertPort != "" { + edgeCoreConfig.Modules.EdgeHub.HTTPServer = "https://" + net.JoinHostPort(host, opt.CertPort) + } else { + edgeCoreConfig.Modules.EdgeHub.HTTPServer = "https://" + net.JoinHostPort(host, "10002") + } + edgeCoreConfig.Modules.EdgeStream.TunnelServer = net.JoinHostPort(host, "10004") + + if len(opt.Labels) > 0 { + labelsMap := make(map[string]string) + for _, label := range opt.Labels { + arr := strings.SplitN(label, "=", 2) + if arr[0] == "" { + continue + } + + if len(arr) > 1 { + labelsMap[arr[0]] = arr[1] + } else { + labelsMap[arr[0]] = "" + } + } + edgeCoreConfig.Modules.Edged.Labels = labelsMap + } + + return util.Write2File(configFilePath, edgeCoreConfig) +} + +func runEdgeCore() error { + systemdExist := keutil.HasSystemd() + + var binExec, tip string + if systemdExist { + tip = fmt.Sprintf("KubeEdge edgecore is running, For logs visit: journalctl -u %s.service -xe", constants.EdgeComponent) + binExec = fmt.Sprintf( + "sudo systemctl daemon-reload && sudo systemctl enable %s && sudo systemctl start %s", + constants.EdgeComponent, constants.EdgeComponent) + } else { + tip = fmt.Sprintf("KubeEdge edgecore is running, For logs visit: %s/%s.log", constants.LogDir, constants.EdgeComponent) + binExec = fmt.Sprintf( + "%s > %s/edge/%s.log 2>&1 &", + filepath.Join(constants.UsrBinPath, constants.EdgeComponent), + constants.LogDir, + constants.EdgeComponent, + ) + } + + cmd := exec.NewCommand(binExec) + if err := cmd.Exec(); err != nil { + return err + } + logrus.Infoln(cmd.GetStdOut()) + logrus.Infoln(tip) + return nil +} diff --git a/core/assistant/reset.go b/core/assistant/reset.go new file mode 100644 index 0000000..ebe918f --- /dev/null +++ b/core/assistant/reset.go @@ -0,0 +1,306 @@ +// Copyright © 2022 99nil. +// +// 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 assistant + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/99nil/diplomat/global/constants" + + "github.com/AlecAivazis/survey/v2" + keutil "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" + "github.com/zc2638/aide" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/client-go/kubernetes" + utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime" + utilsexec "k8s.io/utils/exec" +) + +// ChooseResetConfirm reset之前先确认 +func ChooseResetConfirm(isEdgeNode bool) aide.StepFunc { + return func(sc *aide.StepContext) { + if isEdgeNode { + sc.Log("This is an edge side") + } else { + sc.Log("This is a cloud side") + } + var isReset bool + prompt := &survey.Confirm{ + Message: "[reset] WARNING: Changes made to this host by 'init' will be reverted.\n [reset] Are you sure you want to proceed? (default: yes)", + Default: true, + } + if err := survey.AskOne(prompt, &isReset); err != nil { + sc.Error(err) + } + if !isReset { + sc.Log("reset was cancelled!") + sc.Exit() + } + } +} + +func ResetCloud(kubeClient kubernetes.Interface) aide.StepFunc { + return func(sc *aide.StepContext) { + // For the cloudcore deploy on the container: When deleting the namespace, cloudcore is deleted as well + // 停止服务 + systemdExist := keutil.HasSystemd() + if systemdExist { + // remove the system service. + serviceFilePath := fmt.Sprintf("/etc/systemd/system/%s.service", constants.CloudComponent) + serviceFileRemoveExec := fmt.Sprintf("&& sudo rm %s", serviceFilePath) + if _, err := os.Stat(serviceFilePath); err != nil && os.IsNotExist(err) { + serviceFileRemoveExec = "" + } + command := fmt.Sprintf("sudo systemctl stop %s.service && sudo systemctl disable %s.service %s && sudo systemctl daemon-reload", + constants.CloudComponent, constants.CloudComponent, serviceFileRemoveExec) + if err := sc.Shell(command); err != nil { + sc.Logfl(aide.WarnLevel, "Stop diplomat cloud failed: %v", err) + } else { + sc.Log("Stop diplomat cloud successful") + } + } else { + if err := sc.Shell(fmt.Sprintf("pkill %s", constants.CloudComponent)); err != nil { + sc.Logfl(aide.WarnLevel, "Stop diplomat cloud failed: %v", err) + } else { + sc.Log("Stop diplomat cloud successful") + } + } + + // 清理目录 + if err := os.RemoveAll(constants.LogDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.LogDir, err) + } + if err := os.RemoveAll(constants.RootDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.RootDir, err) + } + if err := os.RemoveAll(constants.ResourceDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.RootDir, err) + } + + // 清理k8s资源 + rqt, err := labels.NewRequirement("diplomat", selection.Equals, []string{"diplomat"}) + if err != nil { + sc.Errorf("Failed to create k8s requirement, err: %s", err) + } + selector := labels.NewSelector().Add(*rqt) + sc.Log("Start to clean resource") + if err := kubeClient.RbacV1().ClusterRoleBindings().DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat clusterrolebinding: %s\n", err) + } + if err := kubeClient.RbacV1().ClusterRoles().DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat clusterrole: %s\n", err) + } + if err := kubeClient.PolicyV1beta1().PodSecurityPolicies().DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat policy: %s\n", err) + } + if err := kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations().DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat mutating webhook config: %s\n", err) + } + if err := kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat validating webhook config: %s\n", err) + } + // delete kube-system namespace raven-controller resource + if err := kubeClient.RbacV1().RoleBindings(constants.RavenControllerNamespace).DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat rolebinding: %s\n", err) + } + if err := kubeClient.RbacV1().Roles(constants.RavenControllerNamespace).DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat role: %s\n", err) + } + if err := kubeClient.CoreV1().ServiceAccounts(constants.RavenControllerNamespace).DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat serviceAccount: %s\n", err) + } + if err := kubeClient.CoreV1().Secrets(constants.RavenControllerNamespace).DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat secret: %s\n", err) + } + if err := kubeClient.AppsV1().Deployments(constants.RavenControllerNamespace).DeleteCollection( + sc.Context(), + metaV1.DeleteOptions{}, + metaV1.ListOptions{ + LabelSelector: selector.String(), + }); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat deployment: %s\n", err) + } + result, err := kubeClient.CoreV1().Services(constants.RavenControllerNamespace).List( + sc.Context(), + metaV1.ListOptions{ + LabelSelector: selector.String(), + }) + if err == nil { + for _, svc := range result.Items { + if err := kubeClient.CoreV1().Services(constants.RavenControllerNamespace).Delete( + sc.Context(), + svc.Name, + metaV1.DeleteOptions{}); err != nil { + sc.Logfl(aide.WarnLevel, "Failed to delete diplomat service: %s\n", err) + } + } + } else { + if !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Failed to list diplomat service: %s\n", err) + } + } + + if err := kubeClient.CoreV1().Namespaces().Delete( + sc.Context(), constants.DefaultNamespace, *metaV1.NewDeleteOptions(0)); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Clean kubernetes resources failed: %v", err) + } + if err := kubeClient.CoreV1().Namespaces().Delete( + sc.Context(), constants.SystemNamespace, *metaV1.NewDeleteOptions(0)); err != nil && !apierrors.IsNotFound(err) { + sc.Logfl(aide.WarnLevel, "Clean kubernetes resources failed: %v", err) + } + if err := checkNS(sc.Context(), kubeClient, constants.DefaultNamespace); err != nil { + sc.Logfl(aide.WarnLevel, "delete namespace %s failed: %v", err) + } + if err := checkNS(sc.Context(), kubeClient, constants.SystemNamespace); err != nil { + sc.Logfl(aide.WarnLevel, "delete namespace %s failed: %v", err) + } + sc.Log("Reset diplomat edge node successful") + } +} + +func checkNS(ctx context.Context, kubeClient kubernetes.Interface, namespace string) error { + for i := 0; i < 20; i++ { + _, err := kubeClient.CoreV1().Namespaces().Get(ctx, namespace, metaV1.GetOptions{}) + if apierrors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + time.Sleep(time.Second * 5) + } + return fmt.Errorf("delete namespace %s timeout", namespace) +} + +func ResetEdge() aide.StepFunc { + return func(sc *aide.StepContext) { + // 停止服务 + systemdExist := keutil.HasSystemd() + if systemdExist { + // remove the system service. + serviceFilePath := fmt.Sprintf("/etc/systemd/system/%s.service", constants.EdgeComponent) + serviceFileRemoveExec := fmt.Sprintf("&& sudo rm %s", serviceFilePath) + if _, err := os.Stat(serviceFilePath); err != nil && os.IsNotExist(err) { + serviceFileRemoveExec = "" + } + command := fmt.Sprintf("sudo systemctl stop %s.service && sudo systemctl disable %s.service %s && sudo systemctl daemon-reload", + constants.EdgeComponent, constants.EdgeComponent, serviceFileRemoveExec) + if err := sc.Shell(command); err != nil { + sc.Logfl(aide.WarnLevel, "Stop diplomat edge failed: %v", err) + } else { + sc.Log("Stop diplomat edge successful") + } + } else { + if err := sc.Shell(fmt.Sprintf("pkill %s", constants.EdgeComponent)); err != nil { + sc.Logfl(aide.WarnLevel, "Stop diplomat edge failed: %v", err) + } else { + sc.Log("Stop diplomat edge successful") + } + } + + // 清理MQTT容器 + if err := sc.Shell(fmt.Sprintf("docker rm -f %s", constants.MQTTName)); err != nil { + sc.Logfl(aide.WarnLevel, "Remove MQTT service container failed: %v", err) + } else { + sc.Log("Remove MQTT service successful") + } + + // 边缘端需要清理运行中的容器 + if err := removeK8sContainers(); err != nil { + sc.Logfl(aide.WarnLevel, "Clean kubernetes containers failed: %v", err) + } else { + sc.Log("Clean kubernetes containers successful") + } + + // 清理目录 + if err := os.RemoveAll(constants.LogDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.LogDir, err) + } + if err := os.RemoveAll(constants.RootDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.RootDir, err) + } + if err := os.RemoveAll(constants.ResourceDir); err != nil { + sc.Logfl(aide.WarnLevel, "Reset diplomat management directory `%s` failed: %v", constants.RootDir, err) + } + sc.Log("Reset diplomat diplomat node successful") + } +} + +func removeK8sContainers() error { + criSocketPath, err := utilruntime.DetectCRISocket() + if err != nil { + return err + } + containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), criSocketPath) + if err != nil { + return err + } + containers, err := containerRuntime.ListKubeContainers() + if err != nil { + return err + } + return containerRuntime.RemoveContainers(containers) +} diff --git a/core/component/component.go b/core/component/component.go index 9a082e2..b2b4165 100644 --- a/core/component/component.go +++ b/core/component/component.go @@ -17,6 +17,7 @@ package component import "context" type Interface interface { + PreInstall(ctx context.Context) error Install(ctx context.Context) error Uninstall(ctx context.Context) error } diff --git a/core/component/raven.go b/core/component/raven.go new file mode 100644 index 0000000..49fdd01 --- /dev/null +++ b/core/component/raven.go @@ -0,0 +1,227 @@ +// Copyright © 2022 99nil. +// +// 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 component + +import ( + "context" + "errors" + "fmt" + "os" + "runtime" + "strings" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/common" + "github.com/99nil/diplomat/pkg/exec" + "github.com/99nil/diplomat/pkg/util" + "github.com/99nil/diplomat/static" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + + "github.com/AlecAivazis/survey/v2" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + coreV1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/restmapper" +) + +var ( + cptFlannel = []string{"diplomat-flannel-edge", "diplomat-flannel"} + cptRaven = []string{"diplomat-raven-agent", "diplomat-raven-agent-edge"} +) + +var cptName = append(cptFlannel, cptRaven...) + +var FlannelVersion = "v0.7.4-diplomat" + +var RavenVersion = "v0.0.1-diplomat" + +type RavenInstallTool struct { + Ctx context.Context + + Resources [][]unstructured.Unstructured + KubeClient kubernetes.Interface + DynamicClient dynamic.Interface +} + +// PreInstall check whether the environment meets installation requirements. +func (t *RavenInstallTool) PreInstall(ctx context.Context) error { + // check ns + if _, err := t.KubeClient.CoreV1().Namespaces(). + Get(t.Ctx, constants.DefaultNamespace, metaV1.GetOptions{}); err != nil { + if apierrors.IsNotFound(err) { + if _, err = t.KubeClient.CoreV1().Namespaces(). + Create( + t.Ctx, + &coreV1.Namespace{ + ObjectMeta: metaV1.ObjectMeta{ + Name: constants.DefaultNamespace, + }, + }, + metaV1.CreateOptions{}); err != nil { + return err + } + return nil + } + return err + } + + // network plugins + if err := t.check(cptFlannel); err != nil { + return err + } + + // raven + if err := t.check(cptRaven); err != nil { + return err + } + + return nil +} + +func (t *RavenInstallTool) Install(ctx context.Context) error { + // apply yaml + gr, err := restmapper.GetAPIGroupResources(t.KubeClient.Discovery()) + if err != nil { + return fmt.Errorf("[raven install] get API group resources failed: %v", err) + } + mapping := restmapper.NewDiscoveryRESTMapper(gr) + + // The KubeEdge permissions required by the Raven component had been applied + for _, resources := range t.Resources { + wg, ctx := errgroup.WithContext(t.Ctx) + for _, obj := range resources { + currentObj := obj.DeepCopy() + wg.Go(func() error { + gvk := currentObj.GroupVersionKind() + logrus.Debugf("[raven install] apply resource %s %s", gvk, currentObj.GetName()) + + restMapping, err := mapping.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return err + } + + var resourceInter dynamic.ResourceInterface + if restMapping.Scope.Name() == meta.RESTScopeNameNamespace { + if currentObj.GetNamespace() == "" { + currentObj.SetNamespace(constants.DefaultNamespace) + } + resourceInter = t.DynamicClient.Resource(restMapping.Resource).Namespace(currentObj.GetNamespace()) + } else { + resourceInter = t.DynamicClient.Resource(restMapping.Resource) + } + + return common.ApplyResource(ctx, resourceInter, currentObj) + }) + } + if err = wg.Wait(); err != nil { + return fmt.Errorf("[raven install] apply resource failed: %v", err) + } + } + + // install custom specified architecture binary 'host-local' + if err = util.ExistsAndCreateDir(constants.CNIBinPath); err != nil { + return fmt.Errorf("[raven install] create dir failed, err: %v", err) + } + + fileName := "cni-plugins-" + runtime.GOARCH + "-" + FlannelVersion + ".tgz" + filePath := static.FlannelBin + "/" + fileName + if !util.IsFile(filePath) { + return fmt.Errorf("[raven install] failed to locate file %s", fileName) + } + + readFile, err := static.EmbedResource.ReadFile(filePath) + if err != nil { + return err + } + + fileHostPath := "/tmp/diplomat/" + fileName + if err = util.ExistsAndCreateDir("/tmp/diplomat/"); err != nil { + return fmt.Errorf("[raven install] create dir failed, err: %v", err) + } + if err = os.WriteFile(fileHostPath, readFile, 0666); err != nil { + return err + } + + if err = exec.NewCommand( + fmt.Sprintf("tar -zxvf %s -C %s", fileHostPath, constants.CNIBinPath), + ).Exec(); err != nil { + return fmt.Errorf("[raven install] failed to exec, err: %v", err) + } + return nil +} + +func (t *RavenInstallTool) Uninstall(ctx context.Context) error { + rq, err := labels.NewRequirement("app", selection.In, cptName) + if err != nil { + return err + } + + return t.KubeClient. + AppsV1(). + Deployments(constants.DefaultNamespace). + DeleteCollection(t.Ctx, + metaV1.DeleteOptions{}, + metaV1.ListOptions{LabelSelector: labels.NewSelector().Add(*rq).String()}, + ) +} + +func (t *RavenInstallTool) Rollback() error { + // TODO + return nil +} + +func (t *RavenInstallTool) check(label []string) error { + if len(label) == 0 { + return errors.New("label must not be null") + } + + rq, err := labels.NewRequirement("app", selection.In, label) + if err != nil { + return err + } + + list, err := t.KubeClient. + AppsV1(). + DaemonSets(constants.DefaultNamespace). + List(t.Ctx, metaV1.ListOptions{ + LabelSelector: labels.NewSelector().Add(*rq).String(), + }) + if err != nil { + return err + } + + if len(list.Items) > 0 { + b := false + prompt := &survey.Confirm{ + Message: fmt.Sprintf("Found %s, will be replaced by diplomat custom version. Confirm?", strings.Join(label, ",")), + } + if err := survey.AskOne(prompt, &b); err != nil { + return err + } + if !b { + logrus.Infof("exit Raven pre install check, confirm exit %s.\n", strings.Join(label, ",")) + return fmt.Errorf("user cofirm exit") + } + } + + return nil +} diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..bc29136 --- /dev/null +++ b/example/README.md @@ -0,0 +1,11 @@ +- kubectl apply -f examples/test-pod.yaml + +- kubectl apply -f examples/hostname.yaml + +- kubectl exec -it alpine-test -- sh + +- (在容器环境内) + + / # curl hostname-svc:12345 + + hostname-edge-84cb45ccf4-lh89n \ No newline at end of file diff --git a/example/alpine-curl.Dockerfile b/example/alpine-curl.Dockerfile new file mode 100644 index 0000000..248bced --- /dev/null +++ b/example/alpine-curl.Dockerfile @@ -0,0 +1,9 @@ +# docker buildx build --push --platform linux/arm64,linux/amd64,linux/arm,linux/ppc64le,linux/s390x \ +# -t $(REPO)/alpine-curl:$(TAG) -f alpine-curl.Dockerfile . +FROM alpine:latest + +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \ + apk update && \ + apk add --no-cache curl + +CMD ["tail", "-f", "/dev/null"] \ No newline at end of file diff --git a/example/hostname.yaml b/example/hostname.yaml new file mode 100644 index 0000000..17071d4 --- /dev/null +++ b/example/hostname.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hostname-edge + labels: + app: hostname-edge +spec: + replicas: 1 + selector: + matchLabels: + app: hostname-edge + template: + metadata: + labels: + app: hostname-edge + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: Exists + - key: node-role.kubernetes.io/agent + operator: Exists + containers: + - name: hostname + image: a526102465/serve_hostname:v0.1-diplomat + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: hostname-svc +spec: + selector: + app: hostname-edge + ports: + - name: http-0 + port: 12345 + protocol: TCP + targetPort: 9376 \ No newline at end of file diff --git a/example/test-pod.yaml b/example/test-pod.yaml new file mode 100644 index 0000000..ea34805 --- /dev/null +++ b/example/test-pod.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: Pod +metadata: + name: alpine-test +spec: + containers: + - name: alpine-curl + image: a526102465/alpine-curl:v0.1-diplomat + imagePullPolicy: IfNotPresent + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + - key: node-role.kubernetes.io/agent + operator: DoesNotExist +--- +apiVersion: v1 +kind: Pod +metadata: + name: websocket-test +spec: + containers: + - name: websocket + image: a526102465/websocket_echo:v0.1-diplomat + imagePullPolicy: IfNotPresent + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + - key: node-role.kubernetes.io/agent + operator: DoesNotExist \ No newline at end of file diff --git a/example/websocket.yaml b/example/websocket.yaml new file mode 100644 index 0000000..07b3d6e --- /dev/null +++ b/example/websocket.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ws-edge + labels: + app: ws-edge +spec: + replicas: 1 + selector: + matchLabels: + app: ws-edge + template: + metadata: + labels: + app: ws-edge + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: Exists + - key: node-role.kubernetes.io/agent + operator: Exists + containers: + - name: ws + image: a526102465/websocket_echo:v0.1-diplomat + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: ws-svc +spec: + selector: + app: ws-edge + ports: + - name: http-0 + port: 12348 + protocol: TCP + targetPort: 8080 \ No newline at end of file diff --git a/global/constants/constants.go b/global/constants/constants.go index 6c2b222..cc42739 100644 --- a/global/constants/constants.go +++ b/global/constants/constants.go @@ -17,9 +17,110 @@ package constants const ( ProjectName = "diplomat" ProjectDomain = ProjectName + ".99nil.com" + + DefaultNamespace = "diplomat" + SystemNamespace = "kubeedge" + RavenControllerNamespace = "kube-system" ) const ( AnnotationRelateClusterRole = ProjectDomain + "/clusterrole" AnnotationRelateRole = ProjectDomain + "/role" ) + +const ( + CNIBinPath = "/opt/cni/bin" + RootDir = "/etc/diplomat" + ResourceDir = "/var/lib/diplomat" + ExecDir = "/usr/local/bin" + LogDir = "/var/log/diplomat" + TmpPath = "/tmp/diplomat" + ConfigDir = RootDir + "/config" + DefaultCertPath = RootDir + "/certs" + UsrBinPath = "/usr/local/bin" +) + +const ( + ComponentCloudStream = "CloudStream" +) + +// use to show token for edge node join cloud +const ( + TokenSecretName = "tokensecret" + TokenDataName = "tokendata" +) + +const ( + KindService = "Service" + KindConfigMap = "ConfigMap" + KindDeployment = "Deployment" + KindDaemonSet = "DaemonSet" +) + +const ( + CloudComponent = "cloudcore" + EdgeComponent = "edgecore" +) + +const DockerContainerRuntime = "docker" + +// config field name +const ( + // CGroupDriver is type of edgecore Cgroup + CGroupDriver = "cgroupdriver" + + // CertPath sets the path of the certificates generated by the KubeEdge Cloud component + CertPath = "certPath" + + // CloudCoreIPPort sets the IP and port of KubeEdge cloud component + CloudCoreIPPort = "cloudcore-ipport" + + // EdgeNodeName is KubeEdge node unique identification string + EdgeNodeName = "edgenode-name" + + // Token sets the token used when edge applying for the certificate + Token = "token" + + Labels = "labels" + + // RuntimeType is default runtime type + RuntimeType = "runtimetype" + + // RemoteRuntimeEndpoint is KubeEdge remote-runtime-endpoint string + RemoteRuntimeEndpoint = "remote-runtime-endpoint" + + // CertPort is the port where to apply for the edge certificate + CertPort = "certport" + + // ImageRepository sets the image repository to pull images + ImageRepository = "image-repository" +) + +// edge config + +type ProtocolName string +type MqttMode int + +const ( + MQTTName = "mqtt" +) + +const ( + MqttModeInternal MqttMode = 0 + MqttModeBoth MqttMode = 1 + MqttModeExternal MqttMode = 2 +) + +const ( + CGroupDriverCGroupFS = "cgroupfs" + CGroupDriverSystemd = "systemd" +) + +const ( + // DataBaseDriverName is sqlite3 + DataBaseDriverName = "sqlite3" + // DataBaseAliasName is default + DataBaseAliasName = "default" + // DataBaseDataSource is edge.db + DataBaseDataSource = "edgecore.db" +) diff --git a/go.mod b/go.mod index 90a784b..ec54f3b 100644 --- a/go.mod +++ b/go.mod @@ -7,24 +7,34 @@ replace github.com/99nil/dsync => ./staging/src/github.com/99nil/dsync require ( github.com/99nil/dsync v0.0.0-00010101000000-000000000000 github.com/99nil/gopkg v0.0.0-20220607055250-e19b23d7661a - github.com/docker/docker v20.10.17+incompatible + github.com/AlecAivazis/survey/v2 v2.3.6 + github.com/docker/docker v20.10.12+incompatible github.com/go-chi/chi v1.5.4 + github.com/kubeedge/kubeedge v1.11.2 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/r3labs/sse/v2 v2.8.0 github.com/sirupsen/logrus v1.8.1 - github.com/spf13/cobra v1.4.0 + github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.12.0 + github.com/zc2638/aide v0.0.1 golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 - k8s.io/client-go v0.24.1 + gopkg.in/yaml.v3 v3.0.1 + k8s.io/api v0.22.6 + k8s.io/apimachinery v0.22.6 + k8s.io/client-go v0.22.6 + k8s.io/klog/v2 v2.60.1 + k8s.io/kubernetes v1.22.6 k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 + sigs.k8s.io/yaml v1.3.0 ) require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/containerd/containerd v1.5.10 // indirect + github.com/cyphar/filepath-securejoin v0.2.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect @@ -32,36 +42,34 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/emicklei/go-restful v2.9.5+incompatible // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.5 // indirect - github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.8 // indirect - github.com/google/gofuzz v1.1.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.12.3 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/runc v1.0.3 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -72,30 +80,63 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.0 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect + golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect + golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect + google.golang.org/grpc v1.46.2 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.3.0 // indirect - k8s.io/api v0.24.1 // indirect - k8s.io/klog/v2 v2.60.1 // indirect + k8s.io/apiserver v0.22.6 // indirect + k8s.io/cluster-bootstrap v0.22.6 // indirect + k8s.io/component-base v0.22.6 // indirect + k8s.io/component-helpers v0.22.6 // indirect + k8s.io/cri-api v0.22.6 // indirect k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect ) -require ( - github.com/go-logr/logr v1.2.3 // indirect - k8s.io/apimachinery v0.24.1 +replace ( + github.com/kubeedge/beehive v0.0.0 => github.com/kubeedge/beehive v1.7.0 + github.com/kubeedge/viaduct v0.0.0 => github.com/kubeedge/viaduct v1.7.0 + k8s.io/api v0.0.0 => k8s.io/api v0.22.6 + k8s.io/apiextensions-apiserver v0.0.0 => k8s.io/apiextensions-apiserver v0.22.6 + k8s.io/apimachinery v0.0.0 => k8s.io/apimachinery v0.22.6 + k8s.io/apiserver v0.0.0 => k8s.io/apiserver v0.22.6 + k8s.io/cli-runtime v0.0.0 => k8s.io/cli-runtime v0.22.6 + k8s.io/client-go v0.0.0 => k8s.io/client-go v0.22.6 // indirect + k8s.io/cloud-provider v0.0.0 => k8s.io/cloud-provider v0.22.6 // indirect + k8s.io/cluster-bootstrap v0.0.0 => k8s.io/cluster-bootstrap v0.22.6 + k8s.io/code-generator v0.0.0 => k8s.io/code-generator v0.15.8-beta.1 + k8s.io/component-base v0.0.0 => k8s.io/component-base v0.22.6 + k8s.io/component-helpers v0.0.0 => k8s.io/component-helpers v0.22.6 + k8s.io/controller-manager v0.0.0 => k8s.io/controller-manager v0.22.6 + k8s.io/cri-api v0.0.0 => k8s.io/cri-api v0.22.6 + k8s.io/csi-translation-lib v0.0.0 => k8s.io/csi-translation-lib v0.22.6 + k8s.io/gengo v0.0.0 => k8s.io/gengo v0.22.6 // indirect + k8s.io/heapster => k8s.io/heapster v1.2.0-beta.1 // indirect + k8s.io/klog => k8s.io/klog v0.4.0 // indirect + k8s.io/kube-aggregator v0.0.0 => k8s.io/kube-aggregator v0.22.6 + k8s.io/kube-controller-manager v0.0.0 => k8s.io/kube-controller-manager v0.22.6 + k8s.io/kube-openapi v0.0.0 => k8s.io/kube-openapi v0.22.6 // indirect + k8s.io/kube-proxy v0.0.0 => k8s.io/kube-proxy v0.22.6 + k8s.io/kube-scheduler v0.0.0 => k8s.io/kube-scheduler v0.22.6 + k8s.io/kubectl => k8s.io/kubectl v0.22.6 + k8s.io/kubelet v0.0.0 => k8s.io/kubelet v0.22.6 + k8s.io/legacy-cloud-providers v0.0.0 => k8s.io/legacy-cloud-providers v0.22.6 + k8s.io/metrics v0.0.0 => k8s.io/metrics v0.22.6 + k8s.io/mount-utils v0.0.0 => k8s.io/mount-utils v0.22.6 + k8s.io/node-api v0.0.0 => k8s.io/node-api v0.22.6 // indirect + k8s.io/pod-security-admission v0.0.0 => k8s.io/pod-security-admission v0.22.6 + k8s.io/repo-infra v0.0.0 => k8s.io/repo-infra v0.22.6 // indirect + k8s.io/sample-apiserver v0.0.0 => k8s.io/sample-apiserver v0.22.6 + k8s.io/utils v0.0.0 => k8s.io/utils v0.22.6 + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.0 => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27 ) diff --git a/go.sum b/go.sum index 9deb799..8952fcf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -7,6 +11,7 @@ cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -28,6 +33,7 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -38,121 +44,470 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/256dpi/gomqtt v0.10.4/go.mod h1:C+397CXyL3GyYapLHsAMlAozXofYs4XxwkNZsSPvbuI= +github.com/256dpi/mercury v0.1.0/go.mod h1:W2/eVt6tqfSn5J8en63oGNmnZSb66PUo0e5YBzSHkkU= github.com/99nil/gopkg v0.0.0-20220607055250-e19b23d7661a h1:R2DqdZwoECFZIIxWL9DeyDLXoLgaJhus492ck5bH2to= github.com/99nil/gopkg v0.0.0-20220607055250-e19b23d7661a/go.mod h1:Q/b1t+c95u1WpUKhSU/xsasqd2P+iZGS9eP7EDB7ZuU= +github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw= +github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ= +github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= +github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= +github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/OwnLocal/goes v1.0.0/go.mod h1:8rIFjBGTue3lCU0wplczcUgt9Gxgrkkrw7etMIcn8TM= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg= +github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +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/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +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/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/astaxie/beego v1.12.0/go.mod h1:fysx+LZNZKnvh4GED/xND7jWtjCR6HzydR2Hh2Im57o= +github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= +github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= +github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= 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/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= +github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= +github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= +github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= +github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= +github.com/containerd/containerd v1.5.10 h1:3cQ2uRVCkJVcx5VombsE7105Gl9Wrl7ORAO3+4+ogf4= +github.com/containerd/containerd v1.5.10/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= +github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= +github.com/coredns/corefile-migration v1.0.12/go.mod h1:NJOI8ceUF/NTgEwtjD+TUq3/BnH/GF7WAM3RzCa3hBo= +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-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= +github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= +github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +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/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= +github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= 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= +github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U= +github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= 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/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= +github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +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.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +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= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= +github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= +github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI= +github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= 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= @@ -179,11 +534,16 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cadvisor v0.39.3/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI= github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= @@ -199,11 +559,15 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +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= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -220,137 +584,480 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.3.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= 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/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +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.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= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +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/heketi/heketi v10.3.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= +github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v0.0.0-20170918002102-8eab2debe79d/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= +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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +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/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kubeedge/beehive v0.0.0-20201125122335-cd19bca6e436/go.mod h1:98VgUi/n7HZkxT3Q7Lak75kPtIRRrWam02BgqgT0tkE= +github.com/kubeedge/beehive v1.7.0/go.mod h1:98VgUi/n7HZkxT3Q7Lak75kPtIRRrWam02BgqgT0tkE= +github.com/kubeedge/kubeedge v1.11.2 h1:z2gJ9NaEVvPdGa+99dM9iLZ1DPXxQPVmnhiPejarswY= +github.com/kubeedge/kubeedge v1.11.2/go.mod h1:GMhBb1+Nv4PuYzI80cF+jT5Q3PlPSIY+gifphUNgQPg= +github.com/kubeedge/viaduct v1.7.0/go.mod h1:9YFeEaWK8WdVl+sjcQlhuRe1rEhWz3Nu/l29CKmL+EY= +github.com/kubernetes-csi/csi-lib-utils v0.6.1/go.mod h1:GVmlUmxZ+SUjVLXicRFjqWUUvWez0g0Y78zNV9t7KfQ= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= +github.com/lucas-clemente/quic-go v0.19.2/go.mod h1:ZUygOqIoai0ASXXLJ92LTnKdbqh9MHCLTX6Nr1jUrK0= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +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.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +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.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4= +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-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 h1:yH0SvLzcbZxcJXho2yh7CqdENGMQe73Cw3woZBpPli0= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 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.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +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.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +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 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= 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.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= +github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 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/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quobyte/api v0.1.8/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/r3labs/sse/v2 v2.8.0 h1:El87DStHljKBTTsbDAdng3PLBej64+9wPafaYIkcV5A= github.com/r3labs/sse/v2 v2.8.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= +github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo= +github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v2.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= +github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= +github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +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 v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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 v0.0.0-20180303142811-b89eecf5ca5d/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/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -359,15 +1066,72 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +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/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/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 v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +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/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zc2638/aide v0.0.1 h1:5DhR1mENE3OeqfjPs4cl94Gn+EpbxZ1buuBm4O+O0jM= +github.com/zc2638/aide v0.0.1/go.mod h1:MG2oT92+HSR/LqK5sdY49RalR8asFQYgUEgI8lyGU8U= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -376,19 +1140,68 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/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= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -396,8 +1209,11 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -409,31 +1225,48 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 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-20190619014844-b5b0513f8c1b/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-20190628185345-da137c7871d7/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-20190827160401-ba9fcec4b297/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-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -450,20 +1283,26 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -474,9 +1313,10 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -490,28 +1330,56 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-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-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-20190316082340-a2f829d7f35f/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-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/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-20190616124812-15dcb6c0061f/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-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/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-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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= @@ -521,12 +1389,26 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -534,20 +1416,32 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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= @@ -558,27 +1452,41 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 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-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= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -586,6 +1494,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -595,6 +1504,7 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -610,16 +1520,28 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -627,6 +1549,7 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= @@ -641,7 +1564,10 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -649,11 +1575,17 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -662,6 +1594,7 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -670,8 +1603,10 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -681,6 +1616,7 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -691,10 +1627,20 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -704,11 +1650,18 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -724,26 +1677,44 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +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/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= +gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= @@ -753,9 +1724,14 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= -gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +helm.sh/helm/v3 v3.7.2/go.mod h1:UXuiAn0+FfBpqbiMuwWt8/aAKkfJvnWLBJ6f4HcFs0M= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -763,29 +1739,133 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.24.1 h1:BjCMRDcyEYz03joa3K1+rbshwh1Ay6oB53+iUx2H8UY= -k8s.io/api v0.24.1/go.mod h1:JhoOvNiLXKTPQ60zh2g0ewpA+bnEYf5q44Flhquh4vQ= -k8s.io/apimachinery v0.24.1 h1:ShD4aDxTQKN5zNf8K1RQ2u98ELLdIW7jEnlO9uAMX/I= -k8s.io/apimachinery v0.24.1/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/client-go v0.24.1 h1:w1hNdI9PFrzu3OlovVeTnf4oHDt+FJLd9Ndluvnb42E= -k8s.io/client-go v0.24.1/go.mod h1:f1kIDqcEYmwXS/vTbbhopMUbhKp2JhOeVTfxgaCIlF8= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.20.10/go.mod h1:0kei3F6biGjtRQBo5dUeujq6Ji3UCh9aOSfp/THYd7I= +k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= +k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk= +k8s.io/api v0.22.6 h1:acjE5ABt0KpsBI9QCtLqaQEPSF94jOtE/LoFxSYasSE= +k8s.io/api v0.22.6/go.mod h1:q1F7IfaNrbi/83ebLy3YFQYLjPSNyunZ/IXQxMmbwCg= +k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= +k8s.io/apiextensions-apiserver v0.22.4/go.mod h1:kH9lxD8dbJ+k0ZizGET55lFgdGjO8t45fgZnCVdZEpw= +k8s.io/apiextensions-apiserver v0.22.6/go.mod h1:wNsLwy8mfIkGThiv4Qq/Hy4qRazViKXqmH5pfYiRKyY= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apimachinery v0.20.10/go.mod h1:kQa//VOAwyVwJ2+L9kOREbsnryfsGSkSM1przND4+mw= +k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0= +k8s.io/apimachinery v0.22.6 h1:z7vxNRkFX0NToA+8D17kzLZ/T4t+DqwzUlqqbqRepRs= +k8s.io/apimachinery v0.22.6/go.mod h1:ZvVLP5iLhwVFg2Yx9Gh5W0um0DUauExbRhe+2Z8I1EU= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI= +k8s.io/apiserver v0.22.4/go.mod h1:38WmcUZiiy41A7Aty8/VorWRa8vDGqoUzDf2XYlku0E= +k8s.io/apiserver v0.22.6 h1:5MXAa5zBEd7dvCmaqrYV5GohA5jvNAmJX3Hy78JAGDY= +k8s.io/apiserver v0.22.6/go.mod h1:OlL1rGa2kKWGj2JEXnwBcul/BwC9Twe95gm4ohtiIIs= +k8s.io/cli-runtime v0.22.4/go.mod h1:x35r0ERHXr/MrbR1C6MPJxQ3xKG6+hXi9m2xLzlMPZA= +k8s.io/cli-runtime v0.22.6/go.mod h1:UY6oHyBUZ/y0O6ovyyPy++S5LdijxJSOizXsrAP+qKU= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.20.10/go.mod h1:fFg+aLoasv/R+xiVaWjxeqGFYltzgQcOQzkFaSRfnJ0= +k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= +k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA= +k8s.io/client-go v0.22.6 h1:ugAXeC312xeGXsn7zTRz+btgtLBnW3qYhtUUpVQL7YE= +k8s.io/client-go v0.22.6/go.mod h1:TffU4AV2idZGeP+g3kdFZP+oHVHWPL1JYFySOALriw0= +k8s.io/cloud-provider v0.22.6/go.mod h1:qKWDzOCIsSWlPvC4txa9X+IuxeJX8LWf9jz/ClpBIPQ= +k8s.io/cluster-bootstrap v0.22.6 h1:Jm1MDTPSxHRQp9m4jT44fVv9S2BiEivZ+R8JjEEdTdQ= +k8s.io/cluster-bootstrap v0.22.6/go.mod h1:G8vRWaBElK/3fk3UsnqFKO4Sr8LyX6urLqdkuPXOC8k= +k8s.io/code-generator v0.15.8-beta.1/go.mod h1:G8bQwmHm2eafm5bgtX67XDZQ8CWKSGu9DekI+yN4Y5I= +k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= +k8s.io/code-generator v0.22.4/go.mod h1:qjYl54pQ/emhkT0UxbufbREYJMWsHNNV/jSVwhYZQGw= +k8s.io/code-generator v0.22.6/go.mod h1:iOZwYADSgFPNGWfqHFfg1V0TNJnl1t0WyZluQp4baqU= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.20.10/go.mod h1:ZKOEin1xu68aJzxgzl5DZSp5J1IrjAOPlPN90/t6OI8= +k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug= +k8s.io/component-base v0.22.4/go.mod h1:MrSaQy4a3tFVViff8TZL6JHYSewNCLshZCwHYM58v5A= +k8s.io/component-base v0.22.6 h1:YgGMDVnr97rhn0eljuYIU/9XFyz8JVDM30slMYrDgPc= +k8s.io/component-base v0.22.6/go.mod h1:ngHLefY4J5fq2fApNdbWyj4yh0lvw36do4aAjNN8rc8= +k8s.io/component-helpers v0.22.6 h1:0ReyVoTv1AVz2aZyxdTSkdN3YawEJfEEJZ2Uuol1s8w= +k8s.io/component-helpers v0.22.6/go.mod h1:C2jlCvarTU8hnT493tS17t3rjk51c8nang8L1D9lQ5Q= +k8s.io/controller-manager v0.22.6/go.mod h1:yklwmkmk51pUYyo8URpFer7R07wcvVq/xNRUN36oDDs= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/cri-api v0.22.6 h1:bloknXbu0D6fPbOl2oMGH5ap0VEyE7EYmlLkp/RQgA4= +k8s.io/cri-api v0.22.6/go.mod h1:uAw9CICQq20/1yB4ZnWT2TjJyMMROl4typFfWaURLwQ= +k8s.io/csi-translation-lib v0.22.6/go.mod h1:/O6a26XNs3xsiAZeHUF75dDQt8dyT53c5C8JBSryLTQ= +k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-aggregator v0.22.6/go.mod h1:0RSTzxqiwsj5HUlov195Z72ZKyE4qgedKXCl6sLKAjM= +k8s.io/kube-controller-manager v0.22.6/go.mod h1:RkYKr813YbQhuOBK+12gikPvK/AXy80qovB6YmHfzW8= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU= k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= +k8s.io/kube-proxy v0.22.6/go.mod h1:xLxEZ3sHyz11XaRyxqI4Z4F3I/Wtt+Jlep8w5yxQPAY= +k8s.io/kube-scheduler v0.22.6/go.mod h1:DcHj6ixvb0M1PvWFbg133a1pz/vv7OSCgZUDU/UUhlU= +k8s.io/kubectl v0.22.6/go.mod h1:9ktAgMwUsd2w12Yhj/xhMZhNna1t9rfExJg9j9jCIYk= +k8s.io/kubelet v0.22.6/go.mod h1:/nSfVw7oYzpmLn8Ua2q2Zix09Fq5gpDGnNqTbab9wts= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/kubernetes v1.22.6 h1:OPKNO4FElcN6wHc3N3P6uW3P1oHvzNxu+HJ8vGQtBzM= +k8s.io/kubernetes v1.22.6/go.mod h1:l2ikQCpfvsMAXgL7FDtzgn/AVdjt4XGUYHMXn2vuzYI= +k8s.io/legacy-cloud-providers v0.22.6/go.mod h1:ZhqLzcCCT4mGgxzVXJNg9/zQDBE8S2isa053fzXSR1s= +k8s.io/metrics v0.22.6/go.mod h1:4a2o3y5qe2CleeMWZ80VCKzz+N8vPboAw/pz3xKQicI= +k8s.io/mount-utils v0.22.6/go.mod h1:dHl6c2P60T5LHUnZxVslyly9EDCMzvhtISO5aY+Z4sk= +k8s.io/pod-security-admission v0.22.6/go.mod h1:aBlsoKgqpuixDMaCu7U4d8IywNzcmGAKi7/fmfr840M= +k8s.io/sample-apiserver v0.22.6/go.mod h1:wiamO3alvd/dicaP8PvTPCdqq31QKDbRxm1uqOGalsI= +k8s.io/system-validators v1.5.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= +modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +oras.land/oras-go v0.4.0/go.mod h1:VJcU+VE4rkclUbum5C0O7deEZbBYnsnpbGSACwTjOcg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/apiserver-network-proxy v0.0.27/go.mod h1:du+Uh7WMRMVMnDwJDx2EahhL+pKqPHLwbWqkNHtlU+o= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27/go.mod h1:tq2nT0Kx7W+/f2JVE+zxYtUhdjuELJkVpNz+x/QN5R4= +sigs.k8s.io/controller-runtime v0.10.3/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= +sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= +sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs= +sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go= +sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/pkg/common/common.go b/pkg/common/common.go new file mode 100644 index 0000000..12a3f60 --- /dev/null +++ b/pkg/common/common.go @@ -0,0 +1,59 @@ +// Copyright © 2022 99nil. +// +// 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 common + +import ( + "context" + "fmt" + "strconv" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/dynamic" +) + +func IsSpecialName(name string) bool { + // TODO 指定svc暴露 + return true +} + +func ApplyResource( + ctx context.Context, + resourceInter dynamic.ResourceInterface, + obj *unstructured.Unstructured, +) error { + current, err := resourceInter.Get(ctx, obj.GetName(), metaV1.GetOptions{ + TypeMeta: metaV1.TypeMeta{ + Kind: obj.GetKind(), + APIVersion: obj.GetAPIVersion(), + }, + }) + if err == nil { + rv, _ := strconv.ParseInt(current.GetResourceVersion(), 10, 64) + obj.SetResourceVersion(strconv.FormatInt(rv, 10)) + if _, err = resourceInter.Update(ctx, obj, metaV1.UpdateOptions{}); err != nil { + err = fmt.Errorf("update %s %s failed: %v", obj.GetKind(), obj.GetName(), err) + } + return err + } + if !apierrors.IsNotFound(err) { + return err + } + if _, err = resourceInter.Create(ctx, obj, metaV1.CreateOptions{}); err != nil { + err = fmt.Errorf("create %s %s failed: %v", obj.GetKind(), obj.GetName(), err) + } + return err +} diff --git a/pkg/common/option.go b/pkg/common/option.go new file mode 100644 index 0000000..4e13ec2 --- /dev/null +++ b/pkg/common/option.go @@ -0,0 +1,192 @@ +// Copyright © 2022 99nil. +// +// 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 common + +import ( + "os" + "strings" + "sync" + + "github.com/99nil/diplomat/global/constants" + "github.com/spf13/cobra" +) + +var ( + AdmissionImage = "docker.io/a526102465/admission:v1.11.2-diplomat" + CloudcoreImage = "docker.io/a526102465/cloudcore:v1.11.2-diplomat" + InstallationPackageImage = "docker.io/a526102465/installation-package:v1.11.2-diplomat" + RavenAgentImage = "docker.io/a526102465/raven-agent:v0.0.1-diplomat" + RavenControllerImage = "docker.io/a526102465/raven-controller:v0.0.1-diplomat" + FlannelImage = "docker.io/a526102465/flannel:v0.14.0-diplomat" +) + +const ( + AdmissionName = "admission" + CloudcoreName = "cloudcore" + InstallationPackageName = "installationpackage" + RavenAgentName = "ravenagent" + RavenControllerName = "ravencontroller" + FlannelName = "flannel" +) + +func NewCloudImageSet() map[string]string { + // 以static下的yaml内的版本为主,这里不要添加默认的 + // 否则将会以imageSet中的版本为优先 + imageSet := make(map[string]string) + imageSet[AdmissionName] = AdmissionImage + imageSet[CloudcoreName] = CloudcoreImage + imageSet[RavenAgentName] = RavenAgentImage + imageSet[RavenControllerName] = RavenControllerImage + imageSet[FlannelName] = FlannelImage + return imageSet +} + +func NewEdgeImageSet() map[string]string { + // 以static下的yaml内的版本为主,这里不要添加默认的 + // 否则将会以imageSet中的版本为优先 + imageSet := make(map[string]string) + imageSet[InstallationPackageName] = InstallationPackageImage + return imageSet +} + +type PortSet struct { + set sync.Map +} + +func (s *PortSet) Has(name string) bool { + _, ok := s.set.Load(name) + return ok +} + +func (s *PortSet) Get(name string) int32 { + val, ok := s.set.Load(name) + if ok { + return val.(int32) + } + return 0 +} + +func (s *PortSet) Add(name string, port int32) { + s.set.Store(name, port) +} + +func (s *PortSet) Remove(name string) { + s.set.Delete(name) +} + +func (s *PortSet) Range(f func(name string, port int32) bool) { + s.set.Range(func(key, value interface{}) bool { + return f(key.(string), value.(int32)) + }) +} + +func (s *PortSet) Reset() { + s.set = sync.Map{} +} + +func NewPortOption() *PortSet { + ps := new(PortSet) + //ps.Add(BackendName, 31181) + //ps.Add(FrontendName, 31180) + //ps.Add(MysqlName, 31186) + //ps.Add(KeycloakName, 31187) + //ps.Add(ManualName, 31189) + // + //ps.Add(PrometheusOperator, 31190) + //ps.Add(Prometheus, 31191) + //ps.Add(Alertmanager, 31192) + // + //ps.Add(LokiName, 31300) + //ps.Add(GrafanaName, 31301) + return ps +} + +type GlobalOption struct { + Module string + EnvPrefix string + Config string + // 显示详细 + Verbose bool + // k8s配置文件路径 + KubeConfig string +} + +func (o *GlobalOption) CompleteFlags(cmd *cobra.Command) { + cfgPathEnv := os.Getenv(o.EnvPrefix + "_CONFIG") + if cfgPathEnv == "" { + cfgPathEnv = "config/config.yaml" + } + cmd.Flags().StringVarP(&o.Config, "config", "c", cfgPathEnv, + "config file (default is $HOME/config.yaml)") +} + +func NewGlobalOption(module string) *GlobalOption { + opt := &GlobalOption{Module: module} + module = strings.ReplaceAll(module, "-", "_") + opt.EnvPrefix = strings.ToUpper(constants.ProjectName + "_" + module) + return opt +} + +const ( + EnvDev = "dev" + EnvProd = "prod" +) + +const ( + TypeBinary = "binary" + TypeContainer = "container" +) + +type InitOption struct { + // 安装类型:二进制binary、容器部署container + Type string + // 服务端可用的IP地址,如果有多个,则以逗号分隔,主要用于证书签名 + AdvertiseAddress string + // 服务端可用的域名,如果有多个,则以逗号分隔,主要用于证书签名 + Domain string + // k8s的证书路径,用于(cloud-stream)日志流服务的证书签名 + K8sCertPath string + // 环境: dev、prod + Env string + // 需要被禁用的组件,如果有多个则以逗号分隔,例如 cloudStream,deviceController + Disable []string + // 指定镜像仓库 e.g. k8s.gcr.io docker.io/99nil + ImageRepository string + // 指定镜像仓库用户名称 + ImageRepositoryUsername string + // 指定镜像仓库用户密码 + ImageRepositoryPassword string + // 安装过程使用的正确IP,从advertiseAddress解析出第一个,如果没有则读取hostIP + CurrentIP string +} + +type JoinOption struct { + CloudCoreIPPort string + EdgeNodeName string + Namespace string + CGroupDriver string + CertPath string + RuntimeType string + RemoteRuntimeEndpoint string + Token string + CertPort string + WithMQTT bool + ImageRepository string + Labels []string +} + +type ResetOption struct { + Force bool +} diff --git a/pkg/edgeconfig/cloud.go b/pkg/edgeconfig/cloud.go new file mode 100644 index 0000000..80d6a6c --- /dev/null +++ b/pkg/edgeconfig/cloud.go @@ -0,0 +1,614 @@ +// Copyright © 2022 99nil. +// +// 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 edgeconfig + +import ( + "encoding/json" + "errors" + "os" + "path" + "path/filepath" + "time" + + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/klog/v2" + "sigs.k8s.io/yaml" +) + +const ( + GroupName = "cloudcore.diplomat.99nil.com" + APIVersion = "v1alpha1" + Kind = "CloudCore" +) + +const ( + DefaultKubeContentType = "application/vnd.kubernetes.protobuf" + DefaultKubeConfig = "/root/.kube/config" + DefaultKubeQPS = 100.0 + DefaultKubeBurst = 200 + + DefaultBuffer = 1024 + DefaultEventBuffer = 1 +) + +// NewDefaultCloudCoreConfig returns a full CloudCoreConfig object +func NewDefaultCloudCoreConfig(rootDir, resourceDir string) *CloudCore { + advertiseAddress, _ := utilnet.ChooseHostInterface() + cfg := &CloudCore{ + TypeMeta: metaV1.TypeMeta{ + Kind: Kind, + APIVersion: path.Join(GroupName, APIVersion), + }, + CommonConfig: &CommonConfig{ + TunnelPort: 10350, + }, + KubeAPIConfig: &KubeAPIConfig{ + ContentType: DefaultKubeContentType, + QPS: DefaultKubeQPS, + Burst: DefaultKubeBurst, + KubeConfig: DefaultKubeConfig, + }, + Modules: &CloudModules{ + CloudHub: &CloudHub{ + Enable: true, + KeepaliveInterval: 30, + NodeLimit: 1000, + TLSCAFile: filepath.Join(rootDir, "/ca/rootCA.crt"), + TLSCAKeyFile: filepath.Join(rootDir, "/ca/rootCA.key"), + TLSCertFile: filepath.Join(rootDir, "/certs/server.crt"), + TLSPrivateKeyFile: filepath.Join(rootDir, "/certs/server.key"), + WriteTimeout: 30, + AdvertiseAddress: []string{advertiseAddress.String()}, + DNSNames: []string{""}, + EdgeCertSigningDuration: 365, + TokenRefreshDuration: 12, + Quic: &CloudHubQUIC{ + Enable: false, + Address: "0.0.0.0", + Port: 10001, + MaxIncomingStreams: 10000, + }, + UnixSocket: &CloudHubUnixSocket{ + Enable: true, + Address: "unix://" + filepath.Join(resourceDir, "edge.sock"), + }, + WebSocket: &CloudHubWebSocket{ + Enable: true, + Port: 10000, + Address: "0.0.0.0", + }, + HTTPS: &CloudHubHTTPS{ + Enable: true, + Port: 10002, + Address: "0.0.0.0", + }, + }, + EdgeController: &EdgeController{ + Enable: true, + NodeUpdateFrequency: 10, + Buffer: &EdgeControllerBuffer{ + PodEvent: DefaultEventBuffer, + ConfigMapEvent: DefaultEventBuffer, + SecretEvent: DefaultEventBuffer, + ServiceEvent: DefaultEventBuffer, + EndpointsEvent: DefaultEventBuffer, + RulesEvent: DefaultEventBuffer, + RuleEndpointsEvent: DefaultEventBuffer, + UpdatePodStatus: DefaultBuffer, + UpdateNodeStatus: DefaultBuffer, + QueryConfigMap: DefaultBuffer, + QuerySecret: DefaultBuffer, + QueryService: DefaultBuffer, + QueryEndpoints: DefaultBuffer, + QueryPersistentVolume: DefaultBuffer, + QueryPersistentVolumeClaim: DefaultBuffer, + QueryVolumeAttachment: DefaultBuffer, + QueryNode: DefaultBuffer, + UpdateNode: DefaultBuffer, + DeletePod: DefaultBuffer, + ServiceAccountToken: DefaultBuffer, + }, + Load: &EdgeControllerLoad{ + UpdatePodStatusWorkers: 1, + UpdateNodeStatusWorkers: 1, + QueryConfigMapWorkers: 4, + QuerySecretWorkers: 4, + QueryServiceWorkers: 4, + QueryEndpointsWorkers: 4, + QueryPersistentVolumeWorkers: 4, + QueryPersistentVolumeClaimWorkers: 4, + QueryVolumeAttachmentWorkers: 4, + QueryNodeWorkers: 4, + UpdateNodeWorkers: 4, + DeletePodWorkers: 4, + UpdateRuleStatusWorkers: 4, + ServiceAccountTokenWorkers: 4, + }, + }, + DeviceController: &DeviceController{ + Enable: true, + Buffer: &DeviceControllerBuffer{ + UpdateDeviceStatus: DefaultBuffer, + DeviceEvent: DefaultEventBuffer, + DeviceModelEvent: DefaultEventBuffer, + }, + Load: &DeviceControllerLoad{ + UpdateDeviceStatusWorkers: 1, + }, + }, + SyncController: &SyncController{ + Enable: true, + }, + DynamicController: &DynamicController{ + Enable: true, + }, + Router: &Router{ + Enable: false, + Address: "0.0.0.0", + Port: 9443, + RestTimeout: 60, + }, + IptablesManager: &IptablesManager{ + Enable: false, + Mode: InternalMode, + }, + }, + } + cfg.Modules.CloudStream = &CloudStream{ + Enable: true, + StreamPort: 10003, + TunnelPort: 10004, + TLSTunnelCAFile: cfg.Modules.CloudHub.TLSCAFile, + TLSTunnelCertFile: cfg.Modules.CloudHub.TLSCertFile, + TLSTunnelPrivateKeyFile: cfg.Modules.CloudHub.TLSPrivateKeyFile, + TLSStreamCAFile: filepath.Join(rootDir, "/ca/streamCA.crt"), + TLSStreamCertFile: filepath.Join(rootDir, "/certs/stream.crt"), + TLSStreamPrivateKeyFile: filepath.Join(rootDir, "/certs/stream.key"), + } + return cfg +} + +// CloudCore indicates the config of cloudCore which get from cloudCore config file +type CloudCore struct { + metaV1.TypeMeta + // CommonConfig indicates common config for all modules + // +Required + CommonConfig *CommonConfig `json:"commonConfig,omitempty"` + // KubeAPIConfig indicates the kubernetes cluster info which cloudCore will connected + // +Required + KubeAPIConfig *KubeAPIConfig `json:"kubeAPIConfig,omitempty"` + // Modules indicates cloudCore modules config + // +Required + Modules *CloudModules `json:"modules,omitempty"` + // FeatureGates is a map of feature names to bools that enable or disable alpha/experimental features. + FeatureGates map[string]bool `json:"featureGates,omitempty"` +} + +type CommonConfig struct { + // TunnelPort indicates the port that the cloudcore tunnel listened + TunnelPort int `json:"tunnelPort,omitempty"` +} + +// KubeAPIConfig indicates the configuration for interacting with k8s server +type KubeAPIConfig struct { + // Master indicates the address of the Kubernetes API server (overrides any value in KubeConfig) + // such as https://127.0.0.1:8443 + // default "" + // Note: Can not use "omitempty" option, It will affect the output of the default configuration file + Master string `json:"master"` + // ContentType indicates the ContentType of message transmission when interacting with k8s + // default "application/vnd.kubernetes.protobuf" + ContentType string `json:"contentType,omitempty"` + // QPS to while talking with kubernetes apiserver + // default 100 + QPS int32 `json:"qps,omitempty"` + // Burst to use while talking with kubernetes apiserver + // default 200 + Burst int32 `json:"burst,omitempty"` + // KubeConfig indicates the path to kubeConfig file with authorization and master location information. + // default "/root/.kube/config" + // +Required + KubeConfig string `json:"kubeConfig"` +} + +// CloudModules indicates the modules of CloudCore will be use +type CloudModules struct { + // CloudHub indicates CloudHub module config + CloudHub *CloudHub `json:"cloudHub,omitempty"` + // EdgeController indicates EdgeController module config + EdgeController *EdgeController `json:"edgeController,omitempty"` + // DeviceController indicates DeviceController module config + DeviceController *DeviceController `json:"deviceController,omitempty"` + // SyncController indicates SyncController module config + SyncController *SyncController `json:"syncController,omitempty"` + // DynamicController indicates DynamicController module config + DynamicController *DynamicController `json:"dynamicController,omitempty"` + // CloudStream indicates cloudstream module config + CloudStream *CloudStream `json:"cloudStream,omitempty"` + // Router indicates router module config + Router *Router `json:"router,omitempty"` + // IptablesManager indicates iptables module config + IptablesManager *IptablesManager `json:"iptablesManager,omitempty"` +} + +// CloudHub indicates the config of CloudHub module. +// CloudHub is a web socket or quic server responsible for watching changes at the cloud side, +// caching and sending messages to EdgeHub. +type CloudHub struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // KeepaliveInterval indicates keep-alive interval (second) + // default 30 + KeepaliveInterval int32 `json:"keepaliveInterval,omitempty"` + // NodeLimit indicates node limit + // default 1000 + NodeLimit int32 `json:"nodeLimit,omitempty"` + // TLSCAFile indicates ca file path + // default "/etc/kubeedge/ca/rootCA.crt" + TLSCAFile string `json:"tlsCAFile,omitempty"` + // TLSCAKeyFile indicates caKey file path + // default "/etc/kubeedge/ca/rootCA.key" + TLSCAKeyFile string `json:"tlsCAKeyFile,omitempty"` + // TLSPrivateKeyFile indicates key file path + // default "/etc/kubeedge/certs/server.crt" + TLSCertFile string `json:"tlsCertFile,omitempty"` + // TLSPrivateKeyFile indicates key file path + // default "/etc/kubeedge/certs/server.key" + TLSPrivateKeyFile string `json:"tlsPrivateKeyFile,omitempty"` + // WriteTimeout indicates write time (second) + // default 30 + WriteTimeout int32 `json:"writeTimeout,omitempty"` + // Quic indicates quic server info + Quic *CloudHubQUIC `json:"quic,omitempty"` + // UnixSocket set unixsocket server info + UnixSocket *CloudHubUnixSocket `json:"unixsocket,omitempty"` + // WebSocket indicates websocket server info + // +Required + WebSocket *CloudHubWebSocket `json:"websocket,omitempty"` + // HTTPS indicates https server info + // +Required + HTTPS *CloudHubHTTPS `json:"https,omitempty"` + // AdvertiseAddress sets the IP address for the cloudcore to advertise. + AdvertiseAddress []string `json:"advertiseAddress,omitempty"` + // DNSNames sets the DNSNames for CloudCore. + DNSNames []string `json:"dnsNames,omitempty"` + // EdgeCertSigningDuration indicates the validity period of edge certificate + // default 365d + EdgeCertSigningDuration time.Duration `json:"edgeCertSigningDuration,omitempty"` + // TokenRefreshDuration indicates the interval of cloudcore token refresh, unit is hour + // default 12h + TokenRefreshDuration time.Duration `json:"tokenRefreshDuration,omitempty"` +} + +// CloudHubQUIC indicates the quic server config +type CloudHubQUIC struct { + // Enable indicates whether enable quic protocol + // default false + Enable bool `json:"enable"` + // Address set server ip address + // default 0.0.0.0 + Address string `json:"address,omitempty"` + // Port set open port for quic server + // default 10001 + Port uint32 `json:"port,omitempty"` + // MaxIncomingStreams set the max incoming stream for quic server + // default 10000 + MaxIncomingStreams int32 `json:"maxIncomingStreams,omitempty"` +} + +// CloudHubUnixSocket indicates the unix socket config +type CloudHubUnixSocket struct { + // Enable indicates whether enable unix domain socket protocol + // default true + Enable bool `json:"enable"` + // Address indicates unix domain socket address + // default "unix:///var/lib/kubeedge/kubeedge.sock" + Address string `json:"address,omitempty"` +} + +// CloudHubWebSocket indicates the websocket config of CloudHub +type CloudHubWebSocket struct { + // Enable indicates whether enable websocket protocol + // default true + Enable bool `json:"enable"` + // Address indicates server ip address + // default 0.0.0.0 + Address string `json:"address,omitempty"` + // Port indicates the open port for websocket server + // default 10000 + Port uint32 `json:"port,omitempty"` +} + +// CloudHubHTTPS indicates the http config of CloudHub +type CloudHubHTTPS struct { + // Enable indicates whether enable Https protocol + // default true + Enable bool `json:"enable"` + // Address indicates server ip address + // default 0.0.0.0 + Address string `json:"address,omitempty"` + // Port indicates the open port for HTTPS server + // default 10002 + Port uint32 `json:"port,omitempty"` +} + +// EdgeController indicates the config of EdgeController module +type EdgeController struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // NodeUpdateFrequency indicates node update frequency (second) + // default 10 + NodeUpdateFrequency int32 `json:"nodeUpdateFrequency,omitempty"` + // Buffer indicates k8s resource buffer + Buffer *EdgeControllerBuffer `json:"buffer,omitempty"` + // Load indicates EdgeController load + Load *EdgeControllerLoad `json:"load,omitempty"` +} + +// EdgeControllerBuffer indicates the EdgeController buffer +type EdgeControllerBuffer struct { + // UpdatePodStatus indicates the buffer of pod status + // default 1024 + UpdatePodStatus int32 `json:"updatePodStatus,omitempty"` + // UpdateNodeStatus indicates the buffer of update node status + // default 1024 + UpdateNodeStatus int32 `json:"updateNodeStatus,omitempty"` + // QueryConfigMap indicates the buffer of query configMap + // default 1024 + QueryConfigMap int32 `json:"queryConfigMap,omitempty"` + // QuerySecret indicates the buffer of query secret + // default 1024 + QuerySecret int32 `json:"querySecret,omitempty"` + // QueryService indicates the buffer of query service + // default 1024 + QueryService int32 `json:"queryService,omitempty"` + // QueryEndpoints indicates the buffer of query endpoint + // default 1024 + QueryEndpoints int32 `json:"queryEndpoints,omitempty"` + // PodEvent indicates the buffer of pod event + // default 1 + PodEvent int32 `json:"podEvent,omitempty"` + // ConfigMapEvent indicates the buffer of configMap event + // default 1 + ConfigMapEvent int32 `json:"configMapEvent,omitempty"` + // SecretEvent indicates the buffer of secret event + // default 1 + SecretEvent int32 `json:"secretEvent,omitempty"` + // ServiceEvent indicates the buffer of service event + // default 1 + ServiceEvent int32 `json:"serviceEvent,omitempty"` + // EndpointsEvent indicates the buffer of endpoint event + // default 1 + EndpointsEvent int32 `json:"endpointsEvent,omitempty"` + // RulesEvent indicates the buffer of rule event + // default 1 + RulesEvent int32 `json:"rulesEvent,omitempty"` + // RuleEndpointsEvent indicates the buffer of endpoint event + // default 1 + RuleEndpointsEvent int32 `json:"ruleEndpointsEvent,omitempty"` + // QueryPersistentVolume indicates the buffer of query persistent volume + // default 1024 + QueryPersistentVolume int32 `json:"queryPersistentVolume,omitempty"` + // QueryPersistentVolumeClaim indicates the buffer of query persistent volume claim + // default 1024 + QueryPersistentVolumeClaim int32 `json:"queryPersistentVolumeClaim,omitempty"` + // QueryVolumeAttachment indicates the buffer of query volume attachment + // default 1024 + QueryVolumeAttachment int32 `json:"queryVolumeAttachment,omitempty"` + // QueryNode indicates the buffer of query node + // default 1024 + QueryNode int32 `json:"queryNode,omitempty"` + // UpdateNode indicates the buffer of update node + // default 1024 + UpdateNode int32 `json:"updateNode,omitempty"` + // DeletePod indicates the buffer of delete pod message from edge + // default 1024 + DeletePod int32 `json:"deletePod,omitempty"` + // ServiceAccount indicates the buffer of service account token + // default 1024 + ServiceAccountToken int32 `json:"serviceAccountToken,omitempty"` +} + +// EdgeControllerLoad indicates the EdgeController load +type EdgeControllerLoad struct { + // UpdatePodStatusWorkers indicates the load of update pod status workers + // default 1 + UpdatePodStatusWorkers int32 `json:"updatePodStatusWorkers,omitempty"` + // UpdateNodeStatusWorkers indicates the load of update node status workers + // default 1 + UpdateNodeStatusWorkers int32 `json:"updateNodeStatusWorkers,omitempty"` + // QueryConfigMapWorkers indicates the load of query config map workers + // default 4 + QueryConfigMapWorkers int32 `json:"queryConfigMapWorkers,omitempty"` + // QuerySecretWorkers indicates the load of query secret workers + // default 4 + QuerySecretWorkers int32 `json:"querySecretWorkers,omitempty"` + // QueryServiceWorkers indicates the load of query service workers + // default 4 + QueryServiceWorkers int32 `json:"queryServiceWorkers,omitempty"` + // QueryEndpointsWorkers indicates the load of query endpoint workers + // default 4 + QueryEndpointsWorkers int32 `json:"queryEndpointsWorkers,omitempty"` + // QueryPersistentVolumeWorkers indicates the load of query persistent volume workers + // default 4 + QueryPersistentVolumeWorkers int32 `json:"queryPersistentVolumeWorkers,omitempty"` + // QueryPersistentVolumeClaimWorkers indicates the load of query persistent volume claim workers + // default 4 + QueryPersistentVolumeClaimWorkers int32 `json:"queryPersistentVolumeClaimWorkers,omitempty"` + // QueryVolumeAttachmentWorkers indicates the load of query volume attachment workers + // default 4 + QueryVolumeAttachmentWorkers int32 `json:"queryVolumeAttachmentWorkers,omitempty"` + // QueryNodeWorkers indicates the load of query node workers + // default 4 + QueryNodeWorkers int32 `json:"queryNodeWorkers,omitempty"` + // UpdateNodeWorkers indicates the load of update node workers + // default 4 + UpdateNodeWorkers int32 `json:"updateNodeWorkers,omitempty"` + // DeletePodWorkers indicates the load of delete pod workers + // default 4 + DeletePodWorkers int32 `json:"deletePodWorkers,omitempty"` + // UpdateRuleStatusWorkers indicates the load of update rule status + // default 4 + UpdateRuleStatusWorkers int32 `json:"UpdateRuleStatusWorkers,omitempty"` + // ServiceAccountTokenWorkers indicates the load of service account token + // default 4 + ServiceAccountTokenWorkers int32 `json:"ServiceAccountTokenWorkers,omitempty"` +} + +// DeviceController indicates the device controller +type DeviceController struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // Buffer indicates Device controller buffer + Buffer *DeviceControllerBuffer `json:"buffer,omitempty"` + // Load indicates DeviceController Load + Load *DeviceControllerLoad `json:"load,omitempty"` +} + +// DeviceControllerBuffer indicates deviceController buffer +type DeviceControllerBuffer struct { + // UpdateDeviceStatus indicates the buffer of update device status + // default 1024 + UpdateDeviceStatus int32 `json:"updateDeviceStatus,omitempty"` + // DeviceEvent indicates the buffer of device event + // default 1 + DeviceEvent int32 `json:"deviceEvent,omitempty"` + // DeviceModelEvent indicates the buffer of device model event + // default 1 + DeviceModelEvent int32 `json:"deviceModelEvent,omitempty"` +} + +// DeviceControllerLoad indicates the deviceController load +type DeviceControllerLoad struct { + // UpdateDeviceStatusWorkers indicates the load of update device status workers + // default 1 + UpdateDeviceStatusWorkers int32 `json:"updateDeviceStatusWorkers,omitempty"` +} + +// SyncController indicates the sync controller +type SyncController struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` +} + +// DynamicController indicates the dynamic controller +type DynamicController struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` +} + +// CloudStream indicates the stream controller +type CloudStream struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // TLSTunnelCAFile indicates ca file path + // default /etc/kubeedge/ca/rootCA.crt + TLSTunnelCAFile string `json:"tlsTunnelCAFile,omitempty"` + // TLSTunnelCertFile indicates cert file path + // default /etc/kubeedge/certs/server.crt + TLSTunnelCertFile string `json:"tlsTunnelCertFile,omitempty"` + // TLSTunnelPrivateKeyFile indicates key file path + // default /etc/kubeedge/certs/server.key + TLSTunnelPrivateKeyFile string `json:"tlsTunnelPrivateKeyFile,omitempty"` + // TunnelPort set open port for tunnel server + // default 10004 + TunnelPort uint32 `json:"tunnelPort,omitempty"` + + // TLSStreamCAFile indicates kube-apiserver ca file path + // default /etc/kubeedge/ca/streamCA.crt + TLSStreamCAFile string `json:"tlsStreamCAFile,omitempty"` + // TLSStreamCertFile indicates cert file path + // default /etc/kubeedge/certs/stream.crt + TLSStreamCertFile string `json:"tlsStreamCertFile,omitempty"` + // TLSStreamPrivateKeyFile indicates key file path + // default /etc/kubeedge/certs/stream.key + TLSStreamPrivateKeyFile string `json:"tlsStreamPrivateKeyFile,omitempty"` + // StreamPort set open port for stream server + // default 10003 + StreamPort uint32 `json:"streamPort,omitempty"` +} + +type Router struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + Address string `json:"address,omitempty"` + Port uint32 `json:"port,omitempty"` + RestTimeout uint32 `json:"restTimeout,omitempty"` +} + +// IptablesManager indicates the config of Iptables +type IptablesManager struct { + // Enable indicates whether enable IptablesManager + // default true + Enable bool `json:"enable"` + // It indicates how the component is deployed, valid mode can use "internal" or "external". + // The iptables manager component with the internal mode is always deployed inside the cloudcore, will share the host network, forward to the internal port of the tunnel port. + // The iptables manager component with the external mode is always deployed outside the cloudcore, will share the host network, forward to the internal cloudcore service and port. + // default internal. + // +kubebuilder:validation:Enum=internal;external + Mode IptablesMgrMode `json:"mode,omitempty"` +} + +type IptablesMgrMode string + +const ( + InternalMode IptablesMgrMode = "internal" + ExternalMode IptablesMgrMode = "external" +) + +func (c *CloudCore) Parse(filename string) error { + data, err := os.ReadFile(filename) + if err != nil { + klog.Errorf("Failed to read configfile %s: %v", filename, err) + return err + } + err = yaml.Unmarshal(data, c) + if err != nil { + klog.Errorf("Failed to unmarshal configfile %s: %v", filename, err) + return err + } + return nil +} + +func (in *IptablesManager) UnmarshalJSON(data []byte) error { + if len(data) == 0 { + return nil + } + + // Define a secondary type so that we don't end up with a recursive call to json.Unmarshal + type IM IptablesManager + var out = (*IM)(in) + err := json.Unmarshal(data, &out) + if err != nil { + return err + } + + // Validate the valid enum values + switch in.Mode { + case InternalMode, ExternalMode: + return nil + default: + in.Mode = "" + return errors.New("invalid value for iptablesmgr mode") + } +} diff --git a/pkg/edgeconfig/edge.go b/pkg/edgeconfig/edge.go new file mode 100644 index 0000000..2b739c1 --- /dev/null +++ b/pkg/edgeconfig/edge.go @@ -0,0 +1,617 @@ +// Package edgeconfig +// Created by zc on 2021/12/1. +package edgeconfig + +import ( + "net" + "net/url" + "os" + "path" + "path/filepath" + "time" + + "github.com/99nil/diplomat/global/constants" + "github.com/99nil/diplomat/pkg/util" + + coreV1 "k8s.io/api/core/v1" + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NewDefaultEdgeCoreConfig returns a full EdgeCoreConfig object +func NewDefaultEdgeCoreConfig(rootDir, resourceDir string) *EdgeCore { + hostnameOverride, err := os.Hostname() + if err != nil { + hostnameOverride = "default-edge-node" + } + + msgs := apimachineryvalidation.NameIsDNSSubdomain(hostnameOverride, false) + if len(msgs) > 0 { + hostnameOverride = "default-edge-node" + } + + localIP, _ := util.GetLocalIP(hostnameOverride) + cfg := &EdgeCore{ + TypeMeta: metaV1.TypeMeta{ + Kind: Kind, + APIVersion: path.Join(GroupName, APIVersion), + }, + DataBase: &DataBase{ + DriverName: constants.DataBaseDriverName, + AliasName: constants.DataBaseAliasName, + DataSource: filepath.Join(resourceDir, constants.DataBaseDataSource), + }, + Modules: &EdgeModules{ + Edged: &Edged{ + Enable: true, + Labels: map[string]string{}, + Annotations: map[string]string{}, + NodeStatusUpdateFrequency: 10, + RuntimeType: "docker", + DockerAddress: "unix:///var/run/docker.sock", + RemoteRuntimeEndpoint: "unix:///var/run/dockershim.sock", + RemoteImageEndpoint: "unix:///var/run/dockershim.sock", + NodeIP: localIP, + ClusterDNS: "", + ClusterDomain: "", + ConcurrentConsumers: 5, + EdgedMemoryCapacity: 7852396000, + PodSandboxImage: "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2", + ImagePullProgressDeadline: 60, + RuntimeRequestTimeout: 2, + HostnameOverride: hostnameOverride, + RegisterNodeNamespace: "default", + CustomInterfaceName: "", + RegisterNode: true, + DevicePluginEnabled: true, + GPUPluginEnabled: true, + ImageGCHighThreshold: 80, + ImageGCLowThreshold: 40, + MaximumDeadContainersPerPod: 1, + CGroupDriver: constants.CGroupDriverCGroupFS, + CgroupsPerQOS: true, + CgroupRoot: "", + CNIConfDir: "/etc/cni/net.d", + CNIBinDir: "/opt/cni/bin", + CNICacheDir: "/var/lib/cni/cache", + NetworkPluginMTU: 1500, + VolumeStatsAggPeriod: time.Second * 60, + EnableMetrics: true, + NetworkPluginName: "cni", + }, + EdgeHub: &EdgeHub{ + Enable: true, + Heartbeat: 15, + MessageQPS: 30, + MessageBurst: 60, + ProjectID: "e632aba927ea4ac2b575ec1603d56f10", + TLSCAFile: filepath.Join(rootDir, "/ca/rootCA.crt"), + TLSCertFile: filepath.Join(rootDir, "/certs/server.crt"), + TLSPrivateKeyFile: filepath.Join(rootDir, "/certs/server.key"), + RotateCertificates: true, + Quic: &EdgeHubQUIC{ + Enable: false, + HandshakeTimeout: 30, + ReadDeadline: 15, + Server: net.JoinHostPort(localIP, "10001"), + WriteDeadline: 15, + }, + WebSocket: &EdgeHubWebSocket{ + Enable: true, + HandshakeTimeout: 30, + ReadDeadline: 15, + Server: net.JoinHostPort(localIP, "10000"), + WriteDeadline: 15, + }, + HTTPServer: (&url.URL{ + Scheme: "https", + Host: net.JoinHostPort(localIP, "10002"), + }).String(), + Token: "", + }, + EventBus: &EventBus{ + Enable: true, + MqttQOS: 0, + MqttRetain: false, + MqttSessionQueueSize: 100, + MqttServerExternal: "tcp://127.0.0.1:1883", + MqttServerInternal: "tcp://127.0.0.1:1884", + MqttSubClientID: "", + MqttPubClientID: "", + MqttUsername: "", + MqttPassword: "", + MqttMode: constants.MqttModeExternal, + TLS: &EventBusTLS{ + Enable: false, + TLSMqttCAFile: filepath.Join(rootDir, "/ca/rootCA.crt"), + TLSMqttCertFile: filepath.Join(rootDir, "/certs/server.crt"), + TLSMqttPrivateKeyFile: filepath.Join(rootDir, "/certs/server.key"), + }, + }, + MetaManager: &MetaManager{ + Enable: true, + ContextSendGroup: "hub", + ContextSendModule: "websocket", + RemoteQueryTimeout: 60, + Debug: false, + MetaServer: &MetaServer{ + Enable: true, + Debug: false, + Server: "127.0.0.1:10550", + Scheme: "https", + TLSCAFile: filepath.Join(rootDir, "/ca/rootCA.crt"), + TLSCertFile: filepath.Join(rootDir, "/certs/server.crt"), + TLSPrivateKeyFile: filepath.Join(rootDir, "/certs/server.key"), + }, + }, + ServiceBus: &ServiceBus{ + Enable: false, + Server: "127.0.0.1", + Port: 9060, + Timeout: 60, + }, + DeviceTwin: &DeviceTwin{ + Enable: true, + }, + DBTest: &DBTest{ + Enable: false, + }, + EdgeStream: &EdgeStream{ + Enable: true, + TLSTunnelCAFile: filepath.Join(rootDir, "/ca/rootCA.crt"), + TLSTunnelCertFile: filepath.Join(rootDir, "/certs/server.crt"), + TLSTunnelPrivateKeyFile: filepath.Join(rootDir, "/certs/server.key"), + HandshakeTimeout: 30, + ReadDeadline: 15, + TunnelServer: net.JoinHostPort("127.0.0.1", "10004"), + WriteDeadline: 15, + }, + }, + } + return cfg +} + +// EdgeCore indicates the EdgeCore config which read from EdgeCore config file +type EdgeCore struct { + metaV1.TypeMeta + // DataBase indicates database info + // +Required + DataBase *DataBase `json:"database,omitempty"` + // Modules indicates EdgeCore modules config + // +Required + Modules *EdgeModules `json:"modules,omitempty"` + // FeatureGates is a map of feature names to bools that enable or disable alpha/experimental features. + FeatureGates map[string]bool `json:"featureGates,omitempty"` +} + +// DataBase indicates the database info +type DataBase struct { + // DriverName indicates database driver name + // default "sqlite3" + DriverName string `json:"driverName,omitempty"` + // AliasName indicates alias name + // default "default" + AliasName string `json:"aliasName,omitempty"` + // DataSource indicates the data source path + // default "/var/lib/kubeedge/edgecore.db" + DataSource string `json:"dataSource,omitempty"` +} + +// EdgeModules indicates the modules which edgeCore will be used +type EdgeModules struct { + // Edged indicates edged module config + // +Required + Edged *Edged `json:"edged,omitempty"` + // EdgeHub indicates edgeHub module config + // +Required + EdgeHub *EdgeHub `json:"edgeHub,omitempty"` + // EventBus indicates eventBus config for edgeCore + // +Required + EventBus *EventBus `json:"eventBus,omitempty"` + // MetaManager indicates meta module config + // +Required + MetaManager *MetaManager `json:"metaManager,omitempty"` + // ServiceBus indicates serviceBus module config + ServiceBus *ServiceBus `json:"serviceBus,omitempty"` + // DeviceTwin indicates deviceTwin module config + DeviceTwin *DeviceTwin `json:"deviceTwin,omitempty"` + // DBTest indicates dbTest module config + DBTest *DBTest `json:"dbTest,omitempty"` + // EdgeStream indicates edgestream module config + // +Required + EdgeStream *EdgeStream `json:"edgeStream,omitempty"` +} + +// Edged indicates the config fo edged module +// edged is lighted-kubelet +type Edged struct { + // Enable indicates whether the module is enabled + // if set to false (for debugging etc.), skip checking other edged configs. + // default true + Enable bool `json:"enable"` + // Labels indicates current node labels + Labels map[string]string `json:"labels,omitempty"` + // Annotations indicates current node annotations + Annotations map[string]string `json:"annotations,omitempty"` + // Taints indicates current node taints + Taints []coreV1.Taint `json:"taints,omitempty"` + // NodeStatusUpdateFrequency indicates node status update frequency (second) + // default 10 + NodeStatusUpdateFrequency int32 `json:"nodeStatusUpdateFrequency,omitempty"` + // RuntimeType indicates cri runtime ,support: docker, remote + // default "docker" + RuntimeType string `json:"runtimeType,omitempty"` + // DockerAddress indicates docker server address + // default "unix:///var/run/docker.sock" + DockerAddress string `json:"dockerAddress,omitempty"` + // RemoteRuntimeEndpoint indicates remote runtime endpoint + // default "unix:///var/run/dockershim.sock" + RemoteRuntimeEndpoint string `json:"remoteRuntimeEndpoint,omitempty"` + // RemoteImageEndpoint indicates remote image endpoint + // default "unix:///var/run/dockershim.sock" + RemoteImageEndpoint string `json:"remoteImageEndpoint,omitempty"` + // NodeIP indicates current node ip. + // Setting the value overwrites the automatically detected IP address + // default get local host ip + NodeIP string `json:"nodeIP"` + // ClusterDNS indicates cluster dns + // Note: Can not use "omitempty" option, It will affect the output of the default configuration file + // +Required + ClusterDNS string `json:"clusterDNS"` + // ClusterDomain indicates cluster domain + // Note: Can not use "omitempty" option, It will affect the output of the default configuration file + ClusterDomain string `json:"clusterDomain"` + // EdgedMemoryCapacity indicates memory capacity (byte) + // default 7852396000 + EdgedMemoryCapacity int64 `json:"edgedMemoryCapacity,omitempty"` + // PodSandboxImage is the image whose network/ipc namespaces containers in each pod will use. + // +Required + // default kubeedge/pause:3.1 + PodSandboxImage string `json:"podSandboxImage,omitempty"` + // ImagePullProgressDeadline indicates image pull progress dead line (second) + // default 60 + ImagePullProgressDeadline int32 `json:"imagePullProgressDeadline,omitempty"` + // RuntimeRequestTimeout indicates runtime request timeout (second) + // default 2 + RuntimeRequestTimeout int32 `json:"runtimeRequestTimeout,omitempty"` + // HostnameOverride indicates hostname + // default os.Hostname() + HostnameOverride string `json:"hostnameOverride,omitempty"` + // RegisterNode enables automatic registration + // default true + RegisterNode bool `json:"registerNode,omitempty"` + //RegisterNodeNamespace indicates register node namespace + // default "default" + RegisterNodeNamespace string `json:"registerNodeNamespace,omitempty"` + // CustomInterfaceName indicates the name of the network interface used for obtaining the IP address. + // Setting this will override the setting 'NodeIP' if provided. + // If this is not defined the IP address is obtained by the hostname. + // default "" + CustomInterfaceName string `json:"customInterfaceName,omitempty"` + // ConcurrentConsumers indicates concurrent consumers for pod add or remove operation + // default 5 + ConcurrentConsumers int `json:"concurrentConsumers,omitempty"` + // DevicePluginEnabled indicates enable device plugin + // default false + // Note: Can not use "omitempty" option, it will affect the output of the default configuration file + DevicePluginEnabled bool `json:"devicePluginEnabled"` + // GPUPluginEnabled indicates enable gpu plugin + // default false, + // Note: Can not use "omitempty" option, it will affect the output of the default configuration file + GPUPluginEnabled bool `json:"gpuPluginEnabled"` + // ImageGCHighThreshold indicates image gc high threshold (percent) + // default 80 + ImageGCHighThreshold int32 `json:"imageGCHighThreshold,omitempty"` + // ImageGCLowThreshold indicates image gc low threshold (percent) + // default 40 + ImageGCLowThreshold int32 `json:"imageGCLowThreshold,omitempty"` + // MaximumDeadContainersPerPod indicates max num dead containers per pod + // default 1 + MaximumDeadContainersPerPod int32 `json:"maximumDeadContainersPerPod,omitempty"` + // CGroupDriver indicates container cgroup driver, support: cgroupfs, systemd + // default "cgroupfs" + // +Required + CGroupDriver string `json:"cgroupDriver,omitempty"` + // NetworkPluginName indicates the name of the network plugin to be invoked, + // if an empty string is specified, use noop plugin + // default "" + NetworkPluginName string `json:"networkPluginName,omitempty"` + // CNIConfDir indicates the full path of the directory in which to search for CNI config files + // default "/etc/cni/net.d" + CNIConfDir string `json:"cniConfDir,omitempty"` + // CNIBinDir indicates a comma-separated list of full paths of directories + // in which to search for CNI plugin binaries + // default "/opt/cni/bin" + CNIBinDir string `json:"cniBinDir,omitempty"` + // CNICacheDir indicates the full path of the directory in which CNI should store cache files + // default "/var/lib/cni/cache" + CNICacheDir string `json:"cniCacheDirs,omitempty"` + // NetworkPluginMTU indicates the MTU to be passed to the network plugin + // default 1500 + NetworkPluginMTU int32 `json:"networkPluginMTU,omitempty"` + // CgroupsPerQOS enables QoS based Cgroup hierarchy: top level cgroups for QoS Classes + // And all Burstable and BestEffort pods are brought up under their + // specific top level QoS cgroup. + // Default: true + CgroupsPerQOS bool `json:"cgroupsPerQOS"` + // CgroupRoot is the root cgroup to use for pods. + // If CgroupsPerQOS is enabled, this is the root of the QoS cgroup hierarchy. + // Default: "" + CgroupRoot string `json:"cgroupRoot"` + // EdgeCoreCgroups is the absolute name of cgroups to isolate the edgecore in + // Dynamic Kubelet Config (beta): This field should not be updated without a full node + // reboot. It is safest to keep this value the same as the local config. + // Default: "" + EdgeCoreCgroups string `json:"edgeCoreCgroups,omitempty"` + // systemCgroups is absolute name of cgroups in which to place + // all non-kernel processes that are not already in a container. Empty + // for no container. Rolling back the flag requires a reboot. + // Dynamic Kubelet Config (beta): This field should not be updated without a full node + // reboot. It is safest to keep this value the same as the local config. + // Default: "" + SystemCgroups string `json:"systemCgroups,omitempty"` + // How frequently to calculate and cache volume disk usage for all pods + // Dynamic Kubelet Config (beta): If dynamically updating this field, consider that + // shortening the period may carry a performance impact. + // Default: "1m" + VolumeStatsAggPeriod time.Duration `json:"volumeStatsAggPeriod,omitempty"` + // EnableMetrics indicates whether enable the metrics + // default true + EnableMetrics bool `json:"enableMetrics,omitempty"` + // Debug enable debug mode, it is helpful to debug Cloud Hub and Edge Hub + Debug bool `json:"debug,omitempty"` + // DebugEdgedAddr In normal mode, Edge Core cannot run on local. + // Therefore, the Edge invocation address is exposed for making a remote invocation of the edged service + DebugEdgedAddr string `json:"debugEdgedAddr,omitempty"` + // PodStatusSyncInterval indicates pod status sync + // default 60 + PodStatusSyncInterval int32 `json:"podStatusSyncInterval,omitempty"` +} + +// EdgeHub indicates the EdgeHub module config +type EdgeHub struct { + // Enable indicates whether the module is enabled + // if set to false (for debugging etc.), skip checking other EdgeHub configs. + // default true + Enable bool `json:"enable"` + // Heartbeat indicates heart beat (second) + // default 15 + Heartbeat int32 `json:"heartbeat,omitempty"` + // MessageQPS is the QPS to allow while send message to cloudHub. + // DefaultQPS: 30 + MessageQPS int32 `json:"messageQPS,omitempty"` + // MessageBurst is the burst to allow while send message to cloudHub. + // DefaultBurst: 60 + MessageBurst int32 `json:"messageBurst,omitempty"` + // ProjectID indicates project id + // default e632aba927ea4ac2b575ec1603d56f10 + ProjectID string `json:"projectID,omitempty"` + // TLSCAFile set ca file path + // default "/etc/kubeedge/ca/rootCA.crt" + TLSCAFile string `json:"tlsCaFile,omitempty"` + // TLSCertFile indicates the file containing x509 Certificate for HTTPS + // default "/etc/kubeedge/certs/server.crt" + TLSCertFile string `json:"tlsCertFile,omitempty"` + // TLSPrivateKeyFile indicates the file containing x509 private key matching tlsCertFile + // default "/etc/kubeedge/certs/server.key" + TLSPrivateKeyFile string `json:"tlsPrivateKeyFile,omitempty"` + // Quic indicates quic config for EdgeHub module + // Optional if websocket is configured + Quic *EdgeHubQUIC `json:"quic,omitempty"` + // WebSocket indicates websocket config for EdgeHub module + // Optional if quic is configured + WebSocket *EdgeHubWebSocket `json:"websocket,omitempty"` + // Token indicates the priority of joining the cluster for the edge + Token string `json:"token"` + // HTTPServer indicates the server for edge to apply for the certificate. + HTTPServer string `json:"httpServer,omitempty"` + // RotateCertificates indicates whether edge certificate can be rotated + // default true + RotateCertificates bool `json:"rotateCertificates,omitempty"` + // Debug enable debug mode, it is helpful to debug Cloud Hub and Edge Hub + Debug bool `json:"debug,omitempty"` + // DebugTargetEdgedServer the DebugEdgedAddr that is set in edged + DebugTargetEdgedServer string `json:"debugTargetEdgedServer,omitempty"` + // DebugEdgeHubAddr Edge Hub expose addr for metaClient to use + DebugEdgeHubAddr string `json:"debugEdgeHubAddr,omitempty"` +} + +// EdgeHubQUIC indicates the quic client config +type EdgeHubQUIC struct { + // Enable indicates whether enable this protocol + // default false + Enable bool `json:"enable"` + // HandshakeTimeout indicates hand shake timeout (second) + // default 30 + HandshakeTimeout int32 `json:"handshakeTimeout,omitempty"` + // ReadDeadline indicates read dead line (second) + // default 15 + ReadDeadline int32 `json:"readDeadline,omitempty"` + // Server indicates quic server address (ip:port) + // +Required + Server string `json:"server,omitempty"` + // WriteDeadline indicates write deadline (second) + // default 15 + WriteDeadline int32 `json:"writeDeadline,omitempty"` +} + +// EdgeHubWebSocket indicates the websocket client config +type EdgeHubWebSocket struct { + // Enable indicates whether enable this protocol + // default true + Enable bool `json:"enable"` + // HandshakeTimeout indicates handshake timeout (second) + // default 30 + HandshakeTimeout int32 `json:"handshakeTimeout,omitempty"` + // ReadDeadline indicates read dead line (second) + // default 15 + ReadDeadline int32 `json:"readDeadline,omitempty"` + // Server indicates websocket server address (ip:port) + // +Required + Server string `json:"server,omitempty"` + // WriteDeadline indicates write dead line (second) + // default 15 + WriteDeadline int32 `json:"writeDeadline,omitempty"` +} + +// EventBus indicates the event bus module config +type EventBus struct { + // Enable indicates whether the module is enabled + // skip checking other EventBus configs. + // default true + Enable bool `json:"enable"` + // MqttQOS indicates mqtt qos + // 0: QOSAtMostOnce, 1: QOSAtLeastOnce, 2: QOSExactlyOnce + // default 0 + // Note: Can not use "omitempty" option, It will affect the output of the default configuration file + MqttQOS uint8 `json:"mqttQOS"` + // MqttRetain indicates whether server will store the message and can be delivered to future subscribers, + // if this flag set true, sever will store the message and can be delivered to future subscribers + // default false + // Note: Can not use "omitempty" option, It will affect the output of the default configuration file + MqttRetain bool `json:"mqttRetain"` + // MqttSessionQueueSize indicates the size of how many sessions will be handled. + // default 100 + MqttSessionQueueSize int32 `json:"mqttSessionQueueSize,omitempty"` + // MqttServerInternal indicates internal mqtt broker url + // default "tcp://127.0.0.1:1884" + MqttServerInternal string `json:"mqttServerInternal,omitempty"` + // MqttServerExternal indicates external mqtt broker url + // default "tcp://127.0.0.1:1883" + MqttServerExternal string `json:"mqttServerExternal,omitempty"` + // MqttSubClientID indicates mqtt subscribe ClientID + // default "" + MqttSubClientID string `json:"mqttSubClientID"` + // MqttPubClientID indicates mqtt publish ClientID + // default "" + MqttPubClientID string `json:"mqttPubClientID"` + // MqttUsername indicates mqtt username + // default "" + MqttUsername string `json:"mqttUsername"` + // MqttPassword indicates mqtt password + // default "" + MqttPassword string `json:"mqttPassword"` + // MqttMode indicates which broker type will be choose + // 0: internal mqtt broker enable only. + // 1: internal and external mqtt broker enable. + // 2: external mqtt broker enable only + // +Required + // default: 2 + MqttMode constants.MqttMode `json:"mqttMode"` + // Tls indicates tls config for EventBus module + TLS *EventBusTLS `json:"eventBusTLS,omitempty"` +} + +// EventBusTLS indicates the EventBus tls config with MQTT broker +type EventBusTLS struct { + // Enable indicates whether enable tls connection + // default false + Enable bool `json:"enable"` + // TLSMqttCAFile sets ca file path + // default "/etc/kubeedge/ca/rootCA.crt" + TLSMqttCAFile string `json:"tlsMqttCAFile,omitempty"` + // TLSMqttCertFile indicates the file containing x509 Certificate for HTTPS + // default "/etc/kubeedge/certs/server.crt" + TLSMqttCertFile string `json:"tlsMqttCertFile,omitempty"` + // TLSMqttPrivateKeyFile indicates the file containing x509 private key matching tlsMqttCertFile + // default "/etc/kubeedge/certs/server.key" + TLSMqttPrivateKeyFile string `json:"tlsMqttPrivateKeyFile,omitempty"` +} + +// MetaManager indicates the MetaManager module config +type MetaManager struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // ContextSendGroup indicates send group + ContextSendGroup string `json:"contextSendGroup,omitempty"` + // ContextSendModule indicates send module + ContextSendModule string `json:"contextSendModule,omitempty"` + // RemoteQueryTimeout indicates remote query timeout (second) + // default 60 + RemoteQueryTimeout int32 `json:"remoteQueryTimeout,omitempty"` + // The config of MetaServer + MetaServer *MetaServer `json:"metaServer,omitempty"` + // Debug enable debug mode, it is helpful to debug Cloud Hub and Edge Hub + Debug bool `json:"debug,omitempty"` + // DebugTargetEdgeHubAddr the debugEdgeHubAddr set in Edge Hub + DebugTargetEdgeHubAddr string `json:"debugTargetEdgeHubAddr,omitempty"` +} + +type MetaServer struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + Debug bool `json:"debug,omitempty"` + Server string `json:"server,omitempty"` + Scheme string `json:"scheme,omitempty"` + // TLSCAFile set ca file path + // default "/etc/kubeedge/ca/rootCA.crt" + TLSCAFile string `json:"tlsCAFile,omitempty"` + // TLSCertFile indicates the file containing x509 Certificate for HTTPS + // default "/etc/kubeedge/certs/server.crt" + TLSCertFile string `json:"tlsCertFile,omitempty"` + // TLSPrivateKeyFile indicates the file containing x509 private key matching tlsCertFile + // default "/etc/kubeedge/certs/server.key" + TLSPrivateKeyFile string `json:"tlsPrivateKeyFile,omitempty"` +} + +// ServiceBus indicates the ServiceBus module config +type ServiceBus struct { + // Enable indicates whether ServiceBus is enabled, + // if set to false (for debugging etc.), skip checking other ServiceBus configs. + // default false + Enable bool `json:"enable"` + // Address indicates address for http server + Server string `json:"server"` + // Port indicates port for http server + Port int `json:"port"` + // Timeout indicates timeout for servicebus receive message + Timeout int `json:"timeout"` +} + +// DeviceTwin indicates the DeviceTwin module config +type DeviceTwin struct { + // Enable indicates whether the module is enabled + // if set to false (for debugging etc.), skip checking other DeviceTwin configs. + // default true + Enable bool `json:"enable"` +} + +// DBTest indicates the DBTest module config +type DBTest struct { + // Enable indicates whether DBTest is enabled, + // if set to false (for debugging etc.), skip checking other DBTest configs. + // default false + Enable bool `json:"enable"` +} + +// EdgeStream indicates the stream controller +type EdgeStream struct { + // Enable indicates whether the module is enabled + // default true + Enable bool `json:"enable"` + // TLSTunnelCAFile indicates ca file path + // default /etc/kubeedge/ca/rootCA.crt + TLSTunnelCAFile string `json:"tlsTunnelCAFile,omitempty"` + + // TLSTunnelCertFile indicates the file containing x509 Certificate for HTTPS + // default /etc/kubeedge/certs/server.crt + TLSTunnelCertFile string `json:"tlsTunnelCertFile,omitempty"` + // TLSTunnelPrivateKeyFile indicates the file containing x509 private key matching tlsCertFile + // default /etc/kubeedge/certs/server.key + TLSTunnelPrivateKeyFile string `json:"tlsTunnelPrivateKeyFile,omitempty"` + + // HandshakeTimeout indicates handshake timeout (second) + // default 30 + HandshakeTimeout int32 `json:"handshakeTimeout,omitempty"` + // ReadDeadline indicates read deadline (second) + // default 15 + ReadDeadline int32 `json:"readDeadline,omitempty"` + // TunnelServer indicates websocket server address (ip:port) + // +Required + TunnelServer string `json:"server,omitempty"` + // WriteDeadline indicates write deadline (second) + // default 15 + WriteDeadline int32 `json:"writeDeadline,omitempty"` +} diff --git a/pkg/edgeconfig/image.go b/pkg/edgeconfig/image.go new file mode 100644 index 0000000..3b4070e --- /dev/null +++ b/pkg/edgeconfig/image.go @@ -0,0 +1,108 @@ +// Copyright © 2022 99nil. +// +// 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 edgeconfig + +import ( + "context" + "fmt" + "path/filepath" + + dockertypes "github.com/docker/docker/api/types" + dockercontainer "github.com/docker/docker/api/types/container" + dockerclient "github.com/docker/docker/client" + "k8s.io/klog/v2" +) + +// CopyResources copies binary and configuration file from the image to the host. +// The same way as func (runtime *DockerRuntime) CopyResources +func CopyResources(ctx context.Context, image string, dirs map[string]string, files map[string]string) error { + cli, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv) + if err != nil { + return fmt.Errorf("init docker client failed: %v", err) + } + + cli.NegotiateAPIVersion(ctx) + + if len(files) == 0 && len(dirs) == 0 { + return fmt.Errorf("no resources need copying") + } + + copyCmd := copyResourcesCmd(dirs, files) + + config := &dockercontainer.Config{ + Image: image, + Cmd: []string{ + "/bin/sh", + "-c", + copyCmd, + }, + } + var binds []string + for origin, bind := range dirs { + binds = append(binds, origin+":"+bind) + } + for origin, bind := range files { + binds = append(binds, filepath.Dir(origin)+":"+filepath.Dir(bind)) + } + + hostConfig := &dockercontainer.HostConfig{ + Binds: binds, + } + + // Randomly generate container names to prevent duplicate names. + container, err := cli.ContainerCreate(ctx, config, hostConfig, nil, nil, "") + if err != nil { + return err + } + defer func() { + if err := cli.ContainerRemove(ctx, container.ID, dockertypes.ContainerRemoveOptions{}); err != nil { + klog.V(3).ErrorS(err, "Remove container failed", "containerID", container.ID) + } + }() + + if err := cli.ContainerStart(ctx, container.ID, dockertypes.ContainerStartOptions{}); err != nil { + return fmt.Errorf("container start failed: %v", err) + } + + statusCh, errCh := cli.ContainerWait(ctx, container.ID, "") + select { + case err := <-errCh: + klog.Errorf("container wait error %v", err) + case <-statusCh: + } + return nil +} + +func copyResourcesCmd(dirs map[string]string, files map[string]string) string { + var copyCmd string + first := true + for origin, bind := range dirs { + if first { + copyCmd = copyCmd + fmt.Sprintf("cp -r %s %s", origin, bind) + } else { + copyCmd = copyCmd + fmt.Sprintf(" && cp -r %s %s", origin, bind) + } + first = false + } + for origin, bind := range files { + if first { + copyCmd = copyCmd + fmt.Sprintf("cp %s %s", origin, bind) + } else { + copyCmd = copyCmd + fmt.Sprintf(" && cp %s %s", origin, bind) + } + first = false + } + return copyCmd +} diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go new file mode 100644 index 0000000..548ae07 --- /dev/null +++ b/pkg/exec/exec.go @@ -0,0 +1,91 @@ +// Copyright © 2022 99nil. +// +// 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 exec + +import ( + "bytes" + "errors" + "fmt" + "os/exec" + "strings" + "syscall" +) + +//Command defines commands to be executed and captures std out and std error +type Command struct { + Cmd *exec.Cmd + StdOut []byte + StdErr []byte + ExitCode int +} + +func NewCommand(command string) *Command { + return &Command{ + Cmd: exec.Command("sh", "-c", command), + } +} + +// Exec run command and exit formatted error, callers can print err directly +// Any running error or non-zero exitcode is consider as error +func (cmd *Command) Exec() error { + var stdoutBuf, stderrBuf bytes.Buffer + cmd.Cmd.Stdout = &stdoutBuf + cmd.Cmd.Stderr = &stderrBuf + + errString := fmt.Sprintf("failed to exec '%s'", cmd.GetCommand()) + + err := cmd.Cmd.Start() + if err != nil { + errString = fmt.Sprintf("%s, err: %v", errString, err) + return errors.New(errString) + } + + err = cmd.Cmd.Wait() + if err != nil { + cmd.StdErr = stderrBuf.Bytes() + + if exit, ok := err.(*exec.ExitError); ok { + cmd.ExitCode = exit.Sys().(syscall.WaitStatus).ExitStatus() + errString = fmt.Sprintf("%s, err: %s", errString, stderrBuf.Bytes()) + } else { + cmd.ExitCode = 1 + } + + errString = fmt.Sprintf("%s, err: %v", errString, err) + + return errors.New(errString) + } + + cmd.StdOut, cmd.StdErr = stdoutBuf.Bytes(), stderrBuf.Bytes() + return nil +} + +func (cmd Command) GetCommand() string { + return strings.Join(cmd.Cmd.Args, " ") +} + +func (cmd Command) GetStdOut() string { + if len(cmd.StdOut) != 0 { + return strings.TrimRight(string(cmd.StdOut), "\n") + } + return "" +} + +func (cmd Command) GetStdErr() string { + if len(cmd.StdErr) != 0 { + return strings.TrimRight(string(cmd.StdErr), "\n") + } + return "" +} diff --git a/pkg/exec/exec_test.go b/pkg/exec/exec_test.go new file mode 100644 index 0000000..14a95db --- /dev/null +++ b/pkg/exec/exec_test.go @@ -0,0 +1,70 @@ +// Copyright © 2022 99nil. +// +// 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 exec + +import ( + "testing" +) + +func TestExecutorNoArgs(t *testing.T) { + cmd := NewCommand("true") + err := cmd.Exec() + if err != nil { + t.Errorf("expected success, got %v", err) + } + if len(cmd.StdOut) != 0 || len(cmd.StdErr) != 0 { + t.Errorf("expected no output, got stdout: %q, stderr: %q", string(cmd.StdOut), string(cmd.StdErr)) + } + + cmd = NewCommand("false") + err = cmd.Exec() + if err == nil { + t.Errorf("expected failure, got nil error") + } + if len(cmd.StdOut) != 0 || len(cmd.StdErr) != 0 { + t.Errorf("expected no output, got stdout: %q, stderr: %q", string(cmd.StdOut), string(cmd.StdErr)) + } + + if cmd.ExitCode != 1 { + t.Errorf("expected exit status 1, got %d", cmd.ExitCode) + } +} + +func TestExecutorWithArgs(t *testing.T) { + cmd := NewCommand("echo stdout") + + if err := cmd.Exec(); err != nil { + t.Errorf("expected success, got %+v", err) + } + if string(cmd.StdOut) != "stdout\n" { + t.Errorf("unexpected output: %q", string(cmd.StdOut)) + } + + cmd = NewCommand("echo stderr > /dev/stderr") + if err := cmd.Exec(); err != nil { + t.Errorf("expected success, got %+v", err) + } + if string(cmd.StdErr) != "stderr\n" { + t.Errorf("unexpected output: %q", string(cmd.StdErr)) + } +} + +func TestExecutableNotFound(t *testing.T) { + cmd := NewCommand("fake_executable_name") + err := cmd.Exec() + if err == nil { + t.Errorf("expected err, got nil") + } +} diff --git a/pkg/hash/fnv.go b/pkg/hash/fnv.go new file mode 100644 index 0000000..1af342f --- /dev/null +++ b/pkg/hash/fnv.go @@ -0,0 +1,41 @@ +// Copyright © 2022 99nil. +// +// 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 hash + +import ( + "fmt" + "hash/fnv" + "strconv" +) + +const alphaNums = "bcdfghjklmnpqrstvwxz2456789" + +func SafeEncodeString(s string) string { + r := make([]byte, len(s)) + for i, b := range []rune(s) { + r[i] = alphaNums[(int(b) % len(alphaNums))] + } + return string(r) +} + +func ComputeHash(data interface{}) string { + h := fnv.New32a() + fmt.Fprintf(h, "%#v", data) + return SafeEncodeString(strconv.FormatUint(uint64(h.Sum32()), 10)) +} + +func BuildNodeName(namespace, name string) string { + return name + "-" + ComputeHash(namespace) +} diff --git a/pkg/k8s/unstructured.go b/pkg/k8s/unstructured.go new file mode 100644 index 0000000..c2c01df --- /dev/null +++ b/pkg/k8s/unstructured.go @@ -0,0 +1,91 @@ +// Copyright © 2022 99nil. +// +// 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 k8s + +import ( + "bytes" + "fmt" + "io" + "path/filepath" + + "github.com/99nil/diplomat/static" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + pkgruntime "k8s.io/apimachinery/pkg/runtime" + serializeryaml "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + utilyaml "k8s.io/apimachinery/pkg/util/yaml" +) + +var serializer = serializeryaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + +func ParseAllYamlToObject(dirPath string) ([][]unstructured.Unstructured, error) { + files, err := static.EmbedResource.ReadDir(dirPath) + if err != nil { + return nil, fmt.Errorf("read resource dir(%s) failed: %v", dirPath, err) + } + + var objs [][]unstructured.Unstructured + for _, file := range files { + name := file.Name() + currentPath := filepath.Join(dirPath, name) + + if file.IsDir() { + current, err := ParseAllYamlToObject(currentPath) + if err != nil { + return nil, err + } + objs = append(objs, current...) + continue + } + + ext := filepath.Ext(name) + isYamlFile := ext == ".yaml" || ext == ".yml" + if !isYamlFile { + continue + } + result, err := parseUnstructuredObject(currentPath) + if err != nil { + return nil, err + } + objs = append(objs, result) + } + return objs, nil +} + +func parseUnstructuredObject(filePath string) ([]unstructured.Unstructured, error) { + data, err := static.EmbedResource.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("read file %s failed: %v", filePath, err) + } + decoder := utilyaml.NewYAMLOrJSONDecoder(bytes.NewReader(data), 256) + + var result []unstructured.Unstructured + for { + var rawObj pkgruntime.RawExtension + if err := decoder.Decode(&rawObj); err != nil { + if err == io.EOF { + break + } + return nil, fmt.Errorf("decode data to raw object failed: %v", err) + } + + var obj unstructured.Unstructured + if err := pkgruntime.DecodeInto(serializer, rawObj.Raw, &obj); err != nil { + return nil, fmt.Errorf("decode raw object failed: %v", err) + } + result = append(result, obj) + } + return result, nil +} diff --git a/pkg/util/file.go b/pkg/util/file.go new file mode 100644 index 0000000..9e7818b --- /dev/null +++ b/pkg/util/file.go @@ -0,0 +1,68 @@ +// Copyright © 2022 99nil. +// +// 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 util + +import ( + "fmt" + "os" + + "sigs.k8s.io/yaml" +) + +func Exists(path string) bool { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return false + } + return false + } + return true +} + +func ExistsAndCreateDir(path string) error { + f, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return os.MkdirAll(path, 0700) + } + return err + } + if !f.IsDir() { + return fmt.Errorf("path %s is not directory", path) + } + return nil +} + +func IsDir(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return s.IsDir() +} + +func IsFile(path string) bool { + return !IsDir(path) +} + +//Write2File writes data into a file in path +func Write2File(path string, data interface{}) error { + d, err := yaml.Marshal(data) + if err != nil { + return err + } + + return os.WriteFile(path, d, 0666) +} diff --git a/pkg/util/service.go b/pkg/util/service.go new file mode 100644 index 0000000..692da6b --- /dev/null +++ b/pkg/util/service.go @@ -0,0 +1,48 @@ +// Copyright © 2022 99nil. +// +// 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 util + +import ( + "fmt" + "os" + "path/filepath" +) + +// ExecStart like: /usr/local/bin/edgecore --config /etc/diplomat/edgecore.yaml +var serviceFileTemplate = `[Unit] +Description=%s + +[Service] +Type=simple +ExecStart=%s +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +` + +func GenerateServiceFile(cfgDir, processPath, process string) error { + filename := fmt.Sprintf("%s.service", process) + execContent := filepath.Join(processPath, process) + " --config " + filepath.Join(cfgDir, process+".yaml") + content := fmt.Sprintf(serviceFileTemplate, process, execContent) + serviceFilePath := fmt.Sprintf("/etc/systemd/system/%s", filename) + return os.WriteFile(serviceFilePath, []byte(content), os.ModePerm) +} + +func RemoveServiceFile(process string) error { + filename := fmt.Sprintf("%s.service", process) + return os.Remove(fmt.Sprintf("/etc/systemd/system/%s", filename)) +} diff --git a/pkg/util/util.go b/pkg/util/util.go index e93b0a3..bebe164 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -15,7 +15,13 @@ package util import ( + "fmt" + "io/ioutil" + "net" "strconv" + + utilnet "k8s.io/apimachinery/pkg/util/net" + "sigs.k8s.io/yaml" ) func ParseResourceVersion(resourceVersion string) uint64 { @@ -39,3 +45,87 @@ func CompareResourceVersion(a, b string) int { } return +1 } + +func WriteToFile(path string, data interface{}) error { + b, err := yaml.Marshal(data) + if err != nil { + return err + } + return ioutil.WriteFile(path, b, 0666) +} + +func GetLocalIP(hostName string) (string, error) { + var ipAddr net.IP + var err error + + // If looks up host failed, will use utilnet.ChooseHostInterface() below, + // So ignore the error here + addrs, _ := net.LookupIP(hostName) + for _, addr := range addrs { + if err := ValidateNodeIP(addr); err != nil { + continue + } + if addr.To4() != nil { + ipAddr = addr + break + } + if ipAddr == nil && addr.To16() != nil { + ipAddr = addr + } + } + + if ipAddr == nil { + ipAddr, err = utilnet.ChooseHostInterface() + if err != nil { + return "", err + } + } + return ipAddr.String(), nil +} + +// ValidateNodeIP validates given node IP belongs to the current host +func ValidateNodeIP(nodeIP net.IP) error { + // Honor IP limitations set in setNodeStatus() + if nodeIP.To4() == nil && nodeIP.To16() == nil { + return fmt.Errorf("nodeIP must be a valid IP address") + } + if nodeIP.IsLoopback() { + return fmt.Errorf("nodeIP can't be loopback address") + } + if nodeIP.IsMulticast() { + return fmt.Errorf("nodeIP can't be a multicast address") + } + if nodeIP.IsLinkLocalUnicast() { + return fmt.Errorf("nodeIP can't be a link-local unicast address") + } + if nodeIP.IsUnspecified() { + return fmt.Errorf("nodeIP can't be an all zeros address") + } + + addrs, err := net.InterfaceAddrs() + if err != nil { + return err + } + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + if ip != nil && ip.Equal(nodeIP) { + return nil + } + } + return fmt.Errorf("node IP: %q not found in the host's network interfaces", nodeIP.String()) +} + +func InStringSlice(ss []string, str string) (index int, exists bool) { + for k, v := range ss { + if str == v { + return k, true + } + } + return -1, false +} diff --git a/pkg/version/version.go b/pkg/version/version.go new file mode 100644 index 0000000..defb6fe --- /dev/null +++ b/pkg/version/version.go @@ -0,0 +1,87 @@ +// Copyright © 2022 99nil. +// +// 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" +) + +var ( + ver string + assistantVer string + kubeedgeVer string + ravenVer string +) + +type Version struct { + Version string + AssistantVersion string + KubeedgeVersion string + RavenVersion string + GoVersion string + Compiler string + Platform string +} + +func Get() *Version { + return &Version{ + Version: ver, + AssistantVersion: assistantVer, + KubeedgeVersion: kubeedgeVer, + RavenVersion: ravenVer, + GoVersion: runtime.Version(), + Compiler: runtime.Compiler, + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + } +} + +func (v *Version) String() string { + return fmt.Sprintf(`version: %s +assistant: %s +kubeedge: %s +raven: %s +go version: %s +go compiler: %s +platform: %s +`, + v.Version, + v.AssistantVersion, + v.KubeedgeVersion, + v.RavenVersion, + v.GoVersion, + v.Compiler, + v.Platform, + ) +} + +func (v *Version) EdgeString() string { + if v.Version == "" { + v.Version = "dev" + } + + return fmt.Sprintf(`version: %s +kubeedge: %s +go version: %s +go compiler: %s +platform: %s +`, + v.AssistantVersion, + v.KubeedgeVersion, + v.GoVersion, + v.Compiler, + v.Platform, + ) +} diff --git a/static/resource/bak/daemonset_iptablesmanager.yaml b/static/resource/bak/daemonset_iptablesmanager.yaml new file mode 100644 index 0000000..1d28ef7 --- /dev/null +++ b/static/resource/bak/daemonset_iptablesmanager.yaml @@ -0,0 +1,50 @@ +{{- if and (.Values.iptablesManager.enable) (eq .Values.iptablesManager.mode "external") }} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: cloud-iptables-manager + {{- with .Values.iptablesManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.iptablesManager.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- with .Values.iptablesManager.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + template: + metadata: + {{- with .Values.iptablesManager.labels }} + labels: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccount: iptables-manager-sa + hostNetwork: {{ .Values.iptablesManager.hostNetWork }} + {{- with .Values.iptablesManager.affinity }} + affinity: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.iptablesManager.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.iptablesManager.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + restartPolicy: Always + {{- with .Values.iptablesManager.image.pullSecrets }} + imagePullSecrets: {{ toYaml . | nindent 8 }} + {{- end }} + containers: + - name: iptables-manager + command: ['iptables-manager'] + image: {{ .Values.iptablesManager.image.repository }}:{{ .Values.iptablesManager.image.tag }} + imagePullPolicy: {{ .Values.iptablesManager.image.pullPolicy }} + {{- with .Values.iptablesManager.securityContext }} + securityContext: {{ toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.iptablesManager.resources }} + resources: {{ toYaml . | nindent 10 }} + {{- end }} +{{- end }} diff --git a/static/resource/bak/deployment_controllermanager.yaml b/static/resource/bak/deployment_controllermanager.yaml new file mode 100644 index 0000000..235888c --- /dev/null +++ b/static/resource/bak/deployment_controllermanager.yaml @@ -0,0 +1,39 @@ +{{- if (.Values.controllerManager.enable) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with .Values.controllerManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controllerManager.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} + name: kubeedge-controller-manager + namespace: kubeedge +spec: + selector: + {{- with .Values.controllerManager.labels }} + matchLabels: {{- toYaml . | nindent 6 }} + {{- end }} + template: + metadata: + {{- with .Values.controllerManager.labels }} + labels: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.controllerManager.image.pullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: controller-manager + image: {{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }} + imagePullPolicy: {{ .Values.controllerManager.image.pullPolicy }} + restartPolicy: Always + serviceAccountName: controller-manager + {{- with .Values.controllerManager.affinity }} + affinity: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controllerManager.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/static/resource/bak/rbac_controllermanager.yaml b/static/resource/bak/rbac_controllermanager.yaml new file mode 100644 index 0000000..ec26357 --- /dev/null +++ b/static/resource/bak/rbac_controllermanager.yaml @@ -0,0 +1,55 @@ +{{- if (.Values.controllerManager.enable) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: {{ .Release.Namespace }} + {{- with .Values.controllerManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: controller-manager + {{- with .Values.controllerManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: controller-manager +subjects: + - kind: ServiceAccount + name: controller-manager + namespace: kubeedge + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: controller-manager + {{- with .Values.controllerManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["apps.kubeedge.io"] + resources: ["nodegroups", "nodegroups/status"] + verbs: ["*"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["list", "watch", "patch", "get"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["list", "watch", "get", "delete"] + - apiGroups: ["apps.kubeedge.io"] + resources: ["edgeapplications", "edgeapplications/status"] + verbs: ["*"] + - apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["list", "watch", "create", "update", "patch", "delete", "get"] + - apiGroups: [""] + resources: ["services"] + verbs: ["list", "watch", "create", "update", "patch", "delete", "get"] +{{- end }} diff --git a/static/resource/bak/rbac_iptablesmanager.yaml b/static/resource/bak/rbac_iptablesmanager.yaml new file mode 100644 index 0000000..73c626e --- /dev/null +++ b/static/resource/bak/rbac_iptablesmanager.yaml @@ -0,0 +1,40 @@ +{{- if and (.Values.iptablesManager.enable) (eq .Values.iptablesManager.mode "external") }} +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- with .Values.iptablesManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + name: iptables-manager-sa + namespace: {{ .Release.Namespace }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: iptables-manager + {{- with .Values.iptablesManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: iptables-manager +subjects: +- kind: ServiceAccount + name: iptables-manager-sa + namespace: {{ .Release.Namespace }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: iptables-manager + {{- with .Values.iptablesManager.labels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch"] +{{- end }} \ No newline at end of file diff --git a/static/resource/binary/flannel/cni-plugins-amd64-v0.7.4-diplomat.tgz b/static/resource/binary/flannel/cni-plugins-amd64-v0.7.4-diplomat.tgz new file mode 100644 index 0000000..e2dd16d Binary files /dev/null and b/static/resource/binary/flannel/cni-plugins-amd64-v0.7.4-diplomat.tgz differ diff --git a/static/resource/binary/flannel/cni-plugins-arm-v0.7.4-diplomat.tgz b/static/resource/binary/flannel/cni-plugins-arm-v0.7.4-diplomat.tgz new file mode 100644 index 0000000..78ea589 Binary files /dev/null and b/static/resource/binary/flannel/cni-plugins-arm-v0.7.4-diplomat.tgz differ diff --git a/static/resource/binary/flannel/cni-plugins-arm64-v0.7.4-diplomat.tgz b/static/resource/binary/flannel/cni-plugins-arm64-v0.7.4-diplomat.tgz new file mode 100644 index 0000000..d4bfa2b Binary files /dev/null and b/static/resource/binary/flannel/cni-plugins-arm64-v0.7.4-diplomat.tgz differ diff --git a/static/resource/binary/flannel/cni-plugins-ppc64le-v0.7.4-diplomat.tgz b/static/resource/binary/flannel/cni-plugins-ppc64le-v0.7.4-diplomat.tgz new file mode 100644 index 0000000..ac271e3 Binary files /dev/null and b/static/resource/binary/flannel/cni-plugins-ppc64le-v0.7.4-diplomat.tgz differ diff --git a/static/resource/binary/flannel/cni-plugins-s390x-v0.7.4-diplomat.tgz b/static/resource/binary/flannel/cni-plugins-s390x-v0.7.4-diplomat.tgz new file mode 100644 index 0000000..5a01a0a Binary files /dev/null and b/static/resource/binary/flannel/cni-plugins-s390x-v0.7.4-diplomat.tgz differ diff --git a/static/resource/scripts/gen-admission-secret.sh b/static/resource/scripts/gen-admission-secret.sh new file mode 100755 index 0000000..ba28b0e --- /dev/null +++ b/static/resource/scripts/gen-admission-secret.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +NAMESPACE=${NAMESPACE:-kubeedge} +SERVICE=${SERVICE:-"admission"} +SECRET=${SECRET:-"admission-secret"} +CERTDIR=${CERTDIR:-"/etc/diplomat/admission-certs"} +ENABLE_CREATE_SECRET=${ENABLE_CREATE_SECRET:-true} +CN=${CN:-"${SERVICE}.${NAMESPACE}.svc"} +IP=${IP:-"127.0.0.1"} +if [[ ${IP} != "127.0.0.1" ]]; then + echo "生成IP证书:${IP}" + CN=${IP} +fi + +if [[ ! -x "$(command -v openssl)" ]]; then + echo "openssl not found" + exit 1 +fi + +function createCerts() { + echo "creating certs in dir ${CERTDIR} " + + cat < ${CERTDIR}/csr.conf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +DNS.1 = ${SERVICE} +DNS.2 = ${SERVICE}.${NAMESPACE} +DNS.3 = ${SERVICE}.${NAMESPACE}.svc +IP = ${IP} +EOF + + openssl genrsa -out ${CERTDIR}/ca.key 2048 + openssl req -x509 -days 3650 -new -nodes -key ${CERTDIR}/ca.key -subj "/CN=${CN}" -out ${CERTDIR}/ca.crt + + openssl genrsa -out ${CERTDIR}/server.key 2048 + openssl req -new -days 3650 -key ${CERTDIR}/server.key -subj "/CN=${CN}" -out ${CERTDIR}/server.csr -config ${CERTDIR}/csr.conf + + openssl x509 -req -days 3650 -in ${CERTDIR}/server.csr -CA ${CERTDIR}/ca.crt -CAkey ${CERTDIR}/ca.key \ + -CAcreateserial -out ${CERTDIR}/server.crt \ + -extensions v3_req -extfile ${CERTDIR}/csr.conf +} + +function createObjects() { + # `ENABLE_CREATE_SECRET` should always be set to `true` unless it has been already created. + if [[ "${ENABLE_CREATE_SECRET}" = true ]]; then + kubectl get ns ${NAMESPACE} || kubectl create ns ${NAMESPACE} + + # create the secret with CA cert and server cert/key + kubectl create secret generic ${SECRET} \ + --from-file=server.key=${CERTDIR}/server.key \ + --from-file=server.crt=${CERTDIR}/server.crt \ + --from-file=ca.crt=${CERTDIR}/ca.crt \ + -n ${NAMESPACE} + fi +} + +mkdir -p ${CERTDIR} +createCerts +createObjects diff --git a/static/resource/scripts/gen-cloudcore-secret.sh b/static/resource/scripts/gen-cloudcore-secret.sh new file mode 100755 index 0000000..1633934 --- /dev/null +++ b/static/resource/scripts/gen-cloudcore-secret.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -o errexit + +NAMESPACE=${NAMESPACE:-kubeedge} +SECRET=${SECRET:-"cloudcore"} +ENABLE_CREATE_SECRET=${ENABLE_CREATE_SECRET:-true} +readonly caPath=${CA_PATH:-/etc/diplomat/ca} +readonly certPath=${CERT_PATH:-/etc/diplomat/certs} +readonly subject=${SUBJECT:-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io} +CN="" +# TODO 支持多IP +IP=${IP:-"127.0.0.1"} +if [[ ${IP} != "127.0.0.1" ]]; then + echo "生成IP证书:${IP}" + CN=${IP} +fi + +function createCerts() { + echo "creating certs in dir ${CERTDIR} " + cat < ${certPath}/csr.conf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +IP = 127.0.0.1 +IP = ${IP} +EOF + + openssl genrsa -out ${caPath}/rootCA.key 2048 + openssl req -x509 -days 3650 -new -nodes -key ${caPath}/rootCA.key -subj "/CN=${CN}" -out ${caPath}/rootCA.crt + + openssl genrsa -out ${certPath}/edge.key 2048 + openssl req -new -days 3650 -key ${certPath}/edge.key -subj "/CN=${CN}" -out ${certPath}/edge.csr -config ${certPath}/csr.conf + + openssl x509 -req -days 3650 -in ${certPath}/edge.csr -CA ${caPath}/rootCA.crt -CAkey ${caPath}/rootCA.key \ + -CAcreateserial -out ${certPath}/edge.crt \ + -extensions v3_req -extfile ${certPath}/csr.conf +} + +function createObjects() { + # `ENABLE_CREATE_SECRET` should always be set to `true` unless it has been already created. + if [[ "${ENABLE_CREATE_SECRET}" = true ]]; then + kubectl get ns ${NAMESPACE} || kubectl create ns ${NAMESPACE} + + # create the secret with CA cert and server cert/key + kubectl create secret generic ${SECRET} \ + --from-file=edge.key=${certPath}/edge.key \ + --from-file=edge.crt=${certPath}/edge.crt \ + --from-file=rootCA.crt=${caPath}/rootCA.crt \ + --from-file=rootCA.key=${caPath}/rootCA.key \ + -n ${NAMESPACE} + fi +} + +ensureFolder() { + if [ ! -d ${caPath} ]; then + mkdir -p ${caPath} + fi + if [ ! -d ${certPath} ]; then + mkdir -p ${certPath} + fi +} + +ensureFolder +createCerts +createObjects diff --git a/static/resource/scripts/gen-stream-secret.sh b/static/resource/scripts/gen-stream-secret.sh new file mode 100755 index 0000000..5a8ce9a --- /dev/null +++ b/static/resource/scripts/gen-stream-secret.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash + +set -o errexit + +NAMESPACE=${NAMESPACE:-kubeedge} +readonly caPath=${CA_PATH:-/etc/diplomat/ca} +readonly caSubject=${CA_SUBJECT:-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io/CN=127.0.0.1} +readonly certPath=${CERT_PATH:-/etc/diplomat/certs} +readonly subject=${SUBJECT:-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge/CN=kubeedge.io/CN=127.0.0.1} + +genCA() { + local IPs=(${@:1}) + echo $IPs + local subj=${subject} +# if [ -n "$IPs" ]; then +# for ip in ${IPs[*]}; do +# subj="${subj}/CN=${ip}" +# done +# fi + echo ${subj} + openssl genrsa -des3 -out ${caPath}/rootCA.key -passout pass:kubeedge.io 4096 + openssl req -x509 -new -nodes -key ${caPath}/rootCA.key -sha256 -days 3650 \ + -subj ${subj} -passin pass:kubeedge.io -out ${caPath}/rootCA.crt +} + +ensureCA() { + local serverIPs=$1 + echo $serverIPs + if [ ! -e ${caPath}/rootCA.key ] || [ ! -e ${caPath}/rootCA.crt ]; then + genCA $serverIPs + fi +} + +ensureFolder() { + if [ ! -d ${caPath} ]; then + mkdir -p ${caPath} + fi + if [ ! -d ${certPath} ]; then + mkdir -p ${certPath} + fi +} + +genCsr() { + local name=$1 IPs=(${@:2}) + local subj=${subject} +# if [ -n "$IPs" ]; then +# for ip in ${IPs[*]}; do +# subj="${subj}/CN=${ip}" +# done +# fi + echo ${subj} + openssl genrsa -out ${certPath}/${name}.key 2048 + openssl req -new -key ${certPath}/${name}.key -subj ${subj} -out ${certPath}/${name}.csr +} + +genCert() { + local name=$1 IPs=(${@:2}) + echo "IPS: " $IPs + if [ -z "$IPs" ] ;then + openssl x509 -req -in ${certPath}/${name}.csr -CA ${caPath}/rootCA.crt -CAkey ${caPath}/rootCA.key \ + -CAcreateserial -passin pass:kubeedge.io -out ${certPath}/${name}.crt -days 365 -sha256 + else + index=1 + SUBJECTALTNAME="subjectAltName = IP.1:127.0.0.1" + # TODO err unable to ParsePKCS1PrivateKey: asn1: structure error: length too large +# for ip in ${IPs[*]}; do +# SUBJECTALTNAME="${SUBJECTALTNAME}," +# index=$(($index+1)) +# SUBJECTALTNAME="${SUBJECTALTNAME}IP.${index}:${ip}" +# done + echo $SUBJECTALTNAME > /tmp/server-extfile.cnf + openssl x509 -req -in ${certPath}/${name}.csr -CA ${caPath}/rootCA.crt -CAkey ${caPath}/rootCA.key \ + -CAcreateserial -passin pass:kubeedge.io -out ${certPath}/${name}.crt -days 365 -sha256 -extfile /tmp/server-extfile.cnf + fi +} + +genCertAndKey() { + while getopts ':i:h' opt; do + case $opt in + i) IPS=($OPTARG) + ;; + h) usage;; + ?) usage;; + esac + done + local name=$1 serverIPs=${IPS} +# if [[ $serverIPs == *"Usage:"* ]];then +# echo $serverIPs +# exit 1 +# fi + ensureFolder + ensureCA $serverIPs + genCsr $name $serverIPs + genCert $name $serverIPs +} + +stream() { + ensureFolder + local k8sCertPath="" + local createK8sSecret=false + readonly CLOUDCOREIPS=${CLOUDCOREIPS} + readonly CLOUDCORE_DOMAINS=${CLOUDCORE_DOMAINS} + readonly streamsubject=${SUBJECT:-/C=CN/ST=Zhejiang/L=Hangzhou/O=KubeEdge} + readonly STREAM_KEY_FILE=${certPath}/stream.key + readonly STREAM_CSR_FILE=${certPath}/stream.csr + readonly STREAM_CRT_FILE=${certPath}/stream.crt + + readonly K8SCA_FILE=${k8sCertPath:-/etc/kubernetes/pki}/ca.crt + readonly K8SCA_KEY_FILE=${k8sCertPath:-/etc/kubernetes/pki}/ca.key + + while getopts ":c:p:h" opt + do + case $opt in + c) + if [ "${OPTARG}" == "true" ]; then + createK8sSecret=true + fi + ;; + p) + if [ -n "${OPTARG}" ]; then + k8sCertPath=${OPTARG} + fi + ;; + h) + echo "Set -c true will create stream k8s secret after generated certificates. +It is necessary to set -p , which use to signed certificates." + ;; + ?) + echo "unknown tag" + exit 1;; + esac + done + + if [ -z "${k8sCertPath}" ]; then + echo "You must set -p to specify k8s cert path." + exit 1 + fi + + if [ -z "${CLOUDCOREIPS}" ] && [ -z "${CLOUDCORE_DOMAINS}" ]; then + echo "You must set at least one of CLOUDCOREIPS or CLOUDCORE_DOMAINS Env.These environment +variables are set to specify the IP addresses or domains of all cloudcore, respectively." + echo "If there are more than one IP or domain, you need to separate them with a space within a single env." + exit 1 + fi + + index=1 + SUBJECTALTNAME="subjectAltName = IP.1:127.0.0.1" + for ip in ${CLOUDCOREIPS}; do + SUBJECTALTNAME="${SUBJECTALTNAME}," + index=$(($index+1)) + SUBJECTALTNAME="${SUBJECTALTNAME}IP.${index}:${ip}" + done + index=1 + if [ ${CLOUDCORE_DOMAINS} -a "-n ${CLOUDCORE_DOMAINS}" ]; then + for domain in ${CLOUDCORE_DOMAINS}; do + SUBJECTALTNAME="${SUBJECTALTNAME}," + index=$(($index+1)) + SUBJECTALTNAME="${SUBJECTALTNAME}DNS.${index}:${domain}" + done + fi + + cp ${K8SCA_FILE} ${caPath}/streamCA.crt + echo $SUBJECTALTNAME > /tmp/server-extfile.cnf + + openssl genrsa -out ${STREAM_KEY_FILE} 2048 + openssl req -new -key ${STREAM_KEY_FILE} -subj ${streamsubject} -out ${STREAM_CSR_FILE} + + # verify + openssl req -in ${STREAM_CSR_FILE} -noout -text + openssl x509 -req -in ${STREAM_CSR_FILE} -CA ${K8SCA_FILE} -CAkey ${K8SCA_KEY_FILE} -CAcreateserial -out ${STREAM_CRT_FILE} -days 5000 -sha256 -extfile /tmp/server-extfile.cnf + #verify + openssl x509 -in ${STREAM_CRT_FILE} -text -noout + + if [ "${createK8sSecret}" = "true" ]; then + kubectl get ns ${NAMESPACE} || kubectl create ns ${NAMESPACE} + kubectl create secret generic cloudcore-stream \ + --from-file=stream.key=${certPath}/stream.key \ + --from-file=stream.crt=${certPath}/stream.crt \ + --from-file=streamCA.crt=${caPath}/streamCA.crt \ + -n ${NAMESPACE} + fi +} + +opts(){ + usage() { echo "Usage: $0 [-i] ip1,ip2,..."; exit; } + local OPTIND + while getopts ':i:h' opt; do + case $opt in + i) IFS=',' + IPS=($OPTARG) + ;; + h) usage;; + ?) usage;; + esac + done + echo ${IPS[*]} +} + +edgesiteServer(){ + serverIPs="$(opts $*)" + if [[ $serverIPs == *"Usage:"* ]];then + echo $serverIPs + exit 1 + fi + local name=edgesite-server + ensureFolder + ensureCA + genCsr $name + genCert $name $serverIPs + genCsr server + genCert server $serverIPs +} + +edgesiteAgent(){ + ensureFolder + ensureCA + local name=edgesite-agent + genCsr $name + genCert $name +} + +# example: buildCloudcoreSecret -i 127.0.0.1,192.168.1.1 +buildCloudcoreSecret() { + ensureFolder + while getopts ':i:h' opt; do + case $opt in + i) IPS=($OPTARG) + ;; + h) usage;; + ?) usage;; + esac + done + local name="edge" + echo ${IPS} + genCertAndKey ${name} -i ${IPS} > /dev/null 2>&1 + cat > ${certPath}/cloudcore-secret.yaml </image - ReplicaSet: + spec/template/spec/containers//image - + Deployment: spec/template/spec/containers//image + \ - StatefulSet: spec/template/spec/containers//image + In addition, all images will be processed if + the resource object has more than one containers. + \n If not nil, only images matches the filters + will be processed." + properties: + path: + description: Path indicates the path of target + field + type: string + required: + - path + type: object + value: + description: Value to be applied to image. Must + not be empty when operator is 'add' or 'replace'. + Defaults to empty and ignored when operator + is 'remove'. + type: string + required: + - component + - operator + type: object + type: array + replicas: + description: Replicas will override the replicas field + of deployment + type: integer + type: object + required: + - name + type: object + type: array + type: object + workloadTemplate: + description: WorkloadTemplate contains original templates of resources + to be deployed as an EdgeApplication. + properties: + manifests: + description: Manifests represent a list of Kubernetes resources + to be deployed on the managed node groups. + items: + description: Manifest represents a resource to be deployed on + managed node groups. + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + required: + - workloadScope + type: object + status: + description: Status represents the status of PropagationStatus. + properties: + workloadStatus: + description: WorkloadStatus contains running statuses of generated + resources. + items: + description: ManifestStatus contains running status of a specific + manifest in spec. + properties: + conditions: + description: 'Conditions contain the different condition statuses + for this manifest. Valid condition types are: 1. Processing: + this workload is under processing and the current state of + manifest does not match the desired. 2. Available: the current + status of this workload matches the desired.' + enum: + - Processing + - Available + type: string + identifier: + description: Identifier represents the identity of a resource + linking to manifests in spec. + properties: + group: + description: Group is the group of the resource. + type: string + kind: + description: Kind is the kind of the resource. + type: string + name: + description: Name is the name of the resource + type: string + namespace: + description: Namespace is the namespace of the resource + type: string + ordinal: + description: Ordinal represents an index in manifests list, + so the condition can still be linked to a manifest even + though manifest cannot be parsed successfully. + minimum: 0 + type: integer + resource: + description: Resource is the resource type of the resource + type: string + version: + description: Version is the version of the resource. + type: string + required: + - ordinal + type: object + required: + - identifier + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_apps_v1alpha1_nodegroup.yaml b/static/resource/yaml/01-kubeedge/00_crd_apps_v1alpha1_nodegroup.yaml new file mode 100644 index 0000000..facaee8 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_apps_v1alpha1_nodegroup.yaml @@ -0,0 +1,92 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: nodegroups.apps.kubeedge.io +spec: + group: apps.kubeedge.io + names: + kind: NodeGroup + listKind: NodeGroupList + plural: nodegroups + shortNames: + - ng + singular: nodegroup + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeGroup is the Schema for the nodegroups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec represents the specification of the desired behavior + of member nodegroup. + properties: + matchLabels: + additionalProperties: + type: string + description: MatchLabels are used to select nodes that have these + labels. + type: object + nodes: + description: Nodes contains names of all the nodes in the nodegroup. + items: + type: string + type: array + type: object + status: + description: Status represents the status of member nodegroup. + properties: + nodeStatuses: + description: NodeStatuses is a status list of all selected nodes. + items: + description: NodeStatus contains status of node that selected by + this NodeGroup. + properties: + nodeName: + description: NodeName contains name of this node. + type: string + readyStatus: + description: ReadyStatus contains ready status of this node. + type: string + selectionStatus: + description: SelectionStatus contains status of the selection + result for this node. + type: string + selectionStatusReason: + description: SelectionStatusReason contains human-readable reason + for this SelectionStatus. + type: string + required: + - nodeName + - readyStatus + - selectionStatus + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_cluster_objectsync_v1alpha1.yaml b/static/resource/yaml/01-kubeedge/00_crd_cluster_objectsync_v1alpha1.yaml new file mode 100644 index 0000000..785e85d --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_cluster_objectsync_v1alpha1.yaml @@ -0,0 +1,73 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: clusterobjectsyncs.reliablesyncs.kubeedge.io +spec: + group: reliablesyncs.kubeedge.io + names: + kind: ClusterObjectSync + listKind: ClusterObjectSyncList + plural: clusterobjectsyncs + singular: clusterobjectsync + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterObjectSync stores the state of the cluster level, nonNamespaced + object that was successfully persisted to the edge node. ClusterObjectSync + name is a concatenation of the node name which receiving the object and + the object UUID. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ObjectSyncSpec stores the details of objects that persist + to the edge. + properties: + objectAPIVersion: + description: ObjectAPIVersion is the APIVersion of the object that + was successfully persist to the edge node. + type: string + objectKind: + description: ObjectType is the kind of the object that was successfully + persist to the edge node. + type: string + objectName: + description: ObjectName is the name of the object that was successfully + persist to the edge node. + type: string + type: object + status: + description: ObjectSyncSpec stores the resourceversion of objects that + persist to the edge. + properties: + objectResourceVersion: + description: ObjectResourceVersion is the resourceversion of the object + that was successfully persist to the edge node. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_device.yaml b/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_device.yaml new file mode 100644 index 0000000..b30df57 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_device.yaml @@ -0,0 +1,532 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: devices.devices.kubeedge.io +spec: + group: devices.kubeedge.io + names: + kind: Device + listKind: DeviceList + plural: devices + singular: device + scope: Namespaced + versions: + - name: v1alpha2 + schema: + openAPIV3Schema: + description: Device is the Schema for the devices API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DeviceSpec represents a single device instance. It is an + instantation of a device model. + properties: + data: + description: Data section describe a list of time-series properties + which should be processed on edge node. + properties: + dataProperties: + description: 'Required: A list of data properties, which are not + required to be processed by edgecore' + items: + description: DataProperty represents the device property for + external use. + properties: + metadata: + additionalProperties: + type: string + description: Additional metadata like timestamp when the + value was reported etc. + type: object + propertyName: + description: 'Required: The property name for which should + be processed by external apps. This property should be + present in the device model.' + type: string + type: object + type: array + dataTopic: + description: Topic used by mapper, all data collected from dataProperties + should be published to this topic, the default value is $ke/events/device/+/data/update + type: string + type: object + deviceModelRef: + description: 'Required: DeviceModelRef is reference to the device + model used as a template to create the device instance.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + nodeSelector: + description: NodeSelector indicates the binding preferences between + devices and nodes. Refer to k8s.io/kubernetes/pkg/apis/core NodeSelector + for more details + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms + are ORed. + items: + description: A null or empty node selector term matches no objects. + The requirements of them are ANDed. The TopologySelectorTerm + type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's + labels. + items: + description: A node selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the selector applies + to. + type: string + operator: + description: Represents a key's relationship to a + set of values. Valid operators are In, NotIn, Exists, + DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator + is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. If the operator is Gt or Lt, + the values array must have a single element, which + will be interpreted as an integer. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's + fields. + items: + description: A node selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the selector applies + to. + type: string + operator: + description: Represents a key's relationship to a + set of values. Valid operators are In, NotIn, Exists, + DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator + is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. If the operator is Gt or Lt, + the values array must have a single element, which + will be interpreted as an integer. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + propertyVisitors: + description: List of property visitors which describe how to access + the device properties. PropertyVisitors must unique by propertyVisitor.propertyName. + items: + description: DevicePropertyVisitor describes the specifics of accessing + a particular device property. Visitors are intended to be consumed + by device mappers which connect to devices and collect data / + perform actions on the device. + properties: + bluetooth: + description: Bluetooth represents a set of additional visitor + config fields of bluetooth protocol. + properties: + characteristicUUID: + description: 'Required: Unique ID of the corresponding operation' + type: string + dataConverter: + description: Responsible for converting the data being read + from the bluetooth device into a form that is understandable + by the platform + properties: + endIndex: + description: 'Required: Specifies the end index of incoming + byte stream to be considered to convert the data the + value specified should be inclusive for example if + 3 is specified it includes the third index' + type: integer + orderOfOperations: + description: Specifies in what order the operations(which + are required to be performed to convert incoming data + into understandable form) are performed + items: + description: Specify the operation that should be + performed to convert incoming data into understandable + form + properties: + operationType: + description: 'Required: Specifies the operation + to be performed to convert incoming data' + type: string + operationValue: + description: 'Required: Specifies with what value + the operation is to be performed' + type: number + type: object + type: array + shiftLeft: + description: Refers to the number of bits to shift left, + if left-shift operation is necessary for conversion + type: integer + shiftRight: + description: Refers to the number of bits to shift right, + if right-shift operation is necessary for conversion + type: integer + startIndex: + description: 'Required: Specifies the start index of + the incoming byte stream to be considered to convert + the data. For example: start-index:2, end-index:3 + concatenates the value present at second and third + index of the incoming byte stream. If we want to reverse + the order we can give it as start-index:3, end-index:2' + type: integer + type: object + dataWrite: + additionalProperties: + format: byte + type: string + description: 'Responsible for converting the data coming + from the platform into a form that is understood by the + bluetooth device For example: "ON":[1], "OFF":[0]' + type: object + type: object + collectCycle: + description: Define how frequent mapper will collect from device. + format: int64 + type: integer + customizedProtocol: + description: CustomizedProtocol represents a set of visitor + config fields of bluetooth protocol. + properties: + configData: + description: 'Required: The configData of customized protocol' + type: object + x-kubernetes-preserve-unknown-fields: true + protocolName: + description: 'Required: name of customized protocol' + type: string + type: object + customizedValues: + description: Customized values for visitor of provided protocols + type: object + x-kubernetes-preserve-unknown-fields: true + modbus: + description: Modbus represents a set of additional visitor config + fields of modbus protocol. + properties: + isRegisterSwap: + description: Indicates whether the high and low register + swapped. Defaults to false. + type: boolean + isSwap: + description: Indicates whether the high and low byte swapped. + Defaults to false. + type: boolean + limit: + description: 'Required: Limit number of registers to read/write.' + format: int64 + type: integer + offset: + description: 'Required: Offset indicates the starting register + number to read/write data.' + format: int64 + type: integer + register: + description: 'Required: Type of register' + enum: + - CoilRegister + - DiscreteInputRegister + - InputRegister + - HoldingRegister + type: string + scale: + description: The scale to convert raw property data into + final units. Defaults to 1.0 + type: number + type: object + opcua: + description: Opcua represents a set of additional visitor config + fields of opc-ua protocol. + properties: + browseName: + description: The name of opc-ua node + type: string + nodeID: + description: 'Required: The ID of opc-ua node, e.g. "ns=1,i=1005"' + type: string + type: object + propertyName: + description: 'Required: The device property name to be accessed. + This should refer to one of the device properties defined + in the device model.' + type: string + reportCycle: + description: Define how frequent mapper will report the value. + format: int64 + type: integer + type: object + type: array + protocol: + description: 'Required: The protocol configuration used to connect + to the device.' + properties: + bluetooth: + description: Protocol configuration for bluetooth + properties: + macAddress: + description: Unique identifier assigned to the device. + type: string + type: object + common: + description: Configuration for protocol common part + properties: + collectRetryTimes: + description: Define retry times of mapper will collect from + device. + format: int64 + type: integer + collectTimeout: + description: Define timeout of mapper collect from device. + format: int64 + type: integer + collectType: + description: Define collect type, sync or async. + enum: + - sync + - async + type: string + com: + properties: + baudRate: + description: Required. BaudRate 115200|57600|38400|19200|9600|4800|2400|1800|1200|600|300|200|150|134|110|75|50 + enum: + - 115200 + - 57600 + - 38400 + - 19200 + - 9600 + - 4800 + - 2400 + - 1800 + - 1200 + - 600 + - 300 + - 200 + - 150 + - 134 + - 110 + - 75 + - 50 + format: int64 + type: integer + dataBits: + description: Required. Valid values are 8, 7, 6, 5. + enum: + - 8 + - 7 + - 6 + - 5 + format: int64 + type: integer + parity: + description: Required. Valid options are "none", "even", + "odd". Defaults to "none". + enum: + - none + - even + - odd + type: string + serialPort: + description: Required. + type: string + stopBits: + description: Required. Bit that stops 1|2 + enum: + - 1 + - 2 + format: int64 + type: integer + type: object + commType: + description: Communication type, like tcp client, tcp server + or COM + type: string + customizedValues: + description: Customized values for provided protocol + type: object + x-kubernetes-preserve-unknown-fields: true + reconnRetryTimes: + description: Reconnecting retry times + format: int64 + type: integer + reconnTimeout: + description: Reconnection timeout + format: int64 + type: integer + tcp: + properties: + ip: + description: Required. + type: string + port: + description: Required. + format: int64 + type: integer + type: object + type: object + customizedProtocol: + description: Configuration for customized protocol + properties: + configData: + description: Any config data + type: object + x-kubernetes-preserve-unknown-fields: true + protocolName: + description: Unique protocol name Required. + type: string + type: object + modbus: + description: Protocol configuration for modbus + properties: + slaveID: + description: Required. 0-255 + format: int64 + type: integer + type: object + opcua: + description: Protocol configuration for opc-ua + properties: + certificate: + description: Certificate for access opc server. + type: string + password: + description: Password for access opc server. + type: string + privateKey: + description: PrivateKey for access opc server. + type: string + securityMode: + description: Defaults to "none". + type: string + securityPolicy: + description: Defaults to "none". + type: string + timeout: + description: Timeout seconds for the opc server connection.??? + format: int64 + type: integer + url: + description: 'Required: The URL for opc server endpoint.' + type: string + userName: + description: Username for access opc server. + type: string + type: object + type: object + type: object + status: + description: DeviceStatus reports the device state and the desired/reported + values of twin attributes. + properties: + twins: + description: 'A list of device twins containing desired/reported desired/reported + values of twin properties.. Optional: A passive device won''t have + twin properties and this list could be empty.' + items: + description: Twin provides a logical representation of control properties + (writable properties in the device model). The properties can + have a Desired state and a Reported state. The cloud configures + the `Desired`state of a device property and this configuration + update is pushed to the edge node. The mapper sends a command + to the device to change this property value as per the desired + state . It receives the `Reported` state of the property once + the previous operation is complete and sends the reported state + to the cloud. Offline device interaction in the edge is possible + via twin properties for control/command operations. + properties: + desired: + description: 'Required: the desired property value.' + properties: + metadata: + additionalProperties: + type: string + description: Additional metadata like timestamp when the + value was reported etc. + type: object + value: + description: 'Required: The value for this property.' + type: string + required: + - value + type: object + propertyName: + description: 'Required: The property name for which the desired/reported + values are specified. This property should be present in the + device model.' + type: string + reported: + description: 'Required: the reported property value.' + properties: + metadata: + additionalProperties: + type: string + description: Additional metadata like timestamp when the + value was reported etc. + type: object + value: + description: 'Required: The value for this property.' + type: string + required: + - value + type: object + type: object + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_devicemodel.yaml b/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_devicemodel.yaml new file mode 100644 index 0000000..0444108 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_devices_v1alpha2_devicemodel.yaml @@ -0,0 +1,164 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: devicemodels.devices.kubeedge.io +spec: + group: devices.kubeedge.io + names: + kind: DeviceModel + listKind: DeviceModelList + plural: devicemodels + singular: devicemodel + scope: Namespaced + versions: + - name: v1alpha2 + schema: + openAPIV3Schema: + description: DeviceModel is the Schema for the device model API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DeviceModelSpec defines the model / template for a device.It + is a blueprint which describes the device capabilities and access mechanism + via property visitors. + properties: + properties: + description: 'Required: List of device properties.' + items: + description: DeviceProperty describes an individual device property + / attribute like temperature / humidity etc. + properties: + description: + description: The device property description. + type: string + name: + description: 'Required: The device property name.' + type: string + type: + description: 'Required: PropertyType represents the type and + data validation of the property.' + properties: + boolean: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + defaultValue: + type: boolean + type: object + bytes: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + type: object + double: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + defaultValue: + type: number + maximum: + type: number + minimum: + type: number + unit: + description: The unit of the property + type: string + type: object + float: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + defaultValue: + type: number + maximum: + type: number + minimum: + type: number + unit: + description: The unit of the property + type: string + type: object + int: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + defaultValue: + format: int64 + type: integer + maximum: + format: int64 + type: integer + minimum: + format: int64 + type: integer + unit: + description: The unit of the property + type: string + type: object + string: + properties: + accessMode: + description: 'Required: Access mode of property, ReadWrite + or ReadOnly.' + enum: + - ReadWrite + - ReadOnly + type: string + defaultValue: + type: string + type: object + type: object + type: object + type: array + protocol: + description: 'Required for DMI: Protocol name used by the device.' + type: string + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_objectsync_v1alpha1.yaml b/static/resource/yaml/01-kubeedge/00_crd_objectsync_v1alpha1.yaml new file mode 100644 index 0000000..0841874 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_objectsync_v1alpha1.yaml @@ -0,0 +1,72 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: objectsyncs.reliablesyncs.kubeedge.io +spec: + group: reliablesyncs.kubeedge.io + names: + kind: ObjectSync + listKind: ObjectSyncList + plural: objectsyncs + singular: objectsync + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ObjectSync stores the state of the namespaced object that was + successfully persisted to the edge node. ObjectSync name is a concatenation + of the node name which receiving the object and the object UUID. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ObjectSyncSpec stores the details of objects that persist + to the edge. + properties: + objectAPIVersion: + description: ObjectAPIVersion is the APIVersion of the object that + was successfully persist to the edge node. + type: string + objectKind: + description: ObjectType is the kind of the object that was successfully + persist to the edge node. + type: string + objectName: + description: ObjectName is the name of the object that was successfully + persist to the edge node. + type: string + type: object + status: + description: ObjectSyncSpec stores the resourceversion of objects that + persist to the edge. + properties: + objectResourceVersion: + description: ObjectResourceVersion is the resourceversion of the object + that was successfully persist to the edge node. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_operations_v1alpha1_nodeupgradejob.yaml b/static/resource/yaml/01-kubeedge/00_crd_operations_v1alpha1_nodeupgradejob.yaml new file mode 100644 index 0000000..971621b --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_operations_v1alpha1_nodeupgradejob.yaml @@ -0,0 +1,186 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: nodeupgradejobs.operations.kubeedge.io +spec: + group: operations.kubeedge.io + names: + kind: NodeUpgradeJob + listKind: NodeUpgradeJobList + plural: nodeupgradejobs + singular: nodeupgradejob + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeUpgradeJob is used to upgrade edge node from cloud side. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of NodeUpgradeJob. + properties: + image: + description: 'Image specifies a container image name, the image contains: + keadm and edgecore. keadm is used as upgradetool, to install the + new version of edgecore. The image name consists of registry hostname + and repository name, if it includes the tag or digest, the tag or + digest will be overwritten by Version field above. If the registry + hostname is empty, docker.io will be used as default. The default + image name is: kubeedge/installation-package.' + type: string + labelSelector: + description: LabelSelector is a filter to select member clusters by + labels. It must match a node's labels for the NodeUpgradeJob to + be operated on that node. Please note that sets of NodeNames and + LabelSelector are ORed. Users must set one and can only set one. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + nodeNames: + description: NodeNames is a request to select some specific nodes. + If it is non-empty, the upgrade job simply select these edge nodes + to do upgrade operation. Please note that sets of NodeNames and + LabelSelector are ORed. Users must set one and can only set one. + items: + type: string + type: array + timeoutSeconds: + description: TimeoutSeconds limits the duration of the node upgrade + job. Default to 300. If set to 0, we'll use the default value 300. + format: int32 + type: integer + upgradeTool: + description: UpgradeTool is a request to decide use which upgrade + tool. If it is empty, the upgrade job simply use default upgrade + tool keadm to do upgrade operation. + type: string + version: + type: string + type: object + status: + description: Most recently observed status of the NodeUpgradeJob. + properties: + state: + description: 'State represents for the state phase of the NodeUpgradeJob. + There are three possible state values: "", upgrading and completed.' + enum: + - upgrading + - completed + type: string + status: + description: Status contains upgrade Status for each edge node. + items: + description: UpgradeStatus stores the status of Upgrade for each + edge node. + properties: + history: + description: History is the last upgrade result of the edge + node. + properties: + fromVersion: + description: FromVersion is the version which the edge node + is upgraded from. + type: string + historyID: + description: HistoryID is to uniquely identify an Upgrade + Operation. + type: string + reason: + description: Reason is the error reason of Upgrade failure. + If the upgrade is successful, this reason is an empty + string. + type: string + result: + description: Result represents the result of upgrade. + enum: + - upgrade_success + - upgrade_failed_rollback_success + - upgrade_failed_rollback_failed + type: string + toVersion: + description: ToVersion is the version which the edge node + is upgraded to. + type: string + upgradeTime: + description: UpgradeTime is the time of this Upgrade. + type: string + type: object + nodeName: + description: NodeName is the name of edge node. + type: string + state: + description: 'State represents for the upgrade state phase of + the edge node. There are three possible state values: "", + upgrading and completed.' + enum: + - upgrading + - completed + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/01-kubeedge/00_crd_router_v1_rule.yaml b/static/resource/yaml/01-kubeedge/00_crd_router_v1_rule.yaml new file mode 100644 index 0000000..e93930c --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_router_v1_rule.yaml @@ -0,0 +1,65 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: rules.rules.kubeedge.io +spec: + group: rules.kubeedge.io + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + source: + description: | + source is a string value representing where the messages come from. Its + value is the same with ruleendpoint name. For example, my-rest or my-eventbus. + type: string + sourceResource: + description: | + sourceResource is a map representing the resource info of source. For rest + rule-endpoint type its value is {"path":"/test"}. For eventbus ruleendpoint type its + value is {"topic":"","node_name":"edge-node"} + type: object + additionalProperties: + type: string + target: + description: | + target is a string value representing where the messages go to. its value is + the same with ruleendpoint name. For example, my-eventbus or my-rest or my-servicebus. + type: string + targetResource: + description: | + targetResource is a map representing the resource info of target. For rest + rule-endpoint type its value is {"resource":"http://a.com"}. For eventbus ruleendpoint + type its value is {"topic":"/test"}. For servicebus rule-endpoint type its value is + {"path":"/request_path"}. + type: object + additionalProperties: + type: string + required: + - source + - sourceResource + - target + - targetResource + status: + type: object + properties: + successMessages: + type: integer + failMessages: + type: integer + errors: + items: + type: string + type: array + scope: Namespaced + names: + plural: rules + singular: rule + kind: Rule diff --git a/static/resource/yaml/01-kubeedge/00_crd_router_v1_ruleEndpoint.yaml b/static/resource/yaml/01-kubeedge/00_crd_router_v1_ruleEndpoint.yaml new file mode 100644 index 0000000..cb5a1d6 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/00_crd_router_v1_ruleEndpoint.yaml @@ -0,0 +1,43 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: ruleendpoints.rules.kubeedge.io +spec: + group: rules.kubeedge.io + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + ruleEndpointType: + description: | + ruleEndpointType is a string value representing rule-endpoint type. its value is + one of rest/eventbus/servicebus. + type: string + enum: + - rest + - eventbus + - servicebus + properties: + description: | + properties is not required except for servicebus rule-endpoint type. It is a map + value representing rule-endpoint properties. When ruleEndpointType is servicebus, + its value is {"service_port":"8080"}. + type: object + additionalProperties: + type: string + required: + - ruleEndpointType + scope: Namespaced + names: + plural: ruleendpoints + singular: ruleendpoint + kind: RuleEndpoint + shortNames: + - re diff --git a/static/resource/yaml/01-kubeedge/01_rbac_cloudcore.yaml b/static/resource/yaml/01-kubeedge/01_rbac_cloudcore.yaml new file mode 100644 index 0000000..9c8c5d2 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/01_rbac_cloudcore.yaml @@ -0,0 +1,77 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cloudcore + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat +rules: +- apiGroups: [""] + resources: ["nodes", "nodes/status", "serviceaccounts/token", "configmaps", "pods", "pods/status", "secrets", "endpoints", "services", "persistentvolumes", "persistentvolumeclaims"] + verbs: ["get", "list", "watch", "create", "update"] +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "create", "list", "watch"] +- apiGroups: [""] + resources: ["nodes", "nodes/status", "pods/status"] + verbs: ["patch"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["delete"] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update"] +- apiGroups: ["devices.kubeedge.io"] + resources: ["devices", "devicemodels", "devices/status", "devicemodels/status"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["reliablesyncs.kubeedge.io"] + resources: ["objectsyncs", "clusterobjectsyncs", "objectsyncs/status", "clusterobjectsyncs/status"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["rules.kubeedge.io"] + resources: ["rules", "ruleendpoints", "rules/status", "ruleendpoints/status"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["networking.istio.io"] + resources: ["*"] + verbs: ["get", "list", "watch"] +- apiGroups: ["operations.kubeedge.io"] + resources: ["nodeupgradejobs", "nodeupgradejobs/status"] + verbs: ["get", "list", "watch", "update", "patch"] +- apiGroups: ["raven.openyurt.io"] + resources: ["*"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + name: cloudcore + namespace: kubeedge + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cloudcore + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cloudcore +subjects: +- kind: ServiceAccount + name: cloudcore + namespace: kubeedge + + + diff --git a/static/resource/yaml/01-kubeedge/02_configmap_cloudcore.yaml b/static/resource/yaml/01-kubeedge/02_configmap_cloudcore.yaml new file mode 100644 index 0000000..7d24c75 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/02_configmap_cloudcore.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cloudcore + namespace: kubeedge + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat +data: + cloudcore.yaml: | + apiVersion: cloudcore.config.kubeedge.io/v1alpha2 + kind: CloudCore + kubeAPIConfig: + kubeConfig: "" + master: "" + modules: + cloudHub: + advertiseAddress: + - "" + dnsNames: + - "" + nodeLimit: 1000 + tlsCAFile: /etc/kubeedge/tunnel/ca/rootCA.crt + tlsCAKeyFile: /etc/kubeedge/tunnel/ca/rootCA.key + tlsCertFile: /etc/kubeedge/tunnel/certs/edge.crt + tlsPrivateKeyFile: /etc/kubeedge/tunnel/certs/edge.key + unixsocket: + address: unix:///var/lib/kubeedge/kubeedge.sock + enable: true + websocket: + address: 0.0.0.0 + enable: true + port: 10000 + quic: + address: 0.0.0.0 + enable: false + maxIncomingStreams: 10000 + port: 10001 + https: + address: 0.0.0.0 + enable: true + port: 10002 + cloudStream: + enable: true + streamPort: 10003 + tunnelPort: 10004 + tlsTunnelCAFile: /etc/kubeedge/tunnel/ca/rootCA.crt + tlsTunnelCertFile: /etc/kubeedge/tunnel/certs/edge.crt + tlsTunnelPrivateKeyFile: /etc/kubeedge/tunnel/certs/edge.key + tlsStreamCAFile: /etc/kubeedge/stream/ca/streamCA.crt + tlsStreamCertFile: /etc/kubeedge/stream/certs/stream.crt + tlsStreamPrivateKeyFile: /etc/kubeedge/stream/certs/stream.key + dynamicController: + enable: true + router: + enable: false + iptablesManager: + enable: true + mode: internal \ No newline at end of file diff --git a/static/resource/yaml/01-kubeedge/03_deployment_cloudcore.yaml b/static/resource/yaml/01-kubeedge/03_deployment_cloudcore.yaml new file mode 100644 index 0000000..22996af --- /dev/null +++ b/static/resource/yaml/01-kubeedge/03_deployment_cloudcore.yaml @@ -0,0 +1,120 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + name: cloudcore + namespace: kubeedge +spec: + replicas: 1 + selector: + matchLabels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + containers: + # TODO + - image: a526102465/cloudcore:v1.11.2-diplomat + imagePullPolicy: IfNotPresent + name: cloudcore + command: [ "/work/cloudcore" ] + ports: + - containerPort: 10000 + hostPort: 10000 + name: cloudhub + protocol: TCP + - containerPort: 10001 + hostPort: 10001 + name: cloudhub-quic + protocol: TCP + - containerPort: 10002 + hostPort: 10002 + name: cloudhub-https + protocol: TCP + - containerPort: 10003 + hostPort: 10003 + name: cloudstream + protocol: TCP + - containerPort: 10004 + hostPort: 10004 + name: tunnelport + protocol: TCP + resources: + limits: + cpu: 200m + memory: 1Gi + requests: + cpu: 100m + memory: 512Mi + securityContext: + privileged: true + volumeMounts: + - mountPath: /etc/kubeedge/config + name: conf + - mountPath: /etc/kubeedge/tunnel + name: tunnel-certs + - mountPath: /etc/kubeedge/stream + name: stream-certs + - mountPath: /var/lib/kubeedge + name: sock + - mountPath: /etc/localtime + name: host-time + readOnly: true + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + restartPolicy: Always + serviceAccount: cloudcore + serviceAccountName: cloudcore + volumes: + - configMap: + defaultMode: 420 + name: cloudcore + name: conf + - name: stream-certs + secret: + defaultMode: 420 + items: + - key: stream.crt + path: certs/stream.crt + - key: stream.key + path: certs/stream.key + - key: streamCA.crt + path: ca/streamCA.crt + secretName: cloudcore-stream + - name: tunnel-certs + secret: + defaultMode: 420 + items: + - key: edge.crt + path: certs/edge.crt + - key: edge.key + path: certs/edge.key + - key: rootCA.crt + path: ca/rootCA.crt + - key: rootCA.key + path: ca/rootCA.key + secretName: cloudcore + - hostPath: + path: /var/lib/diplomat + type: DirectoryOrCreate + name: sock + - hostPath: + path: /etc/localtime + type: "" + name: host-time \ No newline at end of file diff --git a/static/resource/yaml/01-kubeedge/04_service_cloudcore.yaml b/static/resource/yaml/01-kubeedge/04_service_cloudcore.yaml new file mode 100644 index 0000000..bfb12d9 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/04_service_cloudcore.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + name: cloudcore + namespace: kubeedge +spec: + ports: + - name: cloudhub + port: 10000 + protocol: TCP + targetPort: 10000 + - name: cloudhub-quic + port: 10001 + protocol: TCP + targetPort: 10001 + - name: cloudhub-https + port: 10002 + protocol: TCP + targetPort: 10002 + - name: cloudstream + port: 10003 + protocol: TCP + targetPort: 10003 + - name: tunnelport + port: 10004 + protocol: TCP + targetPort: 10004 + selector: + app: diplomat-kubeedge + kubeedge: cloudcore + diplomat: diplomat + type: ClusterIP \ No newline at end of file diff --git a/static/resource/yaml/01-kubeedge/05_admission.yaml b/static/resource/yaml/01-kubeedge/05_admission.yaml new file mode 100644 index 0000000..c9dcee7 --- /dev/null +++ b/static/resource/yaml/01-kubeedge/05_admission.yaml @@ -0,0 +1,129 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: admission + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat +rules: + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["get", "list", "watch", "create", "update"] + # Rules below is used generate admission service secret + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests"] + verbs: ["get", "list", "create", "delete"] + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/approval"] + verbs: ["create", "update"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "get", "patch"] + - apiGroups: [""] + resources: ["services"] + verbs: ["get"] + - apiGroups: ["devices.kubeedge.io"] + resources: ["devicemodels"] + verbs: ["get", "list"] + - apiGroups: ["rules.kubeedge.io"] + resources: ["rules", "ruleendpoints"] + verbs: ["get", "list"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: admission-role + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat +subjects: + - kind: ServiceAccount + name: admission + namespace: kubeedge +roleRef: + kind: ClusterRole + name: admission + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: admission + namespace: kubeedge + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat + name: admission + namespace: kubeedge +spec: + ports: + - name: admission + port: 443 + selector: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat + name: admission + namespace: kubeedge +spec: + selector: + matchLabels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-admission + kubeedge: admission + diplomat: diplomat + spec: + serviceAccountName: admission + serviceAccount: admission + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + containers: + # TODO + - image: a526102465/admission:v1.11.2-diplomat + imagePullPolicy: IfNotPresent + name: admission + command: [ "/work/admission" ] + args: [ "--ca-cert-file", "/work/certs/ca.crt", "--tls-cert-file","/work/certs/server.crt","--tls-private-key-file","/work/certs/server.key" ] + ports: + - containerPort: 443 + protocol: TCP + volumeMounts: + - mountPath: /work/certs + name: admission-certs + readOnly: true + volumes: + - name: admission-certs + secret: + defaultMode: 420 + secretName: admission-secret \ No newline at end of file diff --git a/static/resource/yaml/02-raven/00_crd_raven_v1alpha1_gateway.yaml b/static/resource/yaml/02-raven/00_crd_raven_v1alpha1_gateway.yaml new file mode 100644 index 0000000..6d3b478 --- /dev/null +++ b/static/resource/yaml/02-raven/00_crd_raven_v1alpha1_gateway.yaml @@ -0,0 +1,163 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: gateways.raven.openyurt.io +spec: + group: raven.openyurt.io + names: + kind: Gateway + listKind: GatewayList + plural: gateways + singular: gateway + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.activeEndpoint.nodeName + name: ActiveEndpoint + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Gateway is the Schema for the gateways API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: GatewaySpec defines the desired state of Gateway + properties: + endpoints: + description: TODO add a field to configure using vxlan or host-gw + for inner gateway communication? Endpoints is a list of available + Endpoint. + items: + description: Endpoint stores all essential data for establishing + the VPN tunnel. TODO add priority field? + properties: + config: + additionalProperties: + type: string + type: object + nodeName: + description: NodeName is the Node hosting this endpoint. + type: string + publicIP: + type: string + underNAT: + type: boolean + required: + - nodeName + type: object + type: array + nodeSelector: + description: NodeSelector is a label query over nodes that managed + by the gateway. The nodes in the same gateway should share same + layer 3 network. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + required: + - endpoints + type: object + status: + description: GatewayStatus defines the observed state of Gateway + properties: + activeEndpoint: + description: ActiveEndpoint is the reference of the active endpoint. + properties: + config: + additionalProperties: + type: string + type: object + nodeName: + description: NodeName is the Node hosting this endpoint. + type: string + publicIP: + type: string + underNAT: + type: boolean + required: + - nodeName + type: object + nodes: + description: Nodes contains all information of nodes managed by Gateway. + items: + description: NodeInfo stores information of node managed by Gateway. + properties: + nodeName: + type: string + privateIP: + type: string + subnets: + items: + type: string + type: array + required: + - nodeName + - privateIP + - subnets + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/static/resource/yaml/02-raven/01_flannel_policy.yaml b/static/resource/yaml/02-raven/01_flannel_policy.yaml new file mode 100644 index 0000000..7f5deab --- /dev/null +++ b/static/resource/yaml/02-raven/01_flannel_policy.yaml @@ -0,0 +1,49 @@ +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: psp.flannel.unprivileged + labels: + diplomat: diplomat + app: diplomat-flannel + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default + seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default + apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default + apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default +spec: + privileged: false + volumes: + - configMap + - secret + - emptyDir + - hostPath + allowedHostPaths: + - pathPrefix: "/etc/cni/net.d" + - pathPrefix: "/etc/kube-flannel" + - pathPrefix: "/run/flannel" + readOnlyRootFilesystem: false + # Users and groups + runAsUser: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + fsGroup: + rule: RunAsAny + # Privilege Escalation + allowPrivilegeEscalation: false + defaultAllowPrivilegeEscalation: false + # Capabilities + allowedCapabilities: ['NET_ADMIN', 'NET_RAW'] + defaultAddCapabilities: [] + requiredDropCapabilities: [] + # Host namespaces + hostPID: false + hostIPC: false + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + # SELinux + seLinux: + # SELinux is unused in CaaSP + rule: 'RunAsAny' diff --git a/static/resource/yaml/02-raven/01_flannel_rbac.yaml b/static/resource/yaml/02-raven/01_flannel_rbac.yaml new file mode 100644 index 0000000..88cbaea --- /dev/null +++ b/static/resource/yaml/02-raven/01_flannel_rbac.yaml @@ -0,0 +1,57 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flannel + labels: + diplomat: diplomat + app: diplomat-flannel +rules: + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: ['psp.flannel.unprivileged'] + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/status + verbs: + - patch +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flannel + labels: + diplomat: diplomat + app: diplomat-flannel +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flannel +subjects: + - kind: ServiceAccount + name: flannel + namespace: diplomat +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: flannel + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-flannel diff --git a/static/resource/yaml/02-raven/01_ravenagent_rbac.yaml b/static/resource/yaml/02-raven/01_ravenagent_rbac.yaml new file mode 100644 index 0000000..fac69b0 --- /dev/null +++ b/static/resource/yaml/02-raven/01_ravenagent_rbac.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: raven-agent-account + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-raven-agent +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: raven-agent-role + labels: + diplomat: diplomat + app: diplomat-raven-agent +rules: + - apiGroups: + - raven.openyurt.io + resources: + - gateways + verbs: + - get + - list + - watch + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: raven-agent-role-binding + labels: + diplomat: diplomat + app: diplomat-raven-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: raven-agent-role +subjects: + - kind: ServiceAccount + name: raven-agent-account + namespace: diplomat diff --git a/static/resource/yaml/02-raven/01_ravencontroller_rbac.yaml b/static/resource/yaml/02-raven/01_ravencontroller_rbac.yaml new file mode 100644 index 0000000..fbaf8a1 --- /dev/null +++ b/static/resource/yaml/02-raven/01_ravencontroller_rbac.yaml @@ -0,0 +1,234 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: raven-controller-manager + namespace: kube-system + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: raven-leader-election-role + namespace: kube-system + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: raven-manager-role + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - crd.projectcalico.org + resources: + - blockaffinities + verbs: + - get + - list + - watch + - apiGroups: + - raven.openyurt.io + resources: + - gateways + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - raven.openyurt.io + resources: + - gateways/finalizers + verbs: + - update + - apiGroups: + - raven.openyurt.io + resources: + - gateways/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: raven-metrics-reader + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: raven-proxy-role + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: raven-leader-election-rolebinding + namespace: kube-system + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: raven-leader-election-role +subjects: + - kind: ServiceAccount + name: raven-controller-manager + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: raven-manager-rolebinding + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: raven-manager-role +subjects: + - kind: ServiceAccount + name: raven-controller-manager + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: raven-proxy-rolebinding + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: raven-proxy-role +subjects: + - kind: ServiceAccount + name: raven-controller-manager + namespace: kube-system diff --git a/static/resource/yaml/02-raven/02_flannel_configmap.yaml b/static/resource/yaml/02-raven/02_flannel_configmap.yaml new file mode 100644 index 0000000..0115062 --- /dev/null +++ b/static/resource/yaml/02-raven/02_flannel_configmap.yaml @@ -0,0 +1,37 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: flannel-cfg + namespace: diplomat + labels: + tier: node + app: diplomat-flannel + diplomat: diplomat +data: + cni-conf.json: | + { + "name": "cbr0", + "cniVersion": "0.3.1", + "plugins": [ + { + "type": "flannel", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] + } + net-conf.json: | + { + "Network": "10.244.0.0/16", + "Backend": { + "Type": "vxlan" + } + } diff --git a/static/resource/yaml/02-raven/02_ravenagent_configmap.yaml b/static/resource/yaml/02-raven/02_ravenagent_configmap.yaml new file mode 100644 index 0000000..7baa848 --- /dev/null +++ b/static/resource/yaml/02-raven/02_ravenagent_configmap.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + vpn-driver: libreswan +kind: ConfigMap +metadata: + name: raven-agent-config + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-raven-agent diff --git a/static/resource/yaml/02-raven/02_ravenagent_secret.yaml b/static/resource/yaml/02-raven/02_ravenagent_secret.yaml new file mode 100644 index 0000000..1ad13c6 --- /dev/null +++ b/static/resource/yaml/02-raven/02_ravenagent_secret.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +data: + vpn-connection-psk: | + MDY0NjU0NTg4OGQwMmVkNzdiNThkMTJiNzI0NDMxMmY3OWYxMDY2Zjg5MWFmYWMzNWEwMW + ExOWMwMjQ3MjcxOTFiNmEyY2U5MTJiMjkzYTIzZjQ5YjNjZGQ1YmQxYjU2NDJiMmYwZmI3 + OGU4MzIyYTFlNTE2OTNmOTZjOGZjODE= +metadata: + name: raven-agent-secret + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-raven-agent +type: Opaque diff --git a/static/resource/yaml/02-raven/02_ravencontroller_secret.yaml b/static/resource/yaml/02-raven/02_ravencontroller_secret.yaml new file mode 100644 index 0000000..67c25af --- /dev/null +++ b/static/resource/yaml/02-raven/02_ravencontroller_secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: raven-webhook-certs + namespace: kube-system + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager diff --git a/static/resource/yaml/02-raven/02_ravencontroller_service.yaml b/static/resource/yaml/02-raven/02_ravencontroller_service.yaml new file mode 100644 index 0000000..35ce32f --- /dev/null +++ b/static/resource/yaml/02-raven/02_ravencontroller_service.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: diplomat-raven-controller-manager + control-plane: controller-manager + diplomat: diplomat + name: raven-controller-manager-metrics-service + namespace: kube-system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + app: diplomat-raven-controller-manager + control-plane: controller-manager + diplomat: diplomat +--- +apiVersion: v1 +kind: Service +metadata: + name: raven-webhook-service + namespace: kube-system + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + app: diplomat-raven-controller-manager + control-plane: controller-manager + diplomat: diplomat \ No newline at end of file diff --git a/static/resource/yaml/02-raven/02_ravencontroller_webhookcfg.yaml b/static/resource/yaml/02-raven/02_ravencontroller_webhookcfg.yaml new file mode 100644 index 0000000..a2d56d9 --- /dev/null +++ b/static/resource/yaml/02-raven/02_ravencontroller_webhookcfg.yaml @@ -0,0 +1,59 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: raven-mutating-webhook-configuration + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +webhooks: + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: raven-webhook-service + namespace: kube-system + path: /mutate-raven-openyurt-io-v1alpha1-gateway + failurePolicy: Fail + name: mgateway.kb.io + rules: + - apiGroups: + - raven.openyurt.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - gateways + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: raven-validating-webhook-configuration + labels: + diplomat: diplomat + app: diplomat-raven-controller-manager +webhooks: + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: raven-webhook-service + namespace: kube-system + path: /validate-raven-openyurt-io-v1alpha1-gateway + failurePolicy: Fail + name: vgateway.kb.io + rules: + - apiGroups: + - raven.openyurt.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - gateways + sideEffects: None diff --git a/static/resource/yaml/02-raven/03_flannel_daemonset.yaml b/static/resource/yaml/02-raven/03_flannel_daemonset.yaml new file mode 100644 index 0000000..86ef326 --- /dev/null +++ b/static/resource/yaml/02-raven/03_flannel_daemonset.yaml @@ -0,0 +1,203 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: flannel-ds + namespace: diplomat + labels: + app: diplomat-flannel + diplomat: diplomat +spec: + selector: + matchLabels: + app: diplomat-flannel + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-flannel + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + - key: node-role.kubernetes.io/agent + operator: DoesNotExist + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-node-critical + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: flannel + initContainers: + - name: install-cni + # TODO + image: a526102465/flannel:v0.14.0-diplomat + command: + - cp + args: + - -f + - /etc/kube-flannel/cni-conf.json + - /etc/cni/net.d/10-flannel.conflist + volumeMounts: + - name: cni + mountPath: /etc/cni/net.d + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + containers: + - name: diplomat-flannel + # TODO + image: a526102465/flannel:v0.14.0-diplomat + command: + - /opt/bin/flanneld + args: + - --ip-masq + - --kube-subnet-mgr + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_ADMIN", "NET_RAW"] + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: run + mountPath: /run/flannel + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + volumes: + - name: run + hostPath: + path: /run/flannel + - name: cni + hostPath: + path: /etc/cni/net.d + - name: flannel-cfg + configMap: + name: flannel-cfg +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: flannel-edge-ds + namespace: diplomat + labels: + app: diplomat-flannel + diplomat: diplomat +spec: + selector: + matchLabels: + app: diplomat-flannel + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-flannel + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + - key: node-role.kubernetes.io/edge + operator: Exists + - key: node-role.kubernetes.io/agent + operator: Exists + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-node-critical + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: flannel + initContainers: + - name: install-cni + # TODO + image: a526102465/flannel:v0.14.0-diplomat + command: + - cp + args: + - -f + - /etc/kube-flannel/cni-conf.json + - /etc/cni/net.d/10-flannel.conflist + volumeMounts: + - name: cni + mountPath: /etc/cni/net.d + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + containers: + - name: diplomat-flannel + # TODO + image: a526102465/flannel:v0.14.0-diplomat + command: + - /opt/bin/flanneld + args: + - --ip-masq + - --kube-subnet-mgr + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_ADMIN", "NET_RAW"] + env: + - name: KUBERNETES_SERVICE_HOST + value: 127.0.0.1 + - name: KUBERNETES_SERVICE_PORT + value: "10550" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: run + mountPath: /run/flannel + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + volumes: + - name: run + hostPath: + path: /run/flannel + - name: cni + hostPath: + path: /etc/cni/net.d + - name: flannel-cfg + configMap: + name: flannel-cfg diff --git a/static/resource/yaml/02-raven/04_ravencontroller_deployment.yaml b/static/resource/yaml/02-raven/04_ravencontroller_deployment.yaml new file mode 100644 index 0000000..19482c7 --- /dev/null +++ b/static/resource/yaml/02-raven/04_ravencontroller_deployment.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: raven-controller-manager + control-plane: controller-manager + diplomat: diplomat + name: raven-controller-manager + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: raven-controller-manager + control-plane: controller-manager + diplomat: diplomat + template: + metadata: + labels: + app: raven-controller-manager + control-plane: controller-manager + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: +# - key: node-role.kubernetes.io/master +# operator: DoesNotExist + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + - key: node-role.kubernetes.io/agent + operator: DoesNotExist + containers: + - args: + - --leader-elect + - --v=2 + command: + - raven-manager + # TODO + image: a526102465/raven-controller:v0.0.1-diplomat + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: raven-controller-manager + serviceAccount: raven-controller-manager + terminationGracePeriodSeconds: 10 + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: raven-webhook-certs diff --git a/static/resource/yaml/02-raven/05_ravenagent_daemonset.yaml b/static/resource/yaml/02-raven/05_ravenagent_daemonset.yaml new file mode 100644 index 0000000..7d017fd --- /dev/null +++ b/static/resource/yaml/02-raven/05_ravenagent_daemonset.yaml @@ -0,0 +1,131 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: raven-agent-edge-ds + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-raven-agent +spec: + selector: + matchLabels: + app: diplomat-raven-agent + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-raven-agent + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + - key: node-role.kubernetes.io/edge + operator: Exists + - key: node-role.kubernetes.io/agent + operator: Exists + containers: + - env: + - name: KUBERNETES_SERVICE_HOST + value: 127.0.0.1 + - name: KUBERNETES_SERVICE_PORT + value: "10550" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: VPN_CONNECTION_PSK + valueFrom: + secretKeyRef: + key: vpn-connection-psk + name: raven-agent-secret + - name: VPN_DRIVER + valueFrom: + configMapKeyRef: + key: vpn-driver + name: raven-agent-config + # TODO + image: a526102465/raven-agent:v0.0.1-diplomat + imagePullPolicy: Always + name: diplomat-raven-agent-edge + securityContext: + privileged: true + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: raven-agent-account + tolerations: + - operator: Exists + updateStrategy: + rollingUpdate: + maxUnavailable: 5% +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: raven-agent-ds + namespace: diplomat + labels: + diplomat: diplomat + app: diplomat-raven-agent +spec: + selector: + matchLabels: + app: diplomat-raven-agent + diplomat: diplomat + template: + metadata: + labels: + app: diplomat-raven-agent + diplomat: diplomat + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + - key: node-role.kubernetes.io/edge + operator: DoesNotExist + - key: node-role.kubernetes.io/agent + operator: DoesNotExist + containers: + - env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: VPN_CONNECTION_PSK + valueFrom: + secretKeyRef: + key: vpn-connection-psk + name: raven-agent-secret + - name: VPN_DRIVER + valueFrom: + configMapKeyRef: + key: vpn-driver + name: raven-agent-config + # TODO + image: a526102465/raven-agent:v0.0.1-diplomat + imagePullPolicy: Always + name: diplomat-raven-agent + securityContext: + privileged: true + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: raven-agent-account + tolerations: + - operator: Exists + updateStrategy: + rollingUpdate: + maxUnavailable: 5% diff --git a/static/static.go b/static/static.go new file mode 100644 index 0000000..800c86f --- /dev/null +++ b/static/static.go @@ -0,0 +1,41 @@ +// Copyright © 2022 99nil. +// +// 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 static + +import "embed" + +const ( + RavenYaml = "resource/yaml/02-raven" + KubeEdgeYaml = "resource/yaml/01-kubeedge" + FlannelBin = "resource/binary/flannel" +) + +// EmbedResource defines the resource directory +//go:embed resource +var EmbedResource embed.FS + +var ( + // CoreCertScript defines the cloudcore cert script + //go:embed resource/scripts/gen-cloudcore-secret.sh + CoreCertScript []byte + + // StreamCertScript defines the stream or cloudcore cert script + //go:embed resource/scripts/gen-stream-secret.sh + StreamCertScript []byte + + // AdmissionCertScript defines the admission cert script + //go:embed resource/scripts/gen-admission-secret.sh + AdmissionCertScript []byte +)