From f6b0e363cad66102fef907c1f5a0cda68689e04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Thu, 18 Jul 2024 22:44:12 +0800 Subject: [PATCH 01/30] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=8Ck8s=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/common/kubernetesClient.go | 23 ++++++ action/common/parser.go | 33 +++++++++ action/config/config.go | 117 ++++++++++++++++++++++++++++++ action/k8s/deploy.go | 38 ++++++++++ action/k8s/install.go | 13 ++++ action/k8s/scale.go | 11 +++ action/k8s/status.go | 11 +++ action/k8s/uninstall.go | 11 +++ action/root.go | 10 ++- config.yml | 23 ++++++ model/config.go | 54 ++++++++++++++ 11 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 action/common/kubernetesClient.go create mode 100644 action/common/parser.go create mode 100644 action/config/config.go create mode 100644 action/k8s/deploy.go create mode 100644 action/k8s/install.go create mode 100644 action/k8s/scale.go create mode 100644 action/k8s/status.go create mode 100644 action/k8s/uninstall.go create mode 100644 config.yml create mode 100644 model/config.go diff --git a/action/common/kubernetesClient.go b/action/common/kubernetesClient.go new file mode 100644 index 0000000..736c565 --- /dev/null +++ b/action/common/kubernetesClient.go @@ -0,0 +1,23 @@ +package common + +import ( + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +// GetClient 根据指定的 kubeconfig 文件路径创建并返回 Kubernetes 客户端 +func GetClient(kubeconfigPath string) (*kubernetes.Clientset, error) { + // 使用 clientcmd 加载指定的 kubeconfig 文件 + config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + if err != nil { + return nil, err + } + + // 创建一个 Kubernetes 客户端 + client, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, err + } + + return client, nil +} diff --git a/action/common/parser.go b/action/common/parser.go new file mode 100644 index 0000000..1e7da8a --- /dev/null +++ b/action/common/parser.go @@ -0,0 +1,33 @@ +package common + +import ( + "fmt" + "github.com/seata/seata-ctl/model" + "gopkg.in/yaml.v3" + "io/ioutil" + "os" +) + +// ReadYMLFile 读取并解析 YAML 文件 +func ReadYMLFile(path string) (model.Config, error) { + var config model.Config + + // 检查文件是否存在 + if _, err := os.Stat(path); os.IsNotExist(err) { + return config, fmt.Errorf("file does not exist: %s", path) + } + + // 读取文件内容 + data, err := ioutil.ReadFile(path) + if err != nil { + return config, fmt.Errorf("failed to read file: %v", err) + } + + // 解析 YAML 内容 + err = yaml.Unmarshal(data, &config) + if err != nil { + return config, fmt.Errorf("failed to unmarshal YAML: %v", err) + } + + return config, nil +} diff --git a/action/config/config.go b/action/config/config.go new file mode 100644 index 0000000..d60f192 --- /dev/null +++ b/action/config/config.go @@ -0,0 +1,117 @@ +package config + +import ( + "fmt" + "github.com/seata/seata-ctl/model" + "github.com/spf13/cobra" + "gopkg.in/yaml.v3" + "log" + "os" +) + +var Path = "/" + +var ConfigCmd = &cobra.Command{ + Use: "config", + Short: "config config path", + Run: func(cmd *cobra.Command, args []string) { + err := createYMLFile(Path) + if err != nil { + println("create config error:", err.Error()) + log.Fatal(err) + } + println("create config success!") + }, +} + +func init() { + ConfigCmd.PersistentFlags().StringVar(&Path, "path", "/", "config config path") +} + +func createSampleConfig() model.Config { + return model.Config{ + Kubernetes: model.Kubernetes{ + Clusters: []model.KubernetesCluster{ + { + Name: "", + KubeConfigPath: "", + YmlPath: "", + }, + }, + }, + Prometheus: model.Prometheus{ + Servers: []model.Server{ + { + Name: "", + Address: "", + Auth: "", + }, + }, + }, + Log: model.Log{ + Clusters: []model.Cluster{ + { + Name: "", + Collection: model.Collection{ + Enable: true, + Local: "", + }, + Analysis: model.Analysis{ + Enable: true, + Local: "", + }, + Display: model.Display{ + DisplayType: "", + Path: "", + Local: "", + }, + }, + }, + }, + } +} + +// 创建yml文件 +func createYMLFile(path string) error { + // 检查路径是否存在 + if _, err := os.Stat(path); os.IsNotExist(err) { + return fmt.Errorf("path does not exist: %s", path) + } + + // 检查文件是否存在 + ymlFilePath := path + "/config.yml" + if _, err := os.Stat(ymlFilePath); err == nil { + return fmt.Errorf("file already exists: %s", path) + } + + // 创建示例配置对象 + config := createSampleConfig() + + // 将配置对象编码为 YAML 格式 + data, err := yaml.Marshal(&config) + if err != nil { + log.Fatalf("Failed to marshal config to YAML: %v", err) + } + + // 将 YAML 数据写入文件 + file, err := os.Create("config.yml") + if err != nil { + log.Fatalf("Failed to create YAML config: %v", err) + } + defer func() { + if err := file.Close(); err != nil { + log.Fatalf("Failed to close config: %v", err) + } + }() + + _, err = file.Write(data) + if err != nil { + log.Fatalf("Failed to write to YAML config: %v", err) + } + fmt.Println("YAML config created successfully") + + //修改path的位置 + Path = path + + return nil +} diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go new file mode 100644 index 0000000..9c41316 --- /dev/null +++ b/action/k8s/deploy.go @@ -0,0 +1,38 @@ +package k8s + +import ( + "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/config" + "github.com/spf13/cobra" +) + +var DeployCmd = &cobra.Command{ + Use: "deploy", + Short: "deploy seata in kubernetes", + Run: func(cmd *cobra.Command, args []string) { + println("create config success!") + }, +} + +var version string + +func init() { + DeployCmd.PersistentFlags().StringVar(&version, "version", "lastest", "crd version") +} + +func deploy(version string) error { + //获取config + Config, err := common.ReadYMLFile(config.Path) + if err != nil { + return err + } + //从config中获取kubeconfig + kubeconfigpath := Config.Kubernetes.Cluster.KubeConfigPath + + //创建客户端 + client, err := common.GetClient(kubeconfigpath) + if err != nil { + return err + } + // 部署 crd 和 controller +} diff --git a/action/k8s/install.go b/action/k8s/install.go new file mode 100644 index 0000000..2dfc2c4 --- /dev/null +++ b/action/k8s/install.go @@ -0,0 +1,13 @@ +package k8s + +import ( + "github.com/spf13/cobra" +) + +var InstallCmd = &cobra.Command{ + Use: "install", + Short: "install k8s crd controller", + Run: func(cmd *cobra.Command, args []string) { + println("create config success!") + }, +} diff --git a/action/k8s/scale.go b/action/k8s/scale.go new file mode 100644 index 0000000..b4c785a --- /dev/null +++ b/action/k8s/scale.go @@ -0,0 +1,11 @@ +package k8s + +import "github.com/spf13/cobra" + +var ScaleCmd = &cobra.Command{ + Use: "scale", + Short: "scale seata in kubernetes", + Run: func(cmd *cobra.Command, args []string) { + println("create config success!") + }, +} diff --git a/action/k8s/status.go b/action/k8s/status.go new file mode 100644 index 0000000..b78b442 --- /dev/null +++ b/action/k8s/status.go @@ -0,0 +1,11 @@ +package k8s + +import "github.com/spf13/cobra" + +var StatusCmd = &cobra.Command{ + Use: "status", + Short: "show seata status in kubernetes", + Run: func(cmd *cobra.Command, args []string) { + println("create config success!") + }, +} diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go new file mode 100644 index 0000000..06b780f --- /dev/null +++ b/action/k8s/uninstall.go @@ -0,0 +1,11 @@ +package k8s + +import "github.com/spf13/cobra" + +var UnDeployCmd = &cobra.Command{ + Use: "undeploy", + Short: "undeploy seata in kubernetes", + Run: func(cmd *cobra.Command, args []string) { + println("create config success!") + }, +} diff --git a/action/root.go b/action/root.go index 3570549..8d45ae4 100644 --- a/action/root.go +++ b/action/root.go @@ -1,9 +1,9 @@ /* * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE config distributed with * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with + * The ASF licenses this config to You under the Apache License, Version 2.0 + * (the "License"); you may not use this config except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 @@ -19,7 +19,9 @@ package action import ( "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/config" "github.com/seata/seata-ctl/action/get" + "github.com/seata/seata-ctl/action/k8s" "github.com/seata/seata-ctl/action/reload" se "github.com/seata/seata-ctl/action/set" del "github.com/seata/seata-ctl/action/try" @@ -29,7 +31,7 @@ import ( func init() { rootCmd.AddCommand(quitCmd, get.GetCmd, del.TryCmd, - reload.ReloadCmd, se.SetCmd) + reload.ReloadCmd, se.SetCmd, config.ConfigCmd, k8s.DeployCmd, k8s.UnDeployCmd, k8s.InstallCmd, k8s.ScaleCmd) rootCmd.SetHelpTemplate(common.GetHelpTmplWithOnlyAvailableCmd()) rootCmd.CompletionOptions = cobra.CompletionOptions{ DisableDefaultCmd: true, diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..256dc02 --- /dev/null +++ b/config.yml @@ -0,0 +1,23 @@ +kubernetes: + clusters: + - name: "" + kubeconfigpath: "" + ymlpath: "" +prometheus: + servers: + - name: "" + address: "" + auth: "" +log: + clusters: + - name: "" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" diff --git a/model/config.go b/model/config.go new file mode 100644 index 0000000..4ae413c --- /dev/null +++ b/model/config.go @@ -0,0 +1,54 @@ +package model + +type Config struct { + Kubernetes Kubernetes `yaml:"kubernetes"` + Prometheus Prometheus `yaml:"prometheus"` + Log Log `yaml:"log"` +} + +type Kubernetes struct { + Cluster KubernetesCluster `yaml:"clusters"` +} + +type Prometheus struct { + Servers []Server `yaml:"servers,omitempty"` +} + +type Log struct { + Clusters []Cluster `yaml:"clusters"` +} + +type KubernetesCluster struct { + Name string `yaml:"name"` + KubeConfigPath string `yaml:"kubeconfigpath"` + YmlPath string `yaml:"ymlpath"` +} + +type Server struct { + Name string `yaml:"name"` + Address string `yaml:"address"` + Auth string `yaml:"auth"` +} + +type Cluster struct { + Name string `yaml:"name"` + Collection Collection `yaml:"collection"` + Analysis Analysis `yaml:"analysis"` + Display Display `yaml:"display"` +} + +type Collection struct { + Enable bool `yaml:"enable"` + Local string `yaml:"local"` +} + +type Analysis struct { + Enable bool `yaml:"enable"` + Local string `yaml:"local"` +} + +type Display struct { + DisplayType string `yaml:"displayType"` + Path string `yaml:"path"` + Local string `yaml:"local"` +} From 29025cbe12ee98db4f0991c4ebfbbac6a34c7f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sun, 21 Jul 2024 19:57:27 +0800 Subject: [PATCH 02/30] =?UTF-8?q?=E2=80=9C=E5=AE=8C=E5=96=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86=20=E6=96=B0=E5=A2=9E=E9=83=A8?= =?UTF-8?q?=E5=88=86k8s=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/common/kubernetesClient.go | 61 +++++++++- action/common/parser.go | 3 +- action/config/config.go | 18 ++- action/k8s/deploy.go | 38 +++--- action/k8s/install.go | 193 +++++++++++++++++++++++++++++- action/k8s/uninstall.go | 31 ++++- config.yml | 8 +- model/config.go | 10 +- 8 files changed, 333 insertions(+), 29 deletions(-) diff --git a/action/common/kubernetesClient.go b/action/common/kubernetesClient.go index 736c565..5cfef18 100644 --- a/action/common/kubernetesClient.go +++ b/action/common/kubernetesClient.go @@ -1,13 +1,50 @@ package common import ( + "github.com/seata/seata-ctl/model" + "gopkg.in/yaml.v3" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + "log" + "os" ) +// GetKubeConfigPath 根据配置文件中的内容,获取kubeConfigPath +func GetKubeConfigPath() (string, error) { + //获取配置文件 + file, err := os.ReadFile("config.yml") + if err != nil { + log.Fatalf("Failed to read config.yml: %v", err) + } + var config model.Config + err = yaml.Unmarshal(file, &config) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + //获取context name + contextName := config.Context.Kubernetes + var contextPath string + //根据context,获取匹配的kubeconfig位置 + for _, cluster := range config.Kubernetes.Cluster { + if cluster.Name == contextName { + contextPath = cluster.KubeConfigPath + } + } + //如果没有找到,返回错误 + if contextPath == "" { + log.Fatalf("Failed to find context in config.yml") + } + return contextPath, err +} + // GetClient 根据指定的 kubeconfig 文件路径创建并返回 Kubernetes 客户端 -func GetClient(kubeconfigPath string) (*kubernetes.Clientset, error) { - // 使用 clientcmd 加载指定的 kubeconfig 文件 +func GetClient() (*kubernetes.Clientset, error) { + // 使用 client 加载指定的 kubeconfig 文件 + kubeconfigPath, err := GetKubeConfigPath() + if err != nil { + return nil, err + } config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) if err != nil { return nil, err @@ -21,3 +58,23 @@ func GetClient(kubeconfigPath string) (*kubernetes.Clientset, error) { return client, nil } + +// GetDynamicClient 根据指定的 kubeconfig 文件路径创建并返回 Kubernetes 动态客户端 +func GetDynamicClient() (*dynamic.DynamicClient, error) { + // 使用 client 加载指定的 kubeconfig 文件 + kubeconfigPath, err := GetKubeConfigPath() + if err != nil { + return nil, err + } + config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + if err != nil { + return nil, err + } + + // 创建动态客户端 + dynamicClient, err := dynamic.NewForConfig(config) + if err != nil { + log.Fatalf("无法创建动态客户端: %v", err) + } + return dynamicClient, nil +} diff --git a/action/common/parser.go b/action/common/parser.go index 1e7da8a..bb18dc4 100644 --- a/action/common/parser.go +++ b/action/common/parser.go @@ -13,7 +13,8 @@ func ReadYMLFile(path string) (model.Config, error) { var config model.Config // 检查文件是否存在 - if _, err := os.Stat(path); os.IsNotExist(err) { + //ymlFilePath := path + "config.yml" + if _, err := os.Stat("config.yml"); os.IsNotExist(err) { return config, fmt.Errorf("file does not exist: %s", path) } diff --git a/action/config/config.go b/action/config/config.go index d60f192..32cc3a3 100644 --- a/action/config/config.go +++ b/action/config/config.go @@ -31,7 +31,7 @@ func init() { func createSampleConfig() model.Config { return model.Config{ Kubernetes: model.Kubernetes{ - Clusters: []model.KubernetesCluster{ + Cluster: []model.KubernetesCluster{ { Name: "", KubeConfigPath: "", @@ -68,6 +68,11 @@ func createSampleConfig() model.Config { }, }, }, + Context: model.Context{ + Kubernetes: "", + Prometheus: "", + Log: "", + }, } } @@ -79,7 +84,7 @@ func createYMLFile(path string) error { } // 检查文件是否存在 - ymlFilePath := path + "/config.yml" + ymlFilePath := path + "config.yml" if _, err := os.Stat(ymlFilePath); err == nil { return fmt.Errorf("file already exists: %s", path) } @@ -115,3 +120,12 @@ func createYMLFile(path string) error { return nil } + +func Test() { + // 将 YAML 数据写入文件 + file, err := os.ReadFile("config.yml") + if err != nil { + log.Fatalf("Failed to read config.yml: %v", err) + } + println(file) +} diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index 9c41316..daaf41b 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -1,8 +1,6 @@ package k8s import ( - "github.com/seata/seata-ctl/action/common" - "github.com/seata/seata-ctl/action/config" "github.com/spf13/cobra" ) @@ -10,7 +8,7 @@ var DeployCmd = &cobra.Command{ Use: "deploy", Short: "deploy seata in kubernetes", Run: func(cmd *cobra.Command, args []string) { - println("create config success!") + deploy() }, } @@ -20,19 +18,23 @@ func init() { DeployCmd.PersistentFlags().StringVar(&version, "version", "lastest", "crd version") } -func deploy(version string) error { - //获取config - Config, err := common.ReadYMLFile(config.Path) - if err != nil { - return err - } - //从config中获取kubeconfig - kubeconfigpath := Config.Kubernetes.Cluster.KubeConfigPath - - //创建客户端 - client, err := common.GetClient(kubeconfigpath) - if err != nil { - return err - } - // 部署 crd 和 controller +func deploy() error { + //获取动态kubeclient + //client, err := common.GetClient() + //if err != nil { + // return err + //} + //操作deploy + //deployment := &appV1.Deployment{ + // ObjectMeta: metaV1.ObjectMeta{ + // Name: "nginx", + // Labels: map[string]string{ + // "app": "nginx", + // }, + // Namespace: "default", + // }, + // Spec: appV1.DeploymentSpec{}, + //} + //deployment, err = client.AppsV1().Deployments("default").Create(context.Background(), deployment, metaV1.CreateOptions{}) + return nil } diff --git a/action/k8s/install.go b/action/k8s/install.go index 2dfc2c4..c14c90e 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -1,13 +1,204 @@ package k8s import ( + "context" + "fmt" + "github.com/seata/seata-ctl/action/common" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "log" ) var InstallCmd = &cobra.Command{ Use: "install", Short: "install k8s crd controller", Run: func(cmd *cobra.Command, args []string) { - println("create config success!") + err := install() + if err != nil { + log.Fatal(err) + } }, } + +// 测试client 连接方法:输出所有的pod +func test() error { + //获取kubeclient + clientset, err := common.GetClient() + if err != nil { + return err + } + //部署crd资源 + pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{}) + if err != nil { + log.Fatalf("Error listing pods: %v", err) + } + + for _, pod := range pods.Items { + fmt.Printf("Namespace: %s, Name: %s\n", pod.Namespace, pod.Name) + } + return nil +} + +func install() error { + //获取动态kubeclient + client, err := common.GetDynamicClient() + if err != nil { + return err + } + + // 定义 CRD 对象 + crd := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "apiextensions.k8s.io/v1", + "kind": "CustomResourceDefinition", + "metadata": map[string]interface{}{ + "name": "crontabs.stable.com", + }, + "spec": map[string]interface{}{ + "group": "stable.com", + "scope": "Namespaced", + "names": map[string]interface{}{ + "plural": "crontabs", + "singular": "crontab", + "kind": "CronTab", + "shortNames": []string{"ct"}, + }, + "versions": []map[string]interface{}{ + { + "name": "v1", + "served": true, + "storage": true, + "schema": map[string]interface{}{ + "openAPIV3Schema": map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "spec": map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "cronSpec": map[string]interface{}{ + "type": "string", + "pattern": "^((\\d+|\\*)(\\/\\d+)?){4}$", + }, + "image": map[string]interface{}{ + "type": "string", + }, + "replicas": map[string]interface{}{ + "type": "integer", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + //crd := &unstructured.Unstructured{ + // Object: map[string]interface{}{ + // "apiVersion": "apiextensions.k8s.io/v1", + // "kind": "CustomResourceDefinition", + // "metadata": map[string]interface{}{ + // "name": "seataservers.operator.seata.apache.org", + // "annotations": map[string]string{ + // "controller-gen.kubebuilder.io/version": "v0.13.0", + // }, + // }, + // "spec": map[string]interface{}{ + // "group": "operator.seata.apache.org", + // "scope": "Namespaced", + // "names": map[string]interface{}{ + // "kind": "SeataServer", + // "listKind": "SeataServerList", + // "plural": "seataservers", + // "singular": "seataserver", + // }, + // "versions": []interface{}{ + // map[string]interface{}{ + // "name": "v1alpha1", + // "schema": map[string]interface{}{ + // "openAPIV3Schema": map[string]interface{}{ + // "description": "SeataServer is the Schema for the seataservers API", + // "properties": map[string]interface{}{ + // "apiVersion": map[string]interface{}{ + // "description": "APIVersion defines the versioned schema of this representation\nof an object. Servers should convert recognized schemas to the latest\ninternal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + // "type": "string", + // }, + // "kind": map[string]interface{}{ + // "description": "Kind is a string value representing the REST resource this\nobject represents. Servers may infer this from the endpoint the client\nsubmits 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": map[string]interface{}{ + // "type": "object", + // }, + // "spec": map[string]interface{}{ + // "description": "SeataServerSpec defines the desired state of SeataServer", + // "properties": map[string]interface{}{ + // "containerName": "seata-server", + // "type": "string", + // }, + // "env": map[string]interface{}{ + // "additionalProperties": map[string]interface{}{ + // "type": "string", + // }, + // "type": "object", + // }, + // "image": map[string]interface{}{ + // "type": "string", + // }, + // "ports": map[string]interface{}{ + // "properties": map[string]interface{}{ + // "consolePort:": map[string]interface{}{ + // "default": "7091", + // "format": "int32", + // "type": "integer", + // }, + // "raftPort:": map[string]interface{}{ + // "default": "9091", + // "format": "int32", + // "type": "integer", + // }, + // "servicePort:": map[string]interface{}{ + // "default": "89091", + // "format": "int32", + // "type": "integer", + // }, + // "type": "string", + // }, + // }, + // }, + // "served": true, + // "storage": true, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + //} + // 获取 GVR(Group Version Resource) + gvr := schema.GroupVersionResource{ + Group: "apiextensions.k8s.io", + Version: "v1", + Resource: "customresourcedefinitions", + } + + // 创建 CRD + result, err := client.Resource(gvr).Create(context.TODO(), crd, metav1.CreateOptions{}) + if err != nil { + if errors.IsAlreadyExists(err) { + log.Printf("CRD 已存在: %v", err) + } else { + log.Fatalf("创建 CRD 失败: %v", err) + } + } + + fmt.Printf("CRD 创建成功,名称: %s\n", result.GetName()) + return nil +} diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index 06b780f..4f9de8a 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -1,11 +1,38 @@ package k8s -import "github.com/spf13/cobra" +import ( + "context" + "github.com/seata/seata-ctl/action/common" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) var UnDeployCmd = &cobra.Command{ Use: "undeploy", Short: "undeploy seata in kubernetes", Run: func(cmd *cobra.Command, args []string) { - println("create config success!") + undeploy() }, } + +func undeploy() error { + //获取动态kubeclient + client, err := common.GetDynamicClient() + if err != nil { + return err + } + + gvr := schema.GroupVersionResource{ + Group: "apiextensions.k8s.io", + Version: "v1", + Resource: "customresourcedefinitions", + } + + //删除 CRD + err = client.Resource(gvr).Delete(context.TODO(), "name", metav1.DeleteOptions{}) + if err != nil { + return err + } + return nil +} diff --git a/config.yml b/config.yml index 256dc02..1955b7d 100644 --- a/config.yml +++ b/config.yml @@ -1,7 +1,7 @@ kubernetes: clusters: - - name: "" - kubeconfigpath: "" + - name: "cluster1" + kubeconfigpath: "/Users/wpy/.kube/config" ymlpath: "" prometheus: servers: @@ -21,3 +21,7 @@ log: displayType: "" path: "" local: "" +context: + kubernetes: "cluster1" + prometheus: "" + log: "" diff --git a/model/config.go b/model/config.go index 4ae413c..921f988 100644 --- a/model/config.go +++ b/model/config.go @@ -4,10 +4,11 @@ type Config struct { Kubernetes Kubernetes `yaml:"kubernetes"` Prometheus Prometheus `yaml:"prometheus"` Log Log `yaml:"log"` + Context Context `yaml:"context"` } type Kubernetes struct { - Cluster KubernetesCluster `yaml:"clusters"` + Cluster []KubernetesCluster `yaml:"clusters"` } type Prometheus struct { @@ -18,6 +19,13 @@ type Log struct { Clusters []Cluster `yaml:"clusters"` } +// Context 依据Context字段选择使用哪个配置 +type Context struct { + Kubernetes string `yaml:"kubernetes"` + Prometheus string `yaml:"prometheus"` + Log string `yaml:"log"` +} + type KubernetesCluster struct { Name string `yaml:"name"` KubeConfigPath string `yaml:"kubeconfigpath"` From ef16a53ab22e9db4ff9176b93dbf04b8810f9ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 12 Aug 2024 12:25:23 +0800 Subject: [PATCH 03/30] =?UTF-8?q?kubernetes=E9=83=A8=E5=88=86=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E5=AE=8C=E6=88=90=EF=BC=8C=E6=8F=90=E4=BA=A4prometheu?= =?UTF-8?q?s=E9=83=A8=E5=88=86demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/k8s/deploy.go | 83 ++++++-- action/k8s/install.go | 367 +++++++++++++++++++++++------------ action/k8s/scale.go | 59 +++++- action/k8s/status.go | 74 ++++++- action/k8s/undeploy.go | 51 +++++ action/k8s/uninstall.go | 41 +++- action/prometheus/metrics.go | 82 ++++++++ action/root.go | 17 +- 8 files changed, 617 insertions(+), 157 deletions(-) create mode 100644 action/k8s/undeploy.go create mode 100644 action/prometheus/metrics.go diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index daaf41b..5ed9776 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -1,40 +1,85 @@ package k8s import ( + "context" + "fmt" + "github.com/seata/seata-ctl/action/common" "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" ) var DeployCmd = &cobra.Command{ Use: "deploy", - Short: "deploy seata in kubernetes", + Short: "deploy seata in k8s", Run: func(cmd *cobra.Command, args []string) { deploy() }, } -var version string +var Name string +var ServiceName string +var Replicas int32 +var Image string +var Namespace string func init() { - DeployCmd.PersistentFlags().StringVar(&version, "version", "lastest", "crd version") + DeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") + DeployCmd.PersistentFlags().StringVar(&ServiceName, "service", "seata-service", "Headless Service name") + DeployCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") + DeployCmd.PersistentFlags().StringVar(&Image, "image", "seata-server", "Image tag") + DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") } func deploy() error { //获取动态kubeclient - //client, err := common.GetClient() - //if err != nil { - // return err - //} - //操作deploy - //deployment := &appV1.Deployment{ - // ObjectMeta: metaV1.ObjectMeta{ - // Name: "nginx", - // Labels: map[string]string{ - // "app": "nginx", - // }, - // Namespace: "default", - // }, - // Spec: appV1.DeploymentSpec{}, - //} - //deployment, err = client.AppsV1().Deployments("default").Create(context.Background(), deployment, metaV1.CreateOptions{}) + client, err := common.GetDynamicClient() + if err != nil { + return err + } + // 获取命名空间 + namespace := Namespace + + // 定义 Custom Resource 的 GroupVersionResource + gvr := schema.GroupVersionResource{ + Group: "operator.seata.apache.org", + Version: "v1alpha1", + Resource: "seataservers", + } + + var seataServer *unstructured.Unstructured + seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) + if seataServer != nil { + fmt.Println("This seata server already exits!") + return nil + } + // 创建 Custom Resource 对象 + seataServer = &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "operator.seata.apache.org/v1alpha1", + "kind": "SeataServer", + "metadata": map[string]interface{}{ + "name": Name, + }, + "spec": map[string]interface{}{ + "image": "seataio/seata-server:latest", + "containerName": Image, + "replicas": Replicas, + "ports": map[string]interface{}{ + "consolePort": 7091, + "raftPort": 9091, + "servicePort": 8091, + }, + "serviceName": ServiceName, + }, + }, + } + // 尝试创建 Custom Resource + _, err = client.Resource(gvr).Namespace(namespace).Create(context.TODO(), seataServer, metav1.CreateOptions{}) + if err != nil { + return err + } + fmt.Printf("CR 创建成功,名称: %s\n", Name) return nil } diff --git a/action/k8s/install.go b/action/k8s/install.go index c14c90e..711a694 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -5,10 +5,19 @@ import ( "fmt" "github.com/seata/seata-ctl/action/common" "github.com/spf13/cobra" + _ "gopkg.in/yaml.v3" + _ "io/ioutil" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + _ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" + _ "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + _ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + _ "k8s.io/apimachinery/pkg/runtime/schema" + _ "k8s.io/client-go/applyconfigurations/meta/v1" "log" ) @@ -16,33 +25,19 @@ var InstallCmd = &cobra.Command{ Use: "install", Short: "install k8s crd controller", Run: func(cmd *cobra.Command, args []string) { - err := install() + err := InstallCRD() if err != nil { log.Fatal(err) } + //err = DeploymentController() + //if err != nil { + // log.Fatal(err) + //} }, } -// 测试client 连接方法:输出所有的pod -func test() error { - //获取kubeclient - clientset, err := common.GetClient() - if err != nil { - return err - } - //部署crd资源 - pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{}) - if err != nil { - log.Fatalf("Error listing pods: %v", err) - } - - for _, pod := range pods.Items { - fmt.Printf("Namespace: %s, Name: %s\n", pod.Namespace, pod.Name) - } - return nil -} - -func install() error { +// InstallCRD 部署CRD +func InstallCRD() error { //获取动态kubeclient client, err := common.GetDynamicClient() if err != nil { @@ -55,41 +50,203 @@ func install() error { "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", "metadata": map[string]interface{}{ - "name": "crontabs.stable.com", + "name": "seataservers.operator.seata.apache.org", }, "spec": map[string]interface{}{ - "group": "stable.com", - "scope": "Namespaced", + "group": "operator.seata.apache.org", "names": map[string]interface{}{ - "plural": "crontabs", - "singular": "crontab", - "kind": "CronTab", - "shortNames": []string{"ct"}, + "kind": "SeataServer", + "listKind": "SeataServerList", + "plural": "seataservers", + "singular": "seataserver", }, + "scope": "Namespaced", "versions": []map[string]interface{}{ { - "name": "v1", + "name": "v1alpha1", "served": true, "storage": true, "schema": map[string]interface{}{ "openAPIV3Schema": map[string]interface{}{ - "type": "object", + "description": "SeataServer is the Schema for the seataservers API", + "type": "object", "properties": map[string]interface{}{ - "spec": map[string]interface{}{ + "apiVersion": map[string]interface{}{ + "description": "APIVersion defines the versioned schema of this representation", + "type": "string", + }, + "kind": map[string]interface{}{ + "description": "Kind is a string value representing the REST resource this", + "type": "string", + }, + "metadata": map[string]interface{}{ "type": "object", + }, + "spec": map[string]interface{}{ + "description": "SeataServerSpec defines the desired state of SeataServer", + "type": "object", "properties": map[string]interface{}{ - "cronSpec": map[string]interface{}{ + "containerName": map[string]interface{}{ + "default": "seata-server", "type": "string", - "pattern": "^((\\d+|\\*)(\\/\\d+)?){4}$", + }, + "env": map[string]interface{}{ + "additionalProperties": map[string]interface{}{ + "type": "string", + }, + "type": "object", }, "image": map[string]interface{}{ "type": "string", }, + "ports": map[string]interface{}{ + "properties": map[string]interface{}{ + "consolePort": map[string]interface{}{ + "default": 7091, + "format": "int32", + "type": "integer", + }, + "raftPort": map[string]interface{}{ + "default": 9091, + "format": "int32", + "type": "integer", + }, + "servicePort": map[string]interface{}{ + "default": 8091, + "format": "int32", + "type": "integer", + }, + }, + "type": "object", + }, "replicas": map[string]interface{}{ - "type": "integer", + "default": 1, + "format": "int32", + "minimum": 1, + "type": "integer", }, + //"resources": map[string]interface{}{ + // "description": "ResourceRequirements describes the compute resource requirements.", + // "properties": map[string]interface{}{ + // "claims": map[string]interface{}{ + // "description": "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers.", + // "items": map[string]interface{}{ + // "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + // "properties": map[string]interface{}{ + // "name": map[string]interface{}{ + // "description": "Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.", + // "type": "string", + // }, + // }, + // "required": "name", + // "type": "object", + // }, + // "type":"array", + // "x-k8s-list-map-keys": "name", + // "x-k8s-list-type": "map", + // }, + // "limits": map[string]interface{}{ + // "additionalProperties": map[string]interface{}{ + // "anyOf": map[string]interface{}{ + // //"type": "integer", + // "type": "string", + // }, + // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + // "x-k8s-int-or-string": "true", + // }, + // "description": "Limits describes the maximum amount of compute resources", + // "type": "object", + // }, + // "requests": map[string]interface{}{ + // "additionalProperties": map[string]interface{}{ + // "anyOf": map[string]interface{}{ + // //"type": "integer", + // "type": "string", + // }, + // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + // "x-k8s-int-or-string": "true", + // }, + // "description": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container,it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits.More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers.", + // "type": "object", + // }, + // }, + // "type": "object", + //}, + "serviceName": map[string]interface{}{ + "default": "seata-server", + "type": "string", + }, + //"store": map[string]interface{}{ + // "properties": map[string]interface{}{ + // "resources": map[string]interface{}{ + // "description": "ResourceRequirements describes the compute resource requirements.", + // "properties": map[string]interface{}{ + // "claims": map[string]interface{}{ + // "description": "Claims lists the names of resources, defined", + // "items": map[string]interface{}{ + // "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + // "properties": map[string]interface{}{ + // "name": map[string]interface{}{ + // "description": "Name must match the name of one entry in pod.spec.resourceClaims", + // "type": "string", + // }, + // }, + // "required": "name", + // "type": "object", + // }, + // "type": "array", + // "x-k8s-list-map-keys": "name", + // "x-k8s-list-type": "map", + // }, + // "limits": map[string]interface{}{ + // "additionalProperties": map[string]interface{}{ + // "anyOf": map[string]interface{}{ + // "type": "integer", + // //"type":"string", + // }, + // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + // "x-k8s-int-or-string": "true", + // }, + // "description": "Limits describes the maximum amount of compute resources", + // "type": "object", + // }, + // "requests": map[string]interface{}{ + // "additionalProperties": map[string]interface{}{ + // "anyOf": map[string]interface{}{ + // "type": "integer", + // //"type":"string", + // }, + // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + // "x-k8s-int-or-string": "true", + // }, + // "description": "Requests describes the minimum amount of compute", + // "type": "object", + // }, + // "type": "object", + // }, + // "required": "resources", + // "type": "object", + // }, }, }, + "status": map[string]interface{}{ + "description": "SeataServerStatus defines the observed state of SeataServer", + "properties": map[string]interface{}{ + "readyReplicas": map[string]interface{}{ + "format": "int32", + "type": "integer", + }, + "replicas": map[string]interface{}{ + "format": "int32", + "type": "integer", + }, + "synchronized": map[string]interface{}{ + "type": "boolean", + }, + }, + //"required": "replicas", + "type": "object", + }, }, }, }, @@ -98,98 +255,13 @@ func install() error { }, }, } - - //crd := &unstructured.Unstructured{ - // Object: map[string]interface{}{ - // "apiVersion": "apiextensions.k8s.io/v1", - // "kind": "CustomResourceDefinition", - // "metadata": map[string]interface{}{ - // "name": "seataservers.operator.seata.apache.org", - // "annotations": map[string]string{ - // "controller-gen.kubebuilder.io/version": "v0.13.0", - // }, - // }, - // "spec": map[string]interface{}{ - // "group": "operator.seata.apache.org", - // "scope": "Namespaced", - // "names": map[string]interface{}{ - // "kind": "SeataServer", - // "listKind": "SeataServerList", - // "plural": "seataservers", - // "singular": "seataserver", - // }, - // "versions": []interface{}{ - // map[string]interface{}{ - // "name": "v1alpha1", - // "schema": map[string]interface{}{ - // "openAPIV3Schema": map[string]interface{}{ - // "description": "SeataServer is the Schema for the seataservers API", - // "properties": map[string]interface{}{ - // "apiVersion": map[string]interface{}{ - // "description": "APIVersion defines the versioned schema of this representation\nof an object. Servers should convert recognized schemas to the latest\ninternal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - // "type": "string", - // }, - // "kind": map[string]interface{}{ - // "description": "Kind is a string value representing the REST resource this\nobject represents. Servers may infer this from the endpoint the client\nsubmits 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": map[string]interface{}{ - // "type": "object", - // }, - // "spec": map[string]interface{}{ - // "description": "SeataServerSpec defines the desired state of SeataServer", - // "properties": map[string]interface{}{ - // "containerName": "seata-server", - // "type": "string", - // }, - // "env": map[string]interface{}{ - // "additionalProperties": map[string]interface{}{ - // "type": "string", - // }, - // "type": "object", - // }, - // "image": map[string]interface{}{ - // "type": "string", - // }, - // "ports": map[string]interface{}{ - // "properties": map[string]interface{}{ - // "consolePort:": map[string]interface{}{ - // "default": "7091", - // "format": "int32", - // "type": "integer", - // }, - // "raftPort:": map[string]interface{}{ - // "default": "9091", - // "format": "int32", - // "type": "integer", - // }, - // "servicePort:": map[string]interface{}{ - // "default": "89091", - // "format": "int32", - // "type": "integer", - // }, - // "type": "string", - // }, - // }, - // }, - // "served": true, - // "storage": true, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - //} - // 获取 GVR(Group Version Resource) gvr := schema.GroupVersionResource{ Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions", } - // 创建 CRD + //创建 CRD result, err := client.Resource(gvr).Create(context.TODO(), crd, metav1.CreateOptions{}) if err != nil { if errors.IsAlreadyExists(err) { @@ -202,3 +274,58 @@ func install() error { fmt.Printf("CRD 创建成功,名称: %s\n", result.GetName()) return nil } + +// DeploymentController 部署Seata-controller +func DeploymentController() error { + //获取kubeclient + clientset, err := common.GetClient() + //if err != nil { + // return err + //} + // 创建Deployment对象 + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "seata-k8s-controller-manager", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: func(i int32) *int32 { return &i }(1), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "seata-k8s-controller-manager", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "seata-k8s-controller-manager", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "seata-k8s-controller-manager", + Image: "apache/seata-controller:latest", + Ports: []corev1.ContainerPort{ + { + ContainerPort: 80, + }, + }, + }, + }, + }, + }, + }, + } + + // 使用客户端创建Deployment + _, err = clientset.AppsV1().Deployments("default").Create(context.TODO(), deployment, metav1.CreateOptions{}) + if err != nil { + log.Fatalf("Error creating deployment: %s", err.Error()) + } + fmt.Println("Deployment created successfully") + return err +} diff --git a/action/k8s/scale.go b/action/k8s/scale.go index b4c785a..b7e9735 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -1,11 +1,64 @@ package k8s -import "github.com/spf13/cobra" +import ( + "context" + "fmt" + "github.com/seata/seata-ctl/action/common" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" +) var ScaleCmd = &cobra.Command{ Use: "scale", - Short: "scale seata in kubernetes", + Short: "scale seata in k8s", Run: func(cmd *cobra.Command, args []string) { - println("create config success!") + err := scale() + if err != nil { + fmt.Println(err) + } }, } + +func init() { + ScaleCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") + ScaleCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") + ScaleCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") +} + +func scale() error { + //获取动态kubeclient + client, err := common.GetDynamicClient() + if err != nil { + return err + } + // 获取命名空间 + namespace := Namespace + + // 定义 Custom Resource 的 GroupVersionResource + gvr := schema.GroupVersionResource{ + Group: "operator.seata.apache.org", + Version: "v1alpha1", + Resource: "seataservers", + } + + var seataServer *unstructured.Unstructured + seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) + if seataServer == nil { + fmt.Println("This seata server does not exits!") + return nil + } + + //修改 + seataServer.Object["spec"].(map[string]interface{})["replicas"] = Replicas + + // 尝试创建 Custom Resource + _, err = client.Resource(gvr).Namespace(namespace).Update(context.TODO(), seataServer, metav1.UpdateOptions{}) + + if err != nil { + return err + } + fmt.Printf("CR 修改成功,名称: %s\n", Name) + return nil +} diff --git a/action/k8s/status.go b/action/k8s/status.go index b78b442..f452fac 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -1,11 +1,79 @@ package k8s -import "github.com/spf13/cobra" +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "github.com/seata/seata-ctl/action/common" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "log" +) var StatusCmd = &cobra.Command{ Use: "status", - Short: "show seata status in kubernetes", + Short: "show seata status in k8s", Run: func(cmd *cobra.Command, args []string) { - println("create config success!") + err := status() + if err != nil { + fmt.Println(err) + } }, } + +func init() { + StatusCmd.PersistentFlags().StringVar(&Name, "name", "list", "Seataserver name") + StatusCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") +} + +func status() error { + //获取动态kubeclient + client, err := common.GetDynamicClient() + if err != nil { + return err + } + // 获取命名空间 + namespace := Namespace + + // 定义 Custom Resource 的 GroupVersionResource + gvr := schema.GroupVersionResource{ + Group: "operator.seata.apache.org", + Version: "v1alpha1", + Resource: "seataservers", + } + + var jsonData []byte + if Name == "list" { + fmt.Printf("1") + var seataServerList *unstructured.UnstructuredList + seataServerList, err = client.Resource(gvr).Namespace(namespace).List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + jsonData, err = seataServerList.MarshalJSON() + if err != nil { + log.Fatalf("Error marshalling Unstructured object to JSON: %v", err) + } + } else { + var seataServer *unstructured.Unstructured + seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) + if err != nil { + return err + } + jsonData, err = seataServer.MarshalJSON() + if err != nil { + log.Fatalf("Error marshalling Unstructured object to JSON: %v", err) + } + } + //更美观的格式化输出 + var prettyJSON bytes.Buffer + err = json.Indent(&prettyJSON, jsonData, "", "") + if err != nil { + log.Fatalf("Error indenting JSON: %v", err) + } + fmt.Printf("%s\n", prettyJSON.Bytes()) + return nil +} diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go new file mode 100644 index 0000000..f7e9fde --- /dev/null +++ b/action/k8s/undeploy.go @@ -0,0 +1,51 @@ +package k8s + +import ( + "context" + "fmt" + "github.com/seata/seata-ctl/action/common" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var UnDeployCmd = &cobra.Command{ + Use: "undeploy", + Short: "deploy seata in k8s", + Run: func(cmd *cobra.Command, args []string) { + err := undeploy() + if err != nil { + fmt.Println(err) + } + }, +} + +func init() { + UnDeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") + UnDeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") +} + +func undeploy() error { + //获取动态kubeclient + client, err := common.GetDynamicClient() + if err != nil { + return err + } + // 获取命名空间 + namespace := Namespace + + // 定义 Custom Resource 的 GroupVersionResource + gvr := schema.GroupVersionResource{ + Group: "operator.seata.apache.org", + Version: "v1alpha1", + Resource: "seataservers", + } + + //删除 + err = client.Resource(gvr).Namespace(namespace).Delete(context.TODO(), Name, metav1.DeleteOptions{}) + if err != nil { + return err + } + fmt.Printf("CR 删除成功,名称: %s\n", Name) + return nil +} diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index 4f9de8a..b365bdd 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -2,37 +2,60 @@ package k8s import ( "context" + "fmt" "github.com/seata/seata-ctl/action/common" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "log" ) -var UnDeployCmd = &cobra.Command{ - Use: "undeploy", - Short: "undeploy seata in kubernetes", +var UnInstallCmd = &cobra.Command{ + Use: "uninstall", + Short: "uninstall seata in k8s", Run: func(cmd *cobra.Command, args []string) { - undeploy() + err := UninstallCRD() + if err != nil { + log.Fatal(err) + } + //err = UnDeploymentController() + //if err != nil { + // log.Fatal(err) + //} }, } -func undeploy() error { +// UninstallCRD 删除CRD定义 +func UninstallCRD() error { //获取动态kubeclient client, err := common.GetDynamicClient() if err != nil { return err } - gvr := schema.GroupVersionResource{ Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions", } - //删除 CRD - err = client.Resource(gvr).Delete(context.TODO(), "name", metav1.DeleteOptions{}) + err = client.Resource(gvr).Delete(context.TODO(), "seataservers.operator.seata.apache.org", metav1.DeleteOptions{}) if err != nil { - return err + log.Fatalf("删除CRD 失败: %v", err) } + fmt.Printf("删除CRD成功,名称: %s\n", "seataservers.operator.seata.apache.org") return nil } + +// UnDeploymentController 删除Seata-controller +func UnDeploymentController() error { + clientset, err := common.GetClient() + if err != nil { + return err + } + err = clientset.AppsV1().Deployments("default").Delete(context.TODO(), "seata-k8s-controller-manager", metav1.DeleteOptions{}) + if err != nil { + log.Fatalf("Error creating deployment: %s", err.Error()) + } + fmt.Println("Deployment created successfully") + return err +} diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go new file mode 100644 index 0000000..374f434 --- /dev/null +++ b/action/prometheus/metrics.go @@ -0,0 +1,82 @@ +package prometheus + +import ( + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "io/ioutil" + "net/http" + "net/url" +) + +var MetricsCmd = &cobra.Command{ + Use: "metrics", + Short: "show prometheus metrics", + Run: func(cmd *cobra.Command, args []string) { + err := metrics() + if err != nil { + fmt.Println(err) + } + }, +} + +var Name string +var Target string +var Region string + +func init() { + MetricsCmd.PersistentFlags().StringVar(&Name, "name", "prometheus", "Prometheus name") + MetricsCmd.PersistentFlags().StringVar(&Target, "target", "default", "Namespace name") + MetricsCmd.PersistentFlags().StringVar(&Region, "region", "default", "Namespace name") +} + +// QueryResult 用于解析 Prometheus 查询结果的结构体 +type QueryResult struct { + Status string `json:"status"` + Data struct { + ResultType string `json:"resultType"` + Result []struct { + Metric map[string]string `json:"metric"` + Value []interface{} `json:"value"` + } `json:"result"` + } `json:"data"` +} + +func metrics() error { + // 构建查询的 URL + prometheusURL := "http://localhost:9090" + u, _ := url.ParseRequestURI(prometheusURL) + u.Path = "/api/v1/query" + // 添加查询参数 + q := u.Query() + query := "seata.tm.commit" + q.Set("query", query) + u.RawQuery = q.Encode() + + // 发送 HTTP GET 请求 + resp, err := http.Get(u.String()) + if err != nil { + return err + } + defer resp.Body.Close() + + // 读取响应体 + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + // 解析响应体为 QueryResult 结构 + var result QueryResult + err = json.Unmarshal(body, &result) + if err != nil { + return err + } + return err + //// 检查 Prometheus 查询状态 + //if result.Status != "success" { + // return nil, fmt.Errorf("query failed: %s", result.Status) + //} + // + //return &result, nil +} diff --git a/action/root.go b/action/root.go index 8d45ae4..7695354 100644 --- a/action/root.go +++ b/action/root.go @@ -29,9 +29,20 @@ import ( ) func init() { - rootCmd.AddCommand(quitCmd, - get.GetCmd, del.TryCmd, - reload.ReloadCmd, se.SetCmd, config.ConfigCmd, k8s.DeployCmd, k8s.UnDeployCmd, k8s.InstallCmd, k8s.ScaleCmd) + rootCmd.AddCommand( + quitCmd, + get.GetCmd, + del.TryCmd, + reload.ReloadCmd, + se.SetCmd, + config.ConfigCmd, + k8s.DeployCmd, + k8s.UnDeployCmd, + k8s.InstallCmd, + k8s.UnInstallCmd, + k8s.StatusCmd, + k8s.ScaleCmd, + ) rootCmd.SetHelpTemplate(common.GetHelpTmplWithOnlyAvailableCmd()) rootCmd.CompletionOptions = cobra.CompletionOptions{ DisableDefaultCmd: true, From f53552b68dc8f69bb8eee42101b68c532bdef349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sun, 1 Sep 2024 21:25:58 +0800 Subject: [PATCH 04/30] =?UTF-8?q?prometheus=20=E9=83=A8=E5=88=86=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/k8s/deploy.go | 33 +- action/k8s/install.go | 35 +- action/prometheus/metrics.go | 145 ++++++-- action/root.go | 2 + cmd/root.go | 15 +- config.yml | 6 +- operator.seata.apache.org_seataservers.yaml | 390 ++++++++++++++++++++ 7 files changed, 574 insertions(+), 52 deletions(-) create mode 100644 operator.seata.apache.org_seataservers.yaml diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index 5ed9776..1cc55e2 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -60,18 +60,45 @@ func deploy() error { "apiVersion": "operator.seata.apache.org/v1alpha1", "kind": "SeataServer", "metadata": map[string]interface{}{ - "name": Name, + "name": Name, + "namespace": "default", }, "spec": map[string]interface{}{ - "image": "seataio/seata-server:latest", "containerName": Image, + "image": "seataio/seata-server:latest", "replicas": Replicas, + "serviceName": ServiceName, + "env": map[string]interface{}{ + "SEATA_ENV": "prod", + "SEATA_LOG_LEVEL": "info", + }, "ports": map[string]interface{}{ "consolePort": 7091, "raftPort": 9091, "servicePort": 8091, }, - "serviceName": ServiceName, + "resources": map[string]interface{}{ + "limits": map[string]interface{}{ + "cpu": "500m", + "memory": "1Gi", + }, + "requests": map[string]interface{}{ + "cpu": "250m", + "memory": "512Mi", + }, + }, + "store": map[string]interface{}{ + "resources": map[string]interface{}{ + "limits": map[string]interface{}{ + "cpu": "500m", + "memory": "1Gi", + }, + "requests": map[string]interface{}{ + "cpu": "250m", + "memory": "512Mi", + }, + }, + }, }, }, } diff --git a/action/k8s/install.go b/action/k8s/install.go index 711a694..a4d6beb 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -19,23 +19,48 @@ import ( _ "k8s.io/apimachinery/pkg/runtime/schema" _ "k8s.io/client-go/applyconfigurations/meta/v1" "log" + "os/exec" + "strings" ) var InstallCmd = &cobra.Command{ Use: "install", Short: "install k8s crd controller", Run: func(cmd *cobra.Command, args []string) { - err := InstallCRD() - if err != nil { - log.Fatal(err) - } - //err = DeploymentController() + //err := InstallCRD() //if err != nil { // log.Fatal(err) //} + err := DeploymentController() + if err != nil { + log.Fatal(err) + } + output, err := executeCommand("kubectl apply -f operator.seata.apache.org_seataservers.yaml") + if err != nil { + log.Println(output) + } }, } +func executeCommand(input string) (string, error) { + // 将用户输入的命令分割成命令和参数 + args := strings.Fields(input) + if len(args) == 0 { + return "", fmt.Errorf("no command provided") + } + + // 使用 exec.Command 执行命令 + cmd := exec.Command(args[0], args[1:]...) + + // 获取命令的输出 + output, err := cmd.CombinedOutput() + if err != nil { + return "", err + } + + return string(output), nil +} + // InstallCRD 部署CRD func InstallCRD() error { //获取动态kubeclient diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 374f434..004242d 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -3,10 +3,17 @@ package prometheus import ( "encoding/json" "fmt" + "github.com/gdamore/tcell/v2" + "github.com/rivo/tview" + "github.com/seata/seata-ctl/model" "github.com/spf13/cobra" + "gopkg.in/yaml.v3" "io/ioutil" + "log" "net/http" "net/url" + "os" + "time" ) var MetricsCmd = &cobra.Command{ @@ -20,14 +27,27 @@ var MetricsCmd = &cobra.Command{ }, } -var Name string var Target string -var Region string func init() { - MetricsCmd.PersistentFlags().StringVar(&Name, "name", "prometheus", "Prometheus name") - MetricsCmd.PersistentFlags().StringVar(&Target, "target", "default", "Namespace name") - MetricsCmd.PersistentFlags().StringVar(&Region, "region", "default", "Namespace name") + MetricsCmd.PersistentFlags().StringVar(&Target, "target", "seata_transaction_summary", "Namespace name") +} + +func metrics() error { + prometheusURL, err := getPrometheusAddress() + if err != nil { + return err + } + result, err := queryPrometheusMetric(prometheusURL, Target) + if err != nil { + log.Fatalf("Error querying Prometheus: %v", err) + } + err = generateView(result) + if err != nil { + log.Fatalf("Error generating view: %v", err) + return err + } + return nil } // QueryResult 用于解析 Prometheus 查询结果的结构体 @@ -42,41 +62,98 @@ type QueryResult struct { } `json:"data"` } -func metrics() error { - // 构建查询的 URL - prometheusURL := "http://localhost:9090" - u, _ := url.ParseRequestURI(prometheusURL) - u.Path = "/api/v1/query" - // 添加查询参数 - q := u.Query() - query := "seata.tm.commit" - q.Set("query", query) - u.RawQuery = q.Encode() +func getPrometheusAddress() (string, error) { + file, err := os.ReadFile("config.yml") + if err != nil { + log.Fatalf("Failed to read config.yml: %v", err) + } + var config model.Config + err = yaml.Unmarshal(file, &config) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + contextName := config.Context.Prometheus + var contextPath string + for _, server := range config.Prometheus.Servers { + if server.Name == contextName { + contextPath = server.Address + } + } + if contextPath == "" { + log.Fatalf("Failed to find context in config.yml") + return "", err + } + return contextPath, err +} + +func generateView(result *PrometheusResponse) error { + app := tview.NewApplication() + table := tview.NewTable(). + SetBorders(true). + SetFixed(1, 0) + headers := []string{"Metric", "Timestamp", "Value"} + for i, header := range headers { + table.SetCell(0, i, tview.NewTableCell(header). + SetTextColor(tview.TrueColor). + SetAlign(tview.AlignCenter). + SetSelectable(false)) + } + for rowIndex, res := range result.Data.Result { + value := res.Value + if len(value) == 2 { + timestamp, ok := value[0].(float64) + if !ok { + log.Println("Invalid timestamp format") + continue + } + val, ok := value[1].(string) + if !ok { + log.Println("Invalid value format") + continue + } + timeStamp := time.Unix(int64(timestamp), 0).UTC() + table.SetCell(rowIndex+1, 0, tview.NewTableCell(Target). + SetTextColor(tcell.ColorWhite). + SetAlign(tview.AlignLeft)) + table.SetCell(rowIndex+1, 1, tview.NewTableCell(timeStamp.Format(time.RFC3339)). + SetTextColor(tcell.ColorWhite). + SetAlign(tview.AlignCenter)) + table.SetCell(rowIndex+1, 2, tview.NewTableCell(val). + SetTextColor(tcell.ColorWhite). + SetAlign(tview.AlignRight)) + } + } + if err := app.SetRoot(table, true).Run(); err != nil { + log.Fatalf("Error starting tview application: %v", err) + } + return nil +} - // 发送 HTTP GET 请求 - resp, err := http.Get(u.String()) +type PrometheusResponse struct { + Status string `json:"status"` + Data struct { + ResultType string `json:"resultType"` + Result []struct { + Metric map[string]string `json:"metric"` + Value []interface{} `json:"value"` + } `json:"result"` + } `json:"data"` +} + +func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, error) { + queryURL := fmt.Sprintf("%s/api/v1/query?query=%s", prometheusURL, url.QueryEscape(query)) + resp, err := http.Get(queryURL) if err != nil { - return err + return nil, fmt.Errorf("error querying Prometheus: %w", err) } defer resp.Body.Close() - - // 读取响应体 body, err := ioutil.ReadAll(resp.Body) if err != nil { - return err + return nil, fmt.Errorf("error reading response body: %w", err) } - - // 解析响应体为 QueryResult 结构 - var result QueryResult - err = json.Unmarshal(body, &result) - if err != nil { - return err + var result PrometheusResponse + if err := json.Unmarshal(body, &result); err != nil { + return nil, fmt.Errorf("error unmarshalling JSON: %w", err) } - return err - //// 检查 Prometheus 查询状态 - //if result.Status != "success" { - // return nil, fmt.Errorf("query failed: %s", result.Status) - //} - // - //return &result, nil + return &result, nil } diff --git a/action/root.go b/action/root.go index 7695354..105b861 100644 --- a/action/root.go +++ b/action/root.go @@ -22,6 +22,7 @@ import ( "github.com/seata/seata-ctl/action/config" "github.com/seata/seata-ctl/action/get" "github.com/seata/seata-ctl/action/k8s" + "github.com/seata/seata-ctl/action/prometheus" "github.com/seata/seata-ctl/action/reload" se "github.com/seata/seata-ctl/action/set" del "github.com/seata/seata-ctl/action/try" @@ -42,6 +43,7 @@ func init() { k8s.UnInstallCmd, k8s.StatusCmd, k8s.ScaleCmd, + prometheus.MetricsCmd, ) rootCmd.SetHelpTemplate(common.GetHelpTmplWithOnlyAvailableCmd()) rootCmd.CompletionOptions = cobra.CompletionOptions{ diff --git a/cmd/root.go b/cmd/root.go index c59204d..4f5c32e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -73,15 +73,16 @@ func Execute() { os.Exit(0) } } - address := seata.GetAuth().GetAddress() - err := seata.GetAuth().Login() - if err != nil { - fmt.Println("login failed!") - os.Exit(1) - } + //address := seata.GetAuth().GetAddress() + //err := seata.GetAuth().Login() + //if err != nil { + // fmt.Println("login failed!") + // os.Exit(1) + //} + var err error for { - printPrompt(address) + //printPrompt(address) err = common.ReadArgs(os.Stdin) if err != nil { fmt.Println(err) diff --git a/config.yml b/config.yml index 1955b7d..0468007 100644 --- a/config.yml +++ b/config.yml @@ -5,8 +5,8 @@ kubernetes: ymlpath: "" prometheus: servers: - - name: "" - address: "" + - name: "prometheus" + address: "http://localhost:9092" auth: "" log: clusters: @@ -23,5 +23,5 @@ log: local: "" context: kubernetes: "cluster1" - prometheus: "" + prometheus: "prometheus" log: "" diff --git a/operator.seata.apache.org_seataservers.yaml b/operator.seata.apache.org_seataservers.yaml new file mode 100644 index 0000000..3750c99 --- /dev/null +++ b/operator.seata.apache.org_seataservers.yaml @@ -0,0 +1,390 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: seataservers.operator.seata.apache.org +spec: + group: operator.seata.apache.org + names: + kind: SeataServer + listKind: SeataServerList + plural: seataservers + singular: seataserver + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SeataServer is the Schema for the seataservers 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: SeataServerSpec defines the desired state of SeataServer + properties: + containerName: + default: seata-server + type: string + env: + additionalProperties: + type: string + type: object + image: + type: string + ports: + properties: + consolePort: + default: 7091 + format: int32 + type: integer + raftPort: + default: 9091 + format: int32 + type: integer + servicePort: + default: 8091 + format: int32 + type: integer + type: object + replicas: + default: 1 + format: int32 + minimum: 1 + type: integer + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceName: + default: seata-server + type: string + store: + properties: + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - resources + type: object + required: + - image + - store + type: object + status: + description: SeataServerStatus defines the observed state of SeataServer + properties: + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + synchronized: + type: boolean + required: + - replicas + - synchronized + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: seataservers.operator.seata.apache.org +spec: + group: operator.seata.apache.org + names: + kind: SeataServer + listKind: SeataServerList + plural: seataservers + singular: seataserver + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SeataServer is the Schema for the seataservers 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: SeataServerSpec defines the desired state of SeataServer + properties: + containerName: + default: seata-server + type: string + env: + additionalProperties: + type: string + type: object + image: + type: string + ports: + properties: + consolePort: + default: 7091 + format: int32 + type: integer + raftPort: + default: 9091 + format: int32 + type: integer + servicePort: + default: 8091 + format: int32 + type: integer + type: object + replicas: + default: 1 + format: int32 + minimum: 1 + type: integer + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceName: + default: seata-server + type: string + store: + properties: + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - resources + type: object + required: + - image + - store + type: object + status: + description: SeataServerStatus defines the observed state of SeataServer + properties: + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + synchronized: + type: boolean + required: + - replicas + - synchronized + type: object + type: object + served: true + storage: true + subresources: + status: {} From 6eee43c5da69ed4742b076d8a769774d99d6e7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sun, 1 Sep 2024 21:26:58 +0800 Subject: [PATCH 05/30] =?UTF-8?q?prometheus=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qodana.yaml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 qodana.yaml diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 0000000..215d808 --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,29 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +#Specify Qodana linter for analysis (Applied in CI/CD pipeline) +linter: jetbrains/qodana-go:latest From 76a2c9cf1dcaed19ad64e1f4c3a0ad8a853a4f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 27 Sep 2024 01:53:58 +0800 Subject: [PATCH 06/30] fix --- action/config/config.go | 10 - action/k8s/deploy.go | 14 +- action/k8s/install.go | 298 ++---------------- action/k8s/scale.go | 4 +- action/k8s/status.go | 4 +- action/k8s/undeploy.go | 4 +- action/k8s/uninstall.go | 16 +- .../kubernetesClient.go => k8s/utils/file.go} | 26 +- action/k8s/utils/http.go | 170 ++++++++++ action/k8s/utils/request.go | 31 ++ action/k8s/utils/yaml.go | 47 +++ action/log/log.go | 131 ++++++++ action/log/utils/impl/elasticsearch.go | 134 ++++++++ action/log/utils/impl/local.go | 66 ++++ action/log/utils/impl/loki.go | 92 ++++++ action/log/utils/interface.go | 11 + action/prometheus/metrics.go | 117 ++++--- config.yml | 49 +-- go.mod | 68 +++- go.sum | 156 +++++++-- model/config.go | 3 + seata.json | 1 + ...apache.org_seataservers.yaml => seata.yaml | 0 23 files changed, 1028 insertions(+), 424 deletions(-) rename action/{common/kubernetesClient.go => k8s/utils/file.go} (67%) create mode 100644 action/k8s/utils/http.go create mode 100644 action/k8s/utils/request.go create mode 100644 action/k8s/utils/yaml.go create mode 100644 action/log/log.go create mode 100644 action/log/utils/impl/elasticsearch.go create mode 100644 action/log/utils/impl/local.go create mode 100644 action/log/utils/impl/loki.go create mode 100644 action/log/utils/interface.go create mode 100644 seata.json rename operator.seata.apache.org_seataservers.yaml => seata.yaml (100%) diff --git a/action/config/config.go b/action/config/config.go index 32cc3a3..68af909 100644 --- a/action/config/config.go +++ b/action/config/config.go @@ -117,15 +117,5 @@ func createYMLFile(path string) error { //修改path的位置 Path = path - return nil } - -func Test() { - // 将 YAML 数据写入文件 - file, err := os.ReadFile("config.yml") - if err != nil { - log.Fatalf("Failed to read config.yml: %v", err) - } - println(file) -} diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index 1cc55e2..a8437da 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -3,7 +3,7 @@ package k8s import ( "context" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -34,7 +34,7 @@ func init() { func deploy() error { //获取动态kubeclient - client, err := common.GetDynamicClient() + client, err := utils.GetDynamicClient() if err != nil { return err } @@ -68,10 +68,10 @@ func deploy() error { "image": "seataio/seata-server:latest", "replicas": Replicas, "serviceName": ServiceName, - "env": map[string]interface{}{ - "SEATA_ENV": "prod", - "SEATA_LOG_LEVEL": "info", - }, + //"env": map[string]interface{}{ + // "SEATA_ENV": "prod", + // "SEATA_LOG_LEVEL": "info", + //}, "ports": map[string]interface{}{ "consolePort": 7091, "raftPort": 9091, @@ -107,6 +107,6 @@ func deploy() error { if err != nil { return err } - fmt.Printf("CR 创建成功,名称: %s\n", Name) + fmt.Printf("CR install success,name: %s\n", Name) return nil } diff --git a/action/k8s/install.go b/action/k8s/install.go index a4d6beb..828491a 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -3,311 +3,57 @@ package k8s import ( "context" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" _ "gopkg.in/yaml.v3" _ "io/ioutil" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" _ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/api/errors" _ "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" _ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" _ "k8s.io/apimachinery/pkg/runtime/schema" _ "k8s.io/client-go/applyconfigurations/meta/v1" "log" - "os/exec" - "strings" ) var InstallCmd = &cobra.Command{ Use: "install", - Short: "install k8s crd controller", + Short: "Install Kubernetes CRD controller", Run: func(cmd *cobra.Command, args []string) { - //err := InstallCRD() - //if err != nil { - // log.Fatal(err) - //} - err := DeploymentController() + err := DeployCRD() if err != nil { log.Fatal(err) } - output, err := executeCommand("kubectl apply -f operator.seata.apache.org_seataservers.yaml") - if err != nil { - log.Println(output) - } + // err = DeployController() + // if err != nil { + // log.Fatal(err) + // } }, } -func executeCommand(input string) (string, error) { - // 将用户输入的命令分割成命令和参数 - args := strings.Fields(input) - if len(args) == 0 { - return "", fmt.Errorf("no command provided") - } - - // 使用 exec.Command 执行命令 - cmd := exec.Command(args[0], args[1:]...) +const CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" +const FilePath = "seata.yaml" - // 获取命令的输出 - output, err := cmd.CombinedOutput() - if err != nil { - return "", err - } - - return string(output), nil -} - -// InstallCRD 部署CRD -func InstallCRD() error { - //获取动态kubeclient - client, err := common.GetDynamicClient() +// DeployCRD deploys the custom resource definition. +func DeployCRD() error { + res, err := utils.CreateRequest(CreateCrdPath, FilePath) + fmt.Println(res) if err != nil { return err } - - // 定义 CRD 对象 - crd := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "apiextensions.k8s.io/v1", - "kind": "CustomResourceDefinition", - "metadata": map[string]interface{}{ - "name": "seataservers.operator.seata.apache.org", - }, - "spec": map[string]interface{}{ - "group": "operator.seata.apache.org", - "names": map[string]interface{}{ - "kind": "SeataServer", - "listKind": "SeataServerList", - "plural": "seataservers", - "singular": "seataserver", - }, - "scope": "Namespaced", - "versions": []map[string]interface{}{ - { - "name": "v1alpha1", - "served": true, - "storage": true, - "schema": map[string]interface{}{ - "openAPIV3Schema": map[string]interface{}{ - "description": "SeataServer is the Schema for the seataservers API", - "type": "object", - "properties": map[string]interface{}{ - "apiVersion": map[string]interface{}{ - "description": "APIVersion defines the versioned schema of this representation", - "type": "string", - }, - "kind": map[string]interface{}{ - "description": "Kind is a string value representing the REST resource this", - "type": "string", - }, - "metadata": map[string]interface{}{ - "type": "object", - }, - "spec": map[string]interface{}{ - "description": "SeataServerSpec defines the desired state of SeataServer", - "type": "object", - "properties": map[string]interface{}{ - "containerName": map[string]interface{}{ - "default": "seata-server", - "type": "string", - }, - "env": map[string]interface{}{ - "additionalProperties": map[string]interface{}{ - "type": "string", - }, - "type": "object", - }, - "image": map[string]interface{}{ - "type": "string", - }, - "ports": map[string]interface{}{ - "properties": map[string]interface{}{ - "consolePort": map[string]interface{}{ - "default": 7091, - "format": "int32", - "type": "integer", - }, - "raftPort": map[string]interface{}{ - "default": 9091, - "format": "int32", - "type": "integer", - }, - "servicePort": map[string]interface{}{ - "default": 8091, - "format": "int32", - "type": "integer", - }, - }, - "type": "object", - }, - "replicas": map[string]interface{}{ - "default": 1, - "format": "int32", - "minimum": 1, - "type": "integer", - }, - //"resources": map[string]interface{}{ - // "description": "ResourceRequirements describes the compute resource requirements.", - // "properties": map[string]interface{}{ - // "claims": map[string]interface{}{ - // "description": "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers.", - // "items": map[string]interface{}{ - // "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", - // "properties": map[string]interface{}{ - // "name": map[string]interface{}{ - // "description": "Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.", - // "type": "string", - // }, - // }, - // "required": "name", - // "type": "object", - // }, - // "type":"array", - // "x-k8s-list-map-keys": "name", - // "x-k8s-list-type": "map", - // }, - // "limits": map[string]interface{}{ - // "additionalProperties": map[string]interface{}{ - // "anyOf": map[string]interface{}{ - // //"type": "integer", - // "type": "string", - // }, - // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - // "x-k8s-int-or-string": "true", - // }, - // "description": "Limits describes the maximum amount of compute resources", - // "type": "object", - // }, - // "requests": map[string]interface{}{ - // "additionalProperties": map[string]interface{}{ - // "anyOf": map[string]interface{}{ - // //"type": "integer", - // "type": "string", - // }, - // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - // "x-k8s-int-or-string": "true", - // }, - // "description": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container,it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits.More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers.", - // "type": "object", - // }, - // }, - // "type": "object", - //}, - "serviceName": map[string]interface{}{ - "default": "seata-server", - "type": "string", - }, - //"store": map[string]interface{}{ - // "properties": map[string]interface{}{ - // "resources": map[string]interface{}{ - // "description": "ResourceRequirements describes the compute resource requirements.", - // "properties": map[string]interface{}{ - // "claims": map[string]interface{}{ - // "description": "Claims lists the names of resources, defined", - // "items": map[string]interface{}{ - // "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", - // "properties": map[string]interface{}{ - // "name": map[string]interface{}{ - // "description": "Name must match the name of one entry in pod.spec.resourceClaims", - // "type": "string", - // }, - // }, - // "required": "name", - // "type": "object", - // }, - // "type": "array", - // "x-k8s-list-map-keys": "name", - // "x-k8s-list-type": "map", - // }, - // "limits": map[string]interface{}{ - // "additionalProperties": map[string]interface{}{ - // "anyOf": map[string]interface{}{ - // "type": "integer", - // //"type":"string", - // }, - // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - // "x-k8s-int-or-string": "true", - // }, - // "description": "Limits describes the maximum amount of compute resources", - // "type": "object", - // }, - // "requests": map[string]interface{}{ - // "additionalProperties": map[string]interface{}{ - // "anyOf": map[string]interface{}{ - // "type": "integer", - // //"type":"string", - // }, - // "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - // "x-k8s-int-or-string": "true", - // }, - // "description": "Requests describes the minimum amount of compute", - // "type": "object", - // }, - // "type": "object", - // }, - // "required": "resources", - // "type": "object", - // }, - }, - }, - "status": map[string]interface{}{ - "description": "SeataServerStatus defines the observed state of SeataServer", - "properties": map[string]interface{}{ - "readyReplicas": map[string]interface{}{ - "format": "int32", - "type": "integer", - }, - "replicas": map[string]interface{}{ - "format": "int32", - "type": "integer", - }, - "synchronized": map[string]interface{}{ - "type": "boolean", - }, - }, - //"required": "replicas", - "type": "object", - }, - }, - }, - }, - }, - }, - }, - }, - } - gvr := schema.GroupVersionResource{ - Group: "apiextensions.k8s.io", - Version: "v1", - Resource: "customresourcedefinitions", - } - - //创建 CRD - result, err := client.Resource(gvr).Create(context.TODO(), crd, metav1.CreateOptions{}) - if err != nil { - if errors.IsAlreadyExists(err) { - log.Printf("CRD 已存在: %v", err) - } else { - log.Fatalf("创建 CRD 失败: %v", err) - } - } - - fmt.Printf("CRD 创建成功,名称: %s\n", result.GetName()) return nil } -// DeploymentController 部署Seata-controller -func DeploymentController() error { - //获取kubeclient - clientset, err := common.GetClient() - //if err != nil { - // return err - //} - // 创建Deployment对象 +// DeployController deploys the controller for the custom resource. +func DeployController() error { + // Get Kubernetes client + clientset, err := utils.GetClient() + if err != nil { + return fmt.Errorf("error getting clientset: %v", err) + } + // Create Deployment object deployment := &appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ Kind: "Deployment", @@ -345,8 +91,6 @@ func DeploymentController() error { }, }, } - - // 使用客户端创建Deployment _, err = clientset.AppsV1().Deployments("default").Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { log.Fatalf("Error creating deployment: %s", err.Error()) diff --git a/action/k8s/scale.go b/action/k8s/scale.go index b7e9735..0940043 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -3,7 +3,7 @@ package k8s import ( "context" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -29,7 +29,7 @@ func init() { func scale() error { //获取动态kubeclient - client, err := common.GetDynamicClient() + client, err := utils.GetDynamicClient() if err != nil { return err } diff --git a/action/k8s/status.go b/action/k8s/status.go index f452fac..d82a71b 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -5,7 +5,7 @@ import ( "context" "encoding/json" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -31,7 +31,7 @@ func init() { func status() error { //获取动态kubeclient - client, err := common.GetDynamicClient() + client, err := utils.GetDynamicClient() if err != nil { return err } diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go index f7e9fde..4bbbf25 100644 --- a/action/k8s/undeploy.go +++ b/action/k8s/undeploy.go @@ -3,7 +3,7 @@ package k8s import ( "context" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -27,7 +27,7 @@ func init() { func undeploy() error { //获取动态kubeclient - client, err := common.GetDynamicClient() + client, err := utils.GetDynamicClient() if err != nil { return err } diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index b365bdd..fa7ea7d 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -3,7 +3,7 @@ package k8s import ( "context" "fmt" - "github.com/seata/seata-ctl/action/common" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -18,17 +18,17 @@ var UnInstallCmd = &cobra.Command{ if err != nil { log.Fatal(err) } - //err = UnDeploymentController() - //if err != nil { - // log.Fatal(err) - //} + err = UnDeploymentController() + if err != nil { + log.Fatal(err) + } }, } // UninstallCRD 删除CRD定义 func UninstallCRD() error { //获取动态kubeclient - client, err := common.GetDynamicClient() + client, err := utils.GetDynamicClient() if err != nil { return err } @@ -42,13 +42,13 @@ func UninstallCRD() error { if err != nil { log.Fatalf("删除CRD 失败: %v", err) } - fmt.Printf("删除CRD成功,名称: %s\n", "seataservers.operator.seata.apache.org") + fmt.Printf("delete CRD success,名称: %s\n", "seataservers.operator.seata.apache.org") return nil } // UnDeploymentController 删除Seata-controller func UnDeploymentController() error { - clientset, err := common.GetClient() + clientset, err := utils.GetClient() if err != nil { return err } diff --git a/action/common/kubernetesClient.go b/action/k8s/utils/file.go similarity index 67% rename from action/common/kubernetesClient.go rename to action/k8s/utils/file.go index 5cfef18..c03ed6f 100644 --- a/action/common/kubernetesClient.go +++ b/action/k8s/utils/file.go @@ -1,4 +1,4 @@ -package common +package utils import ( "github.com/seata/seata-ctl/model" @@ -10,9 +10,9 @@ import ( "os" ) -// GetKubeConfigPath 根据配置文件中的内容,获取kubeConfigPath +// GetKubeConfigPath retrieves the kubeConfigPath based on the contents of the config file. func GetKubeConfigPath() (string, error) { - //获取配置文件 + // Read the configuration file file, err := os.ReadFile("config.yml") if err != nil { log.Fatalf("Failed to read config.yml: %v", err) @@ -22,25 +22,25 @@ func GetKubeConfigPath() (string, error) { if err != nil { log.Fatalf("Unmarshal: %v", err) } - //获取context name + // Retrieve the context name contextName := config.Context.Kubernetes var contextPath string - //根据context,获取匹配的kubeconfig位置 + // Find the matching kubeconfig path based on the context for _, cluster := range config.Kubernetes.Cluster { if cluster.Name == contextName { contextPath = cluster.KubeConfigPath } } - //如果没有找到,返回错误 + // If no matching context is found, return an error if contextPath == "" { log.Fatalf("Failed to find context in config.yml") } return contextPath, err } -// GetClient 根据指定的 kubeconfig 文件路径创建并返回 Kubernetes 客户端 +// GetClient creates and returns a Kubernetes client based on the specified kubeconfig file path. func GetClient() (*kubernetes.Clientset, error) { - // 使用 client 加载指定的 kubeconfig 文件 + // Load the kubeconfig file using the client kubeconfigPath, err := GetKubeConfigPath() if err != nil { return nil, err @@ -50,7 +50,7 @@ func GetClient() (*kubernetes.Clientset, error) { return nil, err } - // 创建一个 Kubernetes 客户端 + // Create a Kubernetes client client, err := kubernetes.NewForConfig(config) if err != nil { return nil, err @@ -59,9 +59,9 @@ func GetClient() (*kubernetes.Clientset, error) { return client, nil } -// GetDynamicClient 根据指定的 kubeconfig 文件路径创建并返回 Kubernetes 动态客户端 +// GetDynamicClient creates and returns a Kubernetes dynamic client based on the specified kubeconfig file path. func GetDynamicClient() (*dynamic.DynamicClient, error) { - // 使用 client 加载指定的 kubeconfig 文件 + // Load the kubeconfig file using the client kubeconfigPath, err := GetKubeConfigPath() if err != nil { return nil, err @@ -71,10 +71,10 @@ func GetDynamicClient() (*dynamic.DynamicClient, error) { return nil, err } - // 创建动态客户端 + // Create a dynamic client dynamicClient, err := dynamic.NewForConfig(config) if err != nil { - log.Fatalf("无法创建动态客户端: %v", err) + log.Fatalf("Failed to create dynamic client: %v", err) } return dynamicClient, nil } diff --git a/action/k8s/utils/http.go b/action/k8s/utils/http.go new file mode 100644 index 0000000..5011f68 --- /dev/null +++ b/action/k8s/utils/http.go @@ -0,0 +1,170 @@ +package utils + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/clientcmd/api" + "net/http" + "strings" +) + +type ContextType string + +const ( + Json ContextType = "application/json" +) + +// ContextInfo is a structure to hold client certificate, key, CA certificate, API server URL, and content type. +type ContextInfo struct { + ClientCert string + ClientKey string + CACert string + APIServer string + ContentType ContextType +} + +// LoadKubeConfig loads the kubeconfig from the provided path and filename +func LoadKubeConfig(kubeconfigFullPath string) (*api.Config, error) { + // Read the kubeconfig file + kubeconfigBytes, err := ioutil.ReadFile(kubeconfigFullPath) + if err != nil { + return nil, fmt.Errorf("failed to read kubeconfig file: %v", err) + } + // Convert the kubeconfig file content into the Config struct + config, err := clientcmd.Load(kubeconfigBytes) + if err != nil { + return nil, fmt.Errorf("failed to load kubeconfig: %v", err) + } + return config, nil +} + +// GetContextInfo extracts the client certificate, key, CA certificate, API server URL, and content type +// from the provided *api.Config for the current context. +func GetContextInfo(config *api.Config) (*ContextInfo, error) { + // Get the current context name + currentContext := config.CurrentContext + if currentContext == "" { + return nil, fmt.Errorf("no current context is set") + } + // Get the current context object + context, ok := config.Contexts[currentContext] + if !ok { + return nil, fmt.Errorf("context %s not found", currentContext) + } + // Get the cluster object + cluster, ok := config.Clusters[context.Cluster] + if !ok { + return nil, fmt.Errorf("cluster %s not found", context.Cluster) + } + // Get the user object + authInfo, ok := config.AuthInfos[context.AuthInfo] + if !ok { + return nil, fmt.Errorf("auth info %s not found", context.AuthInfo) + } + // Extract the certificate and API server information + clientCert := authInfo.ClientCertificate + clientKey := authInfo.ClientKey + caCert := cluster.CertificateAuthority + apiServer := cluster.Server + // Content type for API request + contentType := Json + // Check if all required fields are present + if clientCert == "" || clientKey == "" || caCert == "" || apiServer == "" { + missingFields := []string{} + if clientCert == "" { + missingFields = append(missingFields, "client certificate") + } + if clientKey == "" { + missingFields = append(missingFields, "client key") + } + if caCert == "" { + missingFields = append(missingFields, "CA certificate") + } + if apiServer == "" { + missingFields = append(missingFields, "API server") + } + return nil, fmt.Errorf("missing required fields: %s", strings.Join(missingFields, ", ")) + } + // Return the ContextInfo struct + return &ContextInfo{ + ClientCert: clientCert, + ClientKey: clientKey, + CACert: caCert, + APIServer: apiServer, + ContentType: contentType, + }, nil +} + +// sendPostRequest sends a POST request to the Kubernetes API server to create a custom resource definition (CRD) +func sendPostRequest(context *ContextInfo, createCrdPath string, filePath string) (string, error) { + certFile := context.ClientCert + keyFile := context.ClientKey + caCertFile := context.CACert + url := context.APIServer + createCrdPath + contentType := context.ContentType + + // Load client certificate and key + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return "", fmt.Errorf("failed to load certificate and key: %v", err) + } + + // Read CA certificate + caCert, err := ioutil.ReadFile(caCertFile) + if err != nil { + return "", fmt.Errorf("failed to read CA certificate: %v", err) + } + caCertPool := x509.NewCertPool() + if ok := caCertPool.AppendCertsFromPEM(caCert); !ok { + return "", fmt.Errorf("failed to append CA certificate") + } + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + } + transport := &http.Transport{TLSClientConfig: tlsConfig} + client := &http.Client{Transport: transport} + + // Read data from file + data, err := ioutil.ReadFile(filePath) + if err != nil { + return "", fmt.Errorf("failed to read data file: %v", err) + } + + // Create a POST request + req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) + if err != nil { + return "", fmt.Errorf("failed to create request: %v", err) + } + + // Set content type + req.Header.Set("Content-Type", string(contentType)) + + // Send the request + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + // Read response body + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed to read response: %v", err) + } + + // Return appropriate response based on status code + if resp.StatusCode == http.StatusCreated { + return "create seata crd success", nil + } + if resp.StatusCode == http.StatusConflict { + return "seata crd already exists", nil + } else { + return "error: " + string(body), err + } +} diff --git a/action/k8s/utils/request.go b/action/k8s/utils/request.go new file mode 100644 index 0000000..6a21c61 --- /dev/null +++ b/action/k8s/utils/request.go @@ -0,0 +1,31 @@ +package utils + +import "fmt" + +func CreateRequest(createCrdPath string, filePath string) (string, error) { + + kubeConfigPath, err := GetKubeConfigPath() + if err != nil { + return "", fmt.Errorf("failed to get kubeconfig path: %v", err) + } + kubeConfig, err := LoadKubeConfig(kubeConfigPath) + if err != nil { + return "", fmt.Errorf("failed to load kubeconfig file: %v", err) + } + contextInfo, err := GetContextInfo(kubeConfig) + if err != nil { + return "", fmt.Errorf("failed to get context info: %v", err) + } + + filePath, err = ConvertAndSaveYamlToJSON(filePath) + + if err != nil { + return "", fmt.Errorf("failed to save yaml: %v", err) + } + + res, err := sendPostRequest(contextInfo, createCrdPath, filePath) + if err != nil { + return res, fmt.Errorf("failed to send post request: %v", err) + } + return res, nil +} diff --git a/action/k8s/utils/yaml.go b/action/k8s/utils/yaml.go new file mode 100644 index 0000000..ace8721 --- /dev/null +++ b/action/k8s/utils/yaml.go @@ -0,0 +1,47 @@ +package utils + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "sigs.k8s.io/yaml" +) + +// ConvertAndSaveYamlToJSON takes a YAML file path and a target file name, converts it to JSON, +// and does not convert if the JSON file already exists. +func ConvertAndSaveYamlToJSON(targetName string) (string, error) { + // Get the original file directory, filename, and extension + dir, file := filepath.Split(targetName) + fileName := file[:len(file)-len(filepath.Ext(file))] // Remove the original file extension + if targetName == "" { + targetName = fileName // If no target name is provided, use the original YAML file name + } + newFilePath := filepath.Join(dir, fileName+".json") // Generate the new JSON file path + + // Check if the JSON file already exists + if _, err := os.Stat(newFilePath); err == nil { + return newFilePath, nil + } else if !os.IsNotExist(err) { + return "", fmt.Errorf("failed to check JSON file existence: %v", err) + } + + // Read the YAML file + yamlData, err := ioutil.ReadFile(targetName) + if err != nil { + return "", fmt.Errorf("failed to read YAML file: %v", err) + } + + // Convert the YAML to JSON + jsonData, err := yaml.YAMLToJSON(yamlData) + if err != nil { + return "", fmt.Errorf("failed to convert YAML to JSON: %v", err) + } + + // Write the converted JSON data to the new file + err = ioutil.WriteFile(newFilePath, jsonData, 0644) + if err != nil { + return "", fmt.Errorf("failed to write JSON file: %v", err) + } + return newFilePath, nil +} diff --git a/action/log/log.go b/action/log/log.go new file mode 100644 index 0000000..e834057 --- /dev/null +++ b/action/log/log.go @@ -0,0 +1,131 @@ +package log + +import ( + "errors" + "fmt" + "github.com/seata/seata-ctl/action/log/utils" + "github.com/seata/seata-ctl/action/log/utils/impl" + "github.com/seata/seata-ctl/model" + "github.com/spf13/cobra" + "gopkg.in/yaml.v3" + "log" + "os" +) + +var LogCmd = &cobra.Command{ + Use: "log", + Short: "get seata log", + Run: func(cmd *cobra.Command, args []string) { + err := getLog() + if err != nil { + fmt.Println(err) + } + }, +} + +var Level string +var TransactionId string +var Expression string + +func init() { + LogCmd.PersistentFlags().StringVar(&Level, "level", "ERROR", "seata log level") + LogCmd.PersistentFlags().StringVar(&TransactionId, "Id", "", "seata transaction id") + LogCmd.PersistentFlags().StringVar(&Expression, "Expression", "", "seata expression") +} + +func getLog() error { + context, currency, err := getContext() + if err != nil { + return err + } + + param := make(map[string]interface{}) + param["currency"] = currency + + client, param, err := getClientAndParams(context, param) + if err != nil { + return err + } + + res, err := client.QueryLogs(param) + if err != nil { + return err + } + + err = showLogInfo(res) + if err != nil { + return err + } + + return nil +} + +func getContext() (*model.Cluster, *utils.Currency, error) { + file, err := os.ReadFile("config.yml") + if err != nil { + log.Fatalf("Failed to read config.yml: %v", err) + } + var config model.Config + err = yaml.Unmarshal(file, &config) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + contextName := config.Context.Log + for _, cluster := range config.Log.Clusters { + if cluster.Name == contextName { + currency := utils.Currency{ + Address: cluster.Address, + Source: cluster.Source, + } + return &cluster, ¤cy, nil + } + } + return nil, nil, fmt.Errorf("failed to find context in config.yml") +} + +func getClientAndParams(cluster *model.Cluster, param map[string]interface{}) (utils.LogQuery, map[string]interface{}, error) { + logType := cluster.Types + switch logType { + case "ElasticSearch": + { + param["ElasticSearch"] = impl.ElasticsearchParams{ + LogLevel: logType, + TransactionId: TransactionId, + } + return &impl.Elasticsearch{}, param, nil + } + case "Loki": + { + param["Loki"] = impl.LokiParams{ + Expression: Expression, + } + return &impl.Loki{}, nil, nil + } + case "Local": + { + param["Local"] = impl.LokiParams{ + Expression: Expression, + } + return &impl.Local{}, nil, nil + } + default: + { + return nil, nil, fmt.Errorf("unknown log type: %s", logType) + } + } +} + +func showLogInfo(logs []string) error { + if len(logs) == 0 { + return errors.New("no logs to display") + } + fmt.Println("=========== LOG ENTRIES ===========") + for i, logEntry := range logs { + fmt.Printf("Log #%d:\n", i+1) + fmt.Println("------------------------------") + fmt.Printf("%s\n", logEntry) + fmt.Println("------------------------------") + } + fmt.Println("=========== END OF LOGS ===========") + return nil +} diff --git a/action/log/utils/impl/elasticsearch.go b/action/log/utils/impl/elasticsearch.go new file mode 100644 index 0000000..86f922a --- /dev/null +++ b/action/log/utils/impl/elasticsearch.go @@ -0,0 +1,134 @@ +package impl + +import ( + "context" + "encoding/json" + "fmt" + "github.com/seata/seata-ctl/action/log/utils" + "log" + "strings" + "time" + + elasticsearch "github.com/elastic/go-elasticsearch/v8" +) + +type LogEntry struct { + Timestamp time.Time `json:"timestamp,omitempty"` // 使用 time.Time 来存储 ISO 8601 格式的时间戳 + LogLevel string `json:"log_level,omitempty"` // 日志级别,例如 "INFO" + Thread string `json:"thread,omitempty"` // 线程名称 + LoggerClass string `json:"logger_class,omitempty"` // 产生日志的类名 + LoggerMethod string `json:"logger_method,omitempty"` // 产生日志的方法名 + LineNumber int `json:"line_number,omitempty"` // 代码的行号 + Message string `json:"message,omitempty"` // 实际的日志消息 + XID string `json:"XID,omitempty"` // 事务的唯一标识 +} + +type Elasticsearch struct { +} + +type ElasticsearchParams struct { + LogLevel string `json:"log_level"` + TransactionId string `json:"transaction_id"` +} + +type Match struct { + Field map[string]string `json:"match"` +} + +type BoolQuery struct { + Must []Match `json:"must"` +} + +type Query struct { + Bool BoolQuery `json:"bool"` +} + +type SearchQuery struct { + Query Query `json:"query"` +} + +func newSearchQuery(logLevel, transactionID string) (string, error) { + must := []Match{ + {Field: map[string]string{"log_level": logLevel}}, + {Field: map[string]string{"transaction_id": transactionID}}, + } + boolQuery := BoolQuery{ + Must: must, + } + query := Query{ + Bool: boolQuery, + } + searchQuery := SearchQuery{ + Query: query, + } + queryJSON, err := json.Marshal(searchQuery) + if err != nil { + return "", err + } + return string(queryJSON), nil +} + +func (e *Elasticsearch) QueryLogs(filter map[string]interface{}) ([]string, error) { + currency, ok := filter["currency"].(utils.Currency) + if !ok { + return nil, fmt.Errorf("error: failed to assert currency type") + } + params, ok := filter["Elasticsearch"].(ElasticsearchParams) + if !ok { + return nil, fmt.Errorf("error: failed to assert elasticsearchParams type") + } + cfg := elasticsearch.Config{ + Addresses: []string{currency.Address}, + } + es, err := elasticsearch.NewClient(cfg) + if err != nil { + log.Fatalf("Error creating the client: %s", err) + } + query, err := newSearchQuery(params.LogLevel, params.TransactionId) + if err != nil { + return nil, err + } + + res, err := es.Search( + es.Search.WithContext(context.Background()), + es.Search.WithIndex(currency.Source), + es.Search.WithBody(strings.NewReader(query)), + es.Search.WithPretty(), + ) + + if err != nil { + log.Fatalf("Error getting response: %s", err) + } + + defer res.Body.Close() + + if res.IsError() { + log.Fatalf("Error: %s", res.String()) + } + + var r map[string]interface{} + if err := json.NewDecoder(res.Body).Decode(&r); err != nil { + log.Fatalf("Error parsing the response body: %s", err) + } + var logStrings []string + for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) { + var entry LogEntry + source := hit.(map[string]interface{})["_source"] + sourceData, _ := json.Marshal(source) + if err := json.Unmarshal(sourceData, &entry); err != nil { + log.Fatalf("Error unmarshalling log: %s", err) + } + logString := fmt.Sprintf("Timestamp: %s, LogLevel: %s, Thread: %s, LoggerClass: %s, LoggerMethod: %s, LineNumber: %d, Message: %s, XID: %s", + entry.Timestamp.Format(time.RFC3339), + entry.LogLevel, + entry.Thread, + entry.LoggerClass, + entry.LoggerMethod, + entry.LineNumber, + entry.Message, + entry.XID, + ) + logStrings = append(logStrings, logString) + } + return logStrings, nil +} diff --git a/action/log/utils/impl/local.go b/action/log/utils/impl/local.go new file mode 100644 index 0000000..5d5ae02 --- /dev/null +++ b/action/log/utils/impl/local.go @@ -0,0 +1,66 @@ +package impl + +import ( + "bufio" + "encoding/json" + "fmt" + "github.com/seata/seata-ctl/action/log/utils" + "io/ioutil" + "log" + "net/http" + "strings" +) + +type Local struct{} + +// 日志响应结构 +type LogsResponse struct { + Logs map[string]string `json:"logs"` // 日志内容以节点名为键,日志内容为值 +} + +func (l *Local) QueryLogs(filter map[string]interface{}) ([]string, error) { + + currency, ok := filter["currency"].(utils.Currency) + if !ok { + return nil, fmt.Errorf("error: failed to assert currency type") + } + params, ok := filter["Local"].(LokiParams) + if !ok { + return nil, fmt.Errorf("error: failed to assert lokiParams type") + } + url := fmt.Sprintf("%s/logs/%s", currency.Address, params.Expression) + + resp, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("received non-OK HTTP status: %s", resp.Status) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %v", err) + } + + var logsResponse LogsResponse + err = json.Unmarshal(body, &logsResponse) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %v", err) + } + var allLogs []string + for node, logs := range logsResponse.Logs { + scanner := bufio.NewScanner(strings.NewReader(logs)) + for scanner.Scan() { + line := scanner.Text() + formattedLine := fmt.Sprintf("Node: %s - %s", node, line) + allLogs = append(allLogs, formattedLine) + } + if err := scanner.Err(); err != nil { + log.Printf("Failed to scan logs for node %s: %v", node, err) + } + } + return nil, nil +} diff --git a/action/log/utils/impl/loki.go b/action/log/utils/impl/loki.go new file mode 100644 index 0000000..8dfe807 --- /dev/null +++ b/action/log/utils/impl/loki.go @@ -0,0 +1,92 @@ +package impl + +import ( + "encoding/json" + "fmt" + "github.com/seata/seata-ctl/action/log/utils" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" +) + +type Loki struct { +} + +type LokiParams struct { + Expression string `json:"expression"` +} + +type LokiQueryResult struct { + Status string `json:"status"` + Data struct { + ResultType string `json:"resultType"` + Result []struct { + Stream map[string]string `json:"stream"` + Values [][]string `json:"values"` + } `json:"result"` + } `json:"data"` +} + +func ConvertLokiResultToStrings(result LokiQueryResult) ([]string, error) { + var logs []string + for _, res := range result.Data.Result { + for _, value := range res.Values { + timestampNano, err := strconv.ParseInt(value[0], 10, 64) + if err != nil { + return nil, fmt.Errorf("failed to parse timestamp: %w", err) + } + timestamp := time.Unix(0, timestampNano).Format(time.RFC3339) + logLine := value[1] + logs = append(logs, fmt.Sprintf("[%s] %s", timestamp, logLine)) + } + } + return logs, nil +} + +func (l *Loki) QueryLogs(filter map[string]interface{}) ([]string, error) { + currency, ok := filter["currency"].(utils.Currency) + if !ok { + return nil, fmt.Errorf("error: failed to assert currency type") + } + params, ok := filter["Loki"].(LokiParams) + if !ok { + return nil, fmt.Errorf("error: failed to assert lokiParams type") + } + + // 构建 Loki 查询 URL + queryParams := url.Values{} + queryParams.Add("query", currency.Source+params.Expression) + queryURL := fmt.Sprintf("%s/loki/api/v1/query_range?%s", currency.Address, queryParams.Encode()) + + // 发送 HTTP 请求 + resp, err := http.Get(queryURL) + if err != nil { + return nil, fmt.Errorf("failed to send request to Loki: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected response status: %s", resp.Status) + } + + // 读取响应体 + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %w", err) + } + + // 解析 JSON + var result LokiQueryResult + if err := json.Unmarshal(body, &result); err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + + //转换格式 + res, err := ConvertLokiResultToStrings(result) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/action/log/utils/interface.go b/action/log/utils/interface.go new file mode 100644 index 0000000..8954a6f --- /dev/null +++ b/action/log/utils/interface.go @@ -0,0 +1,11 @@ +package utils + +type LogQuery interface { + // QueryLogs 根据查询条件获取日志 + QueryLogs(filter map[string]interface{}) ([]string, error) +} + +type Currency struct { + Address string `json:"address"` + Source string `json:"source"` +} diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 004242d..34f3b04 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -3,8 +3,6 @@ package prometheus import ( "encoding/json" "fmt" - "github.com/gdamore/tcell/v2" - "github.com/rivo/tview" "github.com/seata/seata-ctl/model" "github.com/spf13/cobra" "gopkg.in/yaml.v3" @@ -13,7 +11,6 @@ import ( "net/http" "net/url" "os" - "time" ) var MetricsCmd = &cobra.Command{ @@ -42,11 +39,7 @@ func metrics() error { if err != nil { log.Fatalf("Error querying Prometheus: %v", err) } - err = generateView(result) - if err != nil { - log.Fatalf("Error generating view: %v", err) - return err - } + printPrometheusResponse(result) return nil } @@ -86,48 +79,45 @@ func getPrometheusAddress() (string, error) { return contextPath, err } -func generateView(result *PrometheusResponse) error { - app := tview.NewApplication() - table := tview.NewTable(). - SetBorders(true). - SetFixed(1, 0) - headers := []string{"Metric", "Timestamp", "Value"} - for i, header := range headers { - table.SetCell(0, i, tview.NewTableCell(header). - SetTextColor(tview.TrueColor). - SetAlign(tview.AlignCenter). - SetSelectable(false)) - } - for rowIndex, res := range result.Data.Result { - value := res.Value - if len(value) == 2 { - timestamp, ok := value[0].(float64) - if !ok { - log.Println("Invalid timestamp format") - continue - } - val, ok := value[1].(string) - if !ok { - log.Println("Invalid value format") - continue - } - timeStamp := time.Unix(int64(timestamp), 0).UTC() - table.SetCell(rowIndex+1, 0, tview.NewTableCell(Target). - SetTextColor(tcell.ColorWhite). - SetAlign(tview.AlignLeft)) - table.SetCell(rowIndex+1, 1, tview.NewTableCell(timeStamp.Format(time.RFC3339)). - SetTextColor(tcell.ColorWhite). - SetAlign(tview.AlignCenter)) - table.SetCell(rowIndex+1, 2, tview.NewTableCell(val). - SetTextColor(tcell.ColorWhite). - SetAlign(tview.AlignRight)) - } - } - if err := app.SetRoot(table, true).Run(); err != nil { - log.Fatalf("Error starting tview application: %v", err) - } - return nil -} +//func generateView(result *PrometheusResponse) error { +// app := tview.NewApplication() +// table := tview.NewTable(). +// SetBorders(true). +// SetFixed(1, 0) +// headers := []string{"Metric", "Timestamp", "Value"} +// for i, header := range headers { +// table.SetCell(0, i, tview.NewTableCell(header). +// SetTextColor(tview.TrueColor). +// SetAlign(tview.AlignCenter). +// SetSelectable(false)) +// } +// for rowIndex, res := range result.Data.Result { +// value := res.Value +// if len(value) == 2 { +// timestamp, ok := value[0].(float64) +// if !ok { +// log.Println("Invalid timestamp format") +// continue +// } +// val, ok := value[1].(string) +// if !ok { +// log.Println("Invalid value format") +// continue +// } +// timeStamp := time.Unix(int64(timestamp), 0).UTC() +// table.SetCell(rowIndex+1, 0, tview.NewTableCell(Target). +// SetAlign(tview.AlignLeft)) +// table.SetCell(rowIndex+1, 1, tview.NewTableCell(timeStamp.Format(time.RFC3339)). +// SetAlign(tview.AlignCenter)) +// table.SetCell(rowIndex+1, 2, tview.NewTableCell(val). +// SetAlign(tview.AlignRight)) +// } +// } +// if err := app.SetRoot(table, true).Run(); err != nil { +// log.Fatalf("Error starting tview application: %v", err) +// } +// return nil +//} type PrometheusResponse struct { Status string `json:"status"` @@ -157,3 +147,30 @@ func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, er } return &result, nil } + +func printPrometheusResponse(response *PrometheusResponse) { + if response == nil { + fmt.Println("The Prometheus response is nil.") + return + } + + fmt.Println("Prometheus Response Status:", response.Status) + if response.Data.ResultType != "" { + fmt.Println("Result Type:", response.Data.ResultType) + } + + if len(response.Data.Result) > 0 { + fmt.Println("Results:") + for i, result := range response.Data.Result { + fmt.Printf(" Result %d:\n", i+1) + if len(result.Metric) > 0 { + fmt.Printf(" Metric: %+v\n", result.Metric) + } + if len(result.Value) > 0 { + fmt.Printf(" Value: %+v\n", result.Value) + } + } + } else { + fmt.Println(" No results found.") + } +} diff --git a/config.yml b/config.yml index 0468007..338b1ed 100644 --- a/config.yml +++ b/config.yml @@ -1,27 +1,30 @@ kubernetes: - clusters: - - name: "cluster1" - kubeconfigpath: "/Users/wpy/.kube/config" - ymlpath: "" + clusters: + - name: "cluster1" + kubeconfigpath: "/Users/wpy/.kube/config" + ymlpath: "" + - name: "seata" + kubeconfigpath: "/Users/wpy/Documents/Kubernetes/remotekube.txt" + ymlpath: "" prometheus: - servers: - - name: "prometheus" - address: "http://localhost:9092" - auth: "" + servers: + - name: "prometheus" + address: "http://localhost:9092" + auth: "" log: - clusters: - - name: "" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" + clusters: + - name: "" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" context: - kubernetes: "cluster1" - prometheus: "prometheus" - log: "" + kubernetes: "cluster1" + prometheus: "prometheus" + log: "" \ No newline at end of file diff --git a/go.mod b/go.mod index c537646..0a7e3f3 100644 --- a/go.mod +++ b/go.mod @@ -1,32 +1,78 @@ module github.com/seata/seata-ctl -go 1.19 +go 1.22.0 + +toolchain go1.22.6 require ( + github.com/elastic/go-elasticsearch/v8 v8.15.0 github.com/jedib0t/go-pretty/v6 v6.4.7 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.16.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 + gopkg.in/yaml.v3 v3.0.1 + k8s.io/api v0.31.0 + k8s.io/apiextensions-apiserver v0.31.0 + k8s.io/apimachinery v0.31.0 + k8s.io/client-go v0.31.0 + sigs.k8s.io/yaml v1.4.0 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.9.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.24.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index 0378c44..05b547c 100644 --- a/go.sum +++ b/go.sum @@ -46,10 +46,18 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk 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/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= +github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= @@ -57,11 +65,30 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -87,8 +114,12 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -98,7 +129,12 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.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= @@ -112,8 +148,12 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -123,44 +163,71 @@ 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/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.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +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/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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 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/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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +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/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= 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 v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -171,17 +238,21 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= 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= @@ -192,6 +263,14 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -264,6 +343,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -273,6 +354,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -318,11 +401,12 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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= @@ -331,11 +415,13 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -373,6 +459,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -381,8 +468,11 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f 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-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.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= @@ -475,13 +565,21 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= @@ -492,6 +590,26 @@ 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.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/model/config.go b/model/config.go index 921f988..8d84b3c 100644 --- a/model/config.go +++ b/model/config.go @@ -40,6 +40,9 @@ type Server struct { type Cluster struct { Name string `yaml:"name"` + Types string `yaml:"types"` + Address string `yaml:"address"` + Source string `yaml:"source"` Collection Collection `yaml:"collection"` Analysis Analysis `yaml:"analysis"` Display Display `yaml:"display"` diff --git a/seata.json b/seata.json new file mode 100644 index 0000000..0606a2b --- /dev/null +++ b/seata.json @@ -0,0 +1 @@ +{"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{"controller-gen.kubebuilder.io/version":"v0.13.0"},"name":"seataservers.operator.seata.apache.org"},"spec":{"group":"operator.seata.apache.org","names":{"kind":"SeataServer","listKind":"SeataServerList","plural":"seataservers","singular":"seataserver"},"scope":"Namespaced","versions":[{"name":"v1alpha1","schema":{"openAPIV3Schema":{"description":"SeataServer is the Schema for the seataservers 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":"SeataServerSpec defines the desired state of SeataServer","properties":{"containerName":{"default":"seata-server","type":"string"},"env":{"additionalProperties":{"type":"string"},"type":"object"},"image":{"type":"string"},"ports":{"properties":{"consolePort":{"default":7091,"format":"int32","type":"integer"},"raftPort":{"default":9091,"format":"int32","type":"integer"},"servicePort":{"default":8091,"format":"int32","type":"integer"}},"type":"object"},"replicas":{"default":1,"format":"int32","minimum":1,"type":"integer"},"resources":{"description":"ResourceRequirements describes the compute resource requirements.","properties":{"claims":{"description":"Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable. It can only be set for containers.","items":{"description":"ResourceClaim references one entry in PodSpec.ResourceClaims.","properties":{"name":{"description":"Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.","type":"string"}},"required":["name"],"type":"object"},"type":"array","x-kubernetes-list-map-keys":["name"],"x-kubernetes-list-type":"map"},"limits":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"},"requests":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"}},"type":"object"},"serviceName":{"default":"seata-server","type":"string"},"store":{"properties":{"resources":{"description":"ResourceRequirements describes the compute resource requirements.","properties":{"claims":{"description":"Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable. It can only be set for containers.","items":{"description":"ResourceClaim references one entry in PodSpec.ResourceClaims.","properties":{"name":{"description":"Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.","type":"string"}},"required":["name"],"type":"object"},"type":"array","x-kubernetes-list-map-keys":["name"],"x-kubernetes-list-type":"map"},"limits":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"},"requests":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"}},"type":"object"}},"required":["resources"],"type":"object"}},"required":["image","store"],"type":"object"},"status":{"description":"SeataServerStatus defines the observed state of SeataServer","properties":{"readyReplicas":{"format":"int32","type":"integer"},"replicas":{"format":"int32","type":"integer"},"synchronized":{"type":"boolean"}},"required":["replicas","synchronized"],"type":"object"}},"type":"object"}},"served":true,"storage":true,"subresources":{"status":{}}}]}} \ No newline at end of file diff --git a/operator.seata.apache.org_seataservers.yaml b/seata.yaml similarity index 100% rename from operator.seata.apache.org_seataservers.yaml rename to seata.yaml From 9583d22347f18718d720d0fcc42b099cc84069ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 27 Sep 2024 02:07:19 +0800 Subject: [PATCH 07/30] fix --- action/k8s/install.go | 47 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/action/k8s/install.go b/action/k8s/install.go index 828491a..1ad6ea2 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -10,6 +10,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" _ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/errors" _ "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" _ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -26,13 +27,17 @@ var InstallCmd = &cobra.Command{ if err != nil { log.Fatal(err) } - // err = DeployController() - // if err != nil { - // log.Fatal(err) - // } + err = DeployController() + if err != nil { + log.Fatal(err) + } }, } +func init() { + InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") +} + const CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" const FilePath = "seata.yaml" @@ -53,32 +58,48 @@ func DeployController() error { if err != nil { return fmt.Errorf("error getting clientset: %v", err) } - // Create Deployment object + + // Define the Deployment name and namespace + deploymentName := "seata-k8s-controller-manager" + namespace := Namespace + + // Check if the Deployment already exists + _, err = clientset.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, metav1.GetOptions{}) + if err == nil { + // If the Deployment exists, output a message and return + fmt.Printf("Deployment '%s' already exists in the '%s' namespace\n", deploymentName, Namespace) + return nil + } else if !errors.IsNotFound(err) { + // If there is an error other than "not found", return it + return fmt.Errorf("error checking for existing deployment: %v", err) + } + + // Create Deployment object if it does not exist deployment := &appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ Kind: "Deployment", APIVersion: "apps/v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "seata-k8s-controller-manager", + Name: deploymentName, }, Spec: appsv1.DeploymentSpec{ Replicas: func(i int32) *int32 { return &i }(1), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "app": "seata-k8s-controller-manager", + "app": deploymentName, }, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "app": "seata-k8s-controller-manager", + "app": deploymentName, }, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { - Name: "seata-k8s-controller-manager", + Name: deploymentName, Image: "apache/seata-controller:latest", Ports: []corev1.ContainerPort{ { @@ -91,10 +112,12 @@ func DeployController() error { }, }, } - _, err = clientset.AppsV1().Deployments("default").Create(context.TODO(), deployment, metav1.CreateOptions{}) + + // Create the Deployment + _, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { - log.Fatalf("Error creating deployment: %s", err.Error()) + return fmt.Errorf("error creating deployment: %v", err) } fmt.Println("Deployment created successfully") - return err + return nil } From e381f56a7f54391b11d85e3d1c509c656a6d0d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 27 Sep 2024 15:16:18 +0800 Subject: [PATCH 08/30] fix k8s part,this part is available. --- action/k8s/deploy.go | 53 +++++++-------------------- action/k8s/install.go | 2 +- action/k8s/scale.go | 8 +---- action/k8s/status.go | 79 +++++++++++++++++++---------------------- action/k8s/undeploy.go | 6 +--- action/k8s/uninstall.go | 20 ++++++----- 6 files changed, 64 insertions(+), 104 deletions(-) diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index a8437da..2c00d53 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -10,6 +10,11 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +const Image = "apache/seata-server:latest" +const ServiceName = "seata-server-cluster" +const RequestStorage = "1Gi" +const LimitStorage = "1Gi" + var DeployCmd = &cobra.Command{ Use: "deploy", Short: "deploy seata in k8s", @@ -19,29 +24,21 @@ var DeployCmd = &cobra.Command{ } var Name string -var ServiceName string var Replicas int32 -var Image string var Namespace string func init() { DeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") - DeployCmd.PersistentFlags().StringVar(&ServiceName, "service", "seata-service", "Headless Service name") DeployCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") - DeployCmd.PersistentFlags().StringVar(&Image, "image", "seata-server", "Image tag") DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") } func deploy() error { - //获取动态kubeclient client, err := utils.GetDynamicClient() if err != nil { return err } - // 获取命名空间 namespace := Namespace - - // 定义 Custom Resource 的 GroupVersionResource gvr := schema.GroupVersionResource{ Group: "operator.seata.apache.org", Version: "v1alpha1", @@ -54,55 +51,31 @@ func deploy() error { fmt.Println("This seata server already exits!") return nil } - // 创建 Custom Resource 对象 seataServer = &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "operator.seata.apache.org/v1alpha1", "kind": "SeataServer", "metadata": map[string]interface{}{ "name": Name, - "namespace": "default", + "namespace": Namespace, }, "spec": map[string]interface{}{ - "containerName": Image, - "image": "seataio/seata-server:latest", - "replicas": Replicas, - "serviceName": ServiceName, - //"env": map[string]interface{}{ - // "SEATA_ENV": "prod", - // "SEATA_LOG_LEVEL": "info", - //}, - "ports": map[string]interface{}{ - "consolePort": 7091, - "raftPort": 9091, - "servicePort": 8091, - }, - "resources": map[string]interface{}{ - "limits": map[string]interface{}{ - "cpu": "500m", - "memory": "1Gi", - }, - "requests": map[string]interface{}{ - "cpu": "250m", - "memory": "512Mi", - }, - }, + "serviceName": ServiceName, + "replicas": Replicas, + "image": Image, "store": map[string]interface{}{ "resources": map[string]interface{}{ - "limits": map[string]interface{}{ - "cpu": "500m", - "memory": "1Gi", - }, "requests": map[string]interface{}{ - "cpu": "250m", - "memory": "512Mi", + "storage": RequestStorage, + }, + "limits": map[string]interface{}{ + "storage": LimitStorage, }, }, }, }, }, } - // 尝试创建 Custom Resource _, err = client.Resource(gvr).Namespace(namespace).Create(context.TODO(), seataServer, metav1.CreateOptions{}) if err != nil { return err diff --git a/action/k8s/install.go b/action/k8s/install.go index 1ad6ea2..7ca4089 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -100,7 +100,7 @@ func DeployController() error { Containers: []corev1.Container{ { Name: deploymentName, - Image: "apache/seata-controller:latest", + Image: "bearslyricattack/seata-controller:latest", Ports: []corev1.ContainerPort{ { ContainerPort: 80, diff --git a/action/k8s/scale.go b/action/k8s/scale.go index 0940043..329e679 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -28,15 +28,12 @@ func init() { } func scale() error { - //获取动态kubeclient client, err := utils.GetDynamicClient() if err != nil { return err } - // 获取命名空间 namespace := Namespace - // 定义 Custom Resource 的 GroupVersionResource gvr := schema.GroupVersionResource{ Group: "operator.seata.apache.org", Version: "v1alpha1", @@ -49,16 +46,13 @@ func scale() error { fmt.Println("This seata server does not exits!") return nil } - - //修改 seataServer.Object["spec"].(map[string]interface{})["replicas"] = Replicas - // 尝试创建 Custom Resource _, err = client.Resource(gvr).Namespace(namespace).Update(context.TODO(), seataServer, metav1.UpdateOptions{}) if err != nil { return err } - fmt.Printf("CR 修改成功,名称: %s\n", Name) + fmt.Printf("CR scale success,name: %s\n", Name) return nil } diff --git a/action/k8s/status.go b/action/k8s/status.go index d82a71b..8c8465b 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -1,16 +1,11 @@ package k8s import ( - "bytes" "context" - "encoding/json" "fmt" "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "log" ) var StatusCmd = &cobra.Command{ @@ -24,56 +19,54 @@ var StatusCmd = &cobra.Command{ }, } +const Label = "cr_name" + func init() { StatusCmd.PersistentFlags().StringVar(&Name, "name", "list", "Seataserver name") StatusCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") } func status() error { - //获取动态kubeclient - client, err := utils.GetDynamicClient() + statuses, err := getPodsStatusByLabel(Namespace, Name) if err != nil { return err } - // 获取命名空间 - namespace := Namespace - - // 定义 Custom Resource 的 GroupVersionResource - gvr := schema.GroupVersionResource{ - Group: "operator.seata.apache.org", - Version: "v1alpha1", - Resource: "seataservers", + // Print formatted Pod status information + for _, status := range statuses { + fmt.Println(status) } + return nil +} - var jsonData []byte - if Name == "list" { - fmt.Printf("1") - var seataServerList *unstructured.UnstructuredList - seataServerList, err = client.Resource(gvr).Namespace(namespace).List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return err - } - jsonData, err = seataServerList.MarshalJSON() - if err != nil { - log.Fatalf("Error marshalling Unstructured object to JSON: %v", err) - } - } else { - var seataServer *unstructured.Unstructured - seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) - if err != nil { - return err - } - jsonData, err = seataServer.MarshalJSON() - if err != nil { - log.Fatalf("Error marshalling Unstructured object to JSON: %v", err) - } +func getPodsStatusByLabel(namespace, labelSelector string) ([]string, error) { + client, err := utils.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to create client: %v", err) } - //更美观的格式化输出 - var prettyJSON bytes.Buffer - err = json.Indent(&prettyJSON, jsonData, "", "") + + // Retrieve all Pods with the specified label + // Use LabelSelector to filter Pods with the specified cr_name label + labelSelector = Label + "=" + labelSelector + pods, err := client.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: labelSelector, + }) if err != nil { - log.Fatalf("Error indenting JSON: %v", err) + return nil, fmt.Errorf("failed to list pods: %v", err) } - fmt.Printf("%s\n", prettyJSON.Bytes()) - return nil + + // Iterate over all Pods and get their status + var statuses []string + for _, pod := range pods.Items { + statuses = append(statuses, fmt.Sprintf("Pod %s is in %s phase", pod.Name, pod.Status.Phase)) + } + + // Build formatted status string for output + statuses = append(statuses, fmt.Sprintf("%-25s %-10s", "POD NAME", "STATUS")) // Header + statuses = append(statuses, fmt.Sprintf("%s", "-------------------------------------------")) + + for _, pod := range pods.Items { + statuses = append(statuses, fmt.Sprintf("%-25s %-10s", pod.Name, pod.Status.Phase)) + } + + return statuses, nil } diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go index 4bbbf25..cce5bc3 100644 --- a/action/k8s/undeploy.go +++ b/action/k8s/undeploy.go @@ -26,26 +26,22 @@ func init() { } func undeploy() error { - //获取动态kubeclient client, err := utils.GetDynamicClient() if err != nil { return err } - // 获取命名空间 namespace := Namespace - // 定义 Custom Resource 的 GroupVersionResource gvr := schema.GroupVersionResource{ Group: "operator.seata.apache.org", Version: "v1alpha1", Resource: "seataservers", } - //删除 err = client.Resource(gvr).Namespace(namespace).Delete(context.TODO(), Name, metav1.DeleteOptions{}) if err != nil { return err } - fmt.Printf("CR 删除成功,名称: %s\n", Name) + fmt.Printf("CR delete success,name: %s\n", Name) return nil } diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index fa7ea7d..e3885a9 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -10,6 +10,8 @@ import ( "log" ) +const CRDname = "seataservers.operator.seata.apache.org" + var UnInstallCmd = &cobra.Command{ Use: "uninstall", Short: "uninstall seata in k8s", @@ -25,34 +27,36 @@ var UnInstallCmd = &cobra.Command{ }, } -// UninstallCRD 删除CRD定义 +func init() { + UnInstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") +} + func UninstallCRD() error { - //获取动态kubeclient client, err := utils.GetDynamicClient() if err != nil { return err } + gvr := schema.GroupVersionResource{ Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions", } - //删除 CRD - err = client.Resource(gvr).Delete(context.TODO(), "seataservers.operator.seata.apache.org", metav1.DeleteOptions{}) + + err = client.Resource(gvr).Delete(context.TODO(), CRDname, metav1.DeleteOptions{}) if err != nil { - log.Fatalf("删除CRD 失败: %v", err) + log.Fatalf("delete CRD failed: %v", err) } - fmt.Printf("delete CRD success,名称: %s\n", "seataservers.operator.seata.apache.org") + fmt.Printf("delete CRD success,name: %s\n", "seataservers.operator.seata.apache.org") return nil } -// UnDeploymentController 删除Seata-controller func UnDeploymentController() error { clientset, err := utils.GetClient() if err != nil { return err } - err = clientset.AppsV1().Deployments("default").Delete(context.TODO(), "seata-k8s-controller-manager", metav1.DeleteOptions{}) + err = clientset.AppsV1().Deployments(Namespace).Delete(context.TODO(), "seata-k8s-controller-manager", metav1.DeleteOptions{}) if err != nil { log.Fatalf("Error creating deployment: %s", err.Error()) } From 0586e5c2b50a5cbc2e37977ece33b55c356120d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 27 Sep 2024 16:27:34 +0800 Subject: [PATCH 09/30] fix prometheus part,this part is available. --- action/config/config.go | 24 +++--- action/prometheus/metrics.go | 137 ++++++++++++++--------------------- go.mod | 10 +++ go.sum | 24 ++++++ 4 files changed, 100 insertions(+), 95 deletions(-) diff --git a/action/config/config.go b/action/config/config.go index 68af909..1780dad 100644 --- a/action/config/config.go +++ b/action/config/config.go @@ -13,19 +13,19 @@ var Path = "/" var ConfigCmd = &cobra.Command{ Use: "config", - Short: "config config path", + Short: "Set config path", Run: func(cmd *cobra.Command, args []string) { err := createYMLFile(Path) if err != nil { - println("create config error:", err.Error()) + println("Error creating config:", err.Error()) log.Fatal(err) } - println("create config success!") + println("Config created successfully!") }, } func init() { - ConfigCmd.PersistentFlags().StringVar(&Path, "path", "/", "config config path") + ConfigCmd.PersistentFlags().StringVar(&Path, "path", "/", "Set config path") } func createSampleConfig() model.Config { @@ -76,36 +76,36 @@ func createSampleConfig() model.Config { } } -// 创建yml文件 +// Create a YAML file func createYMLFile(path string) error { - // 检查路径是否存在 + // Check if the path exists if _, err := os.Stat(path); os.IsNotExist(err) { return fmt.Errorf("path does not exist: %s", path) } - // 检查文件是否存在 + // Check if the file already exists ymlFilePath := path + "config.yml" if _, err := os.Stat(ymlFilePath); err == nil { return fmt.Errorf("file already exists: %s", path) } - // 创建示例配置对象 + // Create a sample config object config := createSampleConfig() - // 将配置对象编码为 YAML 格式 + // Marshal the config object into YAML format data, err := yaml.Marshal(&config) if err != nil { log.Fatalf("Failed to marshal config to YAML: %v", err) } - // 将 YAML 数据写入文件 + // Write the YAML data to a file file, err := os.Create("config.yml") if err != nil { log.Fatalf("Failed to create YAML config: %v", err) } defer func() { if err := file.Close(); err != nil { - log.Fatalf("Failed to close config: %v", err) + log.Fatalf("Failed to close config file: %v", err) } }() @@ -115,7 +115,7 @@ func createYMLFile(path string) error { } fmt.Println("YAML config created successfully") - //修改path的位置 + // Update the path variable Path = path return nil } diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 34f3b04..51767a8 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -3,6 +3,7 @@ package prometheus import ( "encoding/json" "fmt" + "github.com/guptarohit/asciigraph" "github.com/seata/seata-ctl/model" "github.com/spf13/cobra" "gopkg.in/yaml.v3" @@ -11,14 +12,14 @@ import ( "net/http" "net/url" "os" + "strconv" ) var MetricsCmd = &cobra.Command{ Use: "metrics", - Short: "show prometheus metrics", + Short: "Show Prometheus metrics", Run: func(cmd *cobra.Command, args []string) { - err := metrics() - if err != nil { + if err := showMetrics(); err != nil { fmt.Println(err) } }, @@ -30,41 +31,40 @@ func init() { MetricsCmd.PersistentFlags().StringVar(&Target, "target", "seata_transaction_summary", "Namespace name") } -func metrics() error { +// showMetrics executes the metrics collection and chart generation +func showMetrics() error { prometheusURL, err := getPrometheusAddress() if err != nil { return err } + + // Query Prometheus for metrics result, err := queryPrometheusMetric(prometheusURL, Target) if err != nil { log.Fatalf("Error querying Prometheus: %v", err) } - printPrometheusResponse(result) - return nil -} -// QueryResult 用于解析 Prometheus 查询结果的结构体 -type QueryResult struct { - Status string `json:"status"` - Data struct { - ResultType string `json:"resultType"` - Result []struct { - Metric map[string]string `json:"metric"` - Value []interface{} `json:"value"` - } `json:"result"` - } `json:"data"` + // Generate terminal chart from the queried results + if err = generateTerminalLineChart(result, Target); err != nil { + return err + } + return nil } +// getPrometheusAddress fetches Prometheus server address from configuration func getPrometheusAddress() (string, error) { file, err := os.ReadFile("config.yml") if err != nil { log.Fatalf("Failed to read config.yml: %v", err) } + + // Parse the configuration var config model.Config - err = yaml.Unmarshal(file, &config) - if err != nil { - log.Fatalf("Unmarshal: %v", err) + if err = yaml.Unmarshal(file, &config); err != nil { + log.Fatalf("Failed to unmarshal YAML: %v", err) } + + // Extract Prometheus address based on context contextName := config.Context.Prometheus var contextPath string for _, server := range config.Prometheus.Servers { @@ -73,52 +73,13 @@ func getPrometheusAddress() (string, error) { } } if contextPath == "" { - log.Fatalf("Failed to find context in config.yml") + log.Fatalf("Failed to find Prometheus context in config.yml") return "", err } - return contextPath, err + return contextPath, nil } -//func generateView(result *PrometheusResponse) error { -// app := tview.NewApplication() -// table := tview.NewTable(). -// SetBorders(true). -// SetFixed(1, 0) -// headers := []string{"Metric", "Timestamp", "Value"} -// for i, header := range headers { -// table.SetCell(0, i, tview.NewTableCell(header). -// SetTextColor(tview.TrueColor). -// SetAlign(tview.AlignCenter). -// SetSelectable(false)) -// } -// for rowIndex, res := range result.Data.Result { -// value := res.Value -// if len(value) == 2 { -// timestamp, ok := value[0].(float64) -// if !ok { -// log.Println("Invalid timestamp format") -// continue -// } -// val, ok := value[1].(string) -// if !ok { -// log.Println("Invalid value format") -// continue -// } -// timeStamp := time.Unix(int64(timestamp), 0).UTC() -// table.SetCell(rowIndex+1, 0, tview.NewTableCell(Target). -// SetAlign(tview.AlignLeft)) -// table.SetCell(rowIndex+1, 1, tview.NewTableCell(timeStamp.Format(time.RFC3339)). -// SetAlign(tview.AlignCenter)) -// table.SetCell(rowIndex+1, 2, tview.NewTableCell(val). -// SetAlign(tview.AlignRight)) -// } -// } -// if err := app.SetRoot(table, true).Run(); err != nil { -// log.Fatalf("Error starting tview application: %v", err) -// } -// return nil -//} - +// PrometheusResponse defines the structure of a Prometheus query response type PrometheusResponse struct { Status string `json:"status"` Data struct { @@ -130,6 +91,7 @@ type PrometheusResponse struct { } `json:"data"` } +// queryPrometheusMetric sends a query to the Prometheus API and returns the response func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, error) { queryURL := fmt.Sprintf("%s/api/v1/query?query=%s", prometheusURL, url.QueryEscape(query)) resp, err := http.Get(queryURL) @@ -137,10 +99,14 @@ func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, er return nil, fmt.Errorf("error querying Prometheus: %w", err) } defer resp.Body.Close() + + // Read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("error reading response body: %w", err) } + + // Parse JSON response into the PrometheusResponse structure var result PrometheusResponse if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("error unmarshalling JSON: %w", err) @@ -148,29 +114,34 @@ func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, er return &result, nil } -func printPrometheusResponse(response *PrometheusResponse) { - if response == nil { - fmt.Println("The Prometheus response is nil.") - return - } - - fmt.Println("Prometheus Response Status:", response.Status) - if response.Data.ResultType != "" { - fmt.Println("Result Type:", response.Data.ResultType) - } +// generateTerminalLineChart generates and prints an ASCII line chart based on the Prometheus response +func generateTerminalLineChart(response *PrometheusResponse, metricName string) error { + var yValues []float64 - if len(response.Data.Result) > 0 { - fmt.Println("Results:") - for i, result := range response.Data.Result { - fmt.Printf(" Result %d:\n", i+1) - if len(result.Metric) > 0 { - fmt.Printf(" Metric: %+v\n", result.Metric) - } - if len(result.Value) > 0 { - fmt.Printf(" Value: %+v\n", result.Value) + // Iterate over the results and extract the values for the specified metric + for _, result := range response.Data.Result { + if name, ok := result.Metric["__name__"]; ok && name == metricName { + // Parse the metric value + if valueStr, ok := result.Value[1].(string); ok { + value, err := strconv.ParseFloat(valueStr, 64) + if err != nil { + fmt.Println("Value: Invalid number format") + } else { + yValues = append(yValues, value) + } + } else { + fmt.Println("Value: Invalid value format") } } - } else { - fmt.Println(" No results found.") } + + // Check if any values were found + if len(yValues) == 0 { + return fmt.Errorf("no data found for metric: %s", metricName) + } + + // Generate and display the ASCII line chart + graph := asciigraph.Plot(yValues, asciigraph.Width(50), asciigraph.Height(10), asciigraph.Caption(metricName)) + fmt.Println(graph) + return nil } diff --git a/go.mod b/go.mod index 0a7e3f3..486340d 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.22.6 require ( github.com/elastic/go-elasticsearch/v8 v8.15.0 + github.com/guptarohit/asciigraph v0.7.2 github.com/jedib0t/go-pretty/v6 v6.4.7 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.16.0 @@ -19,17 +20,24 @@ require ( ) require ( + git.sr.ht/~sbinet/gg v0.5.0 // indirect + github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect + github.com/campoy/embedmd v1.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-fonts/liberation v0.3.3 // indirect + github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-pdf/fpdf v0.9.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -59,6 +67,7 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect + golang.org/x/image v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.25.0 // indirect @@ -66,6 +75,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.24.0 // indirect + gonum.org/v1/plot v0.14.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 05b547c..5389c2b 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,16 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX 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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8= +git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo= 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/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= +github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 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= @@ -70,9 +78,13 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-fonts/liberation v0.3.3 h1:tM/T2vEOhjia6v5krQu8SDDegfH1SfXVRUNNKpq0Usk= +github.com/go-fonts/liberation v0.3.3/go.mod h1:eUAzNRuJnpSnd1sm2EyloQfSOT79pdw7X7++Ri+3MCU= 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-latex/latex v0.0.0-20240709081214-31cef3c7570e h1:xcdj0LWnMSIU1j8+jIeJyfvk6SjgJedFQssSqFthJ2E= +github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e/go.mod h1:J4SAGzkcl+28QWi7yz72tyC/4aGnppOvya+AEv4TaAQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -85,10 +97,14 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= +github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -157,6 +173,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/guptarohit/asciigraph v0.7.2 h1:pBBJYbMl4j7zS4AwmrfAs6tA0VQOEQC933aG72dlrFA= +github.com/guptarohit/asciigraph v0.7.2/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= 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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -257,6 +275,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 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= @@ -290,6 +309,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 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/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw= +golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM= 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= @@ -477,6 +498,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= +gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= +gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= 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= @@ -590,6 +613,7 @@ 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= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= From d0485651360cc1f7050886504d7a12075a0b4a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 18 Oct 2024 23:12:14 +0800 Subject: [PATCH 10/30] =?UTF-8?q?es=20loki=E4=B8=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=B8=8E=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20=E5=BD=93=E5=89=8D=E4=B8=BA=E5=8F=AF=E7=94=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/log/log.go | 161 +++++--- action/log/utils/impl/elasticsearch.go | 215 ++++++----- action/log/utils/impl/local.go | 54 --- action/log/utils/impl/loki.go | 130 ++++--- action/log/utils/interface.go | 17 +- action/root.go | 2 + cmd/root.go | 9 +- config.yml | 45 ++- go 2.sum | 72 ++++ go.mod | 43 +-- go.sum | 492 ++----------------------- model/config.go | 1 + 12 files changed, 467 insertions(+), 774 deletions(-) create mode 100644 go 2.sum diff --git a/action/log/log.go b/action/log/log.go index e834057..50c5503 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -1,7 +1,6 @@ package log import ( - "errors" "fmt" "github.com/seata/seata-ctl/action/log/utils" "github.com/seata/seata-ctl/action/log/utils/impl" @@ -12,6 +11,14 @@ import ( "os" ) +const ( + ElasticSearchType = "ElasticSearch" + DefaultNumber = 10 +) +const ( + LokiType = "Loki" +) + var LogCmd = &cobra.Command{ Use: "log", Short: "get seata log", @@ -23,14 +30,33 @@ var LogCmd = &cobra.Command{ }, } -var Level string -var TransactionId string -var Expression string +// ElasticSearch + +var LogLevel string +var Module string +var XID string +var BranchID string +var ResourceID string +var Message string +var Number int + +// Loki + +var Label string +var Start string +var End string func init() { - LogCmd.PersistentFlags().StringVar(&Level, "level", "ERROR", "seata log level") - LogCmd.PersistentFlags().StringVar(&TransactionId, "Id", "", "seata transaction id") - LogCmd.PersistentFlags().StringVar(&Expression, "Expression", "", "seata expression") + LogCmd.PersistentFlags().StringVar(&LogLevel, "level", "", "seata log level") + LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") + LogCmd.PersistentFlags().StringVar(&XID, "XID", "", "seata expression") + LogCmd.PersistentFlags().StringVar(&BranchID, "BranchID", "", "seata branchId") + LogCmd.PersistentFlags().StringVar(&ResourceID, "ResourceID", "", "seata resourceID") + LogCmd.PersistentFlags().StringVar(&Message, "message", "", "seata message") + LogCmd.PersistentFlags().IntVar(&Number, "number", DefaultNumber, "seata number") + LogCmd.PersistentFlags().StringVar(&Label, "label", "", "seata label") + LogCmd.PersistentFlags().StringVar(&Start, "start", "", "seata start") + LogCmd.PersistentFlags().StringVar(&End, "end", "", "seata end") } func getLog() error { @@ -38,25 +64,40 @@ func getLog() error { if err != nil { return err } + logType := context.Types - param := make(map[string]interface{}) - param["currency"] = currency + var client utils.LogQuery + var filter = make(map[string]interface{}) - client, param, err := getClientAndParams(context, param) - if err != nil { - return err + switch logType { + case ElasticSearchType: + { + client = &impl.Elasticsearch{} + filter = buildElasticSearchFilter() + } + case LokiType: + { + client = &impl.Loki{} + filter = buildLokiFilter() + } + //case "Local": + // { + // return &impl.Local{}, nil, nil + // } } - res, err := client.QueryLogs(param) - if err != nil { - return err + if client == nil { + return fmt.Errorf("can not get client") } - err = showLogInfo(res) + err = client.QueryLogs(filter, currency, Number) if err != nil { return err } + //reset var + //ResetAllVariables() + return nil } @@ -76,6 +117,7 @@ func getContext() (*model.Cluster, *utils.Currency, error) { currency := utils.Currency{ Address: cluster.Address, Source: cluster.Source, + Auth: cluster.Auth, } return &cluster, ¤cy, nil } @@ -83,49 +125,56 @@ func getContext() (*model.Cluster, *utils.Currency, error) { return nil, nil, fmt.Errorf("failed to find context in config.yml") } -func getClientAndParams(cluster *model.Cluster, param map[string]interface{}) (utils.LogQuery, map[string]interface{}, error) { - logType := cluster.Types - switch logType { - case "ElasticSearch": - { - param["ElasticSearch"] = impl.ElasticsearchParams{ - LogLevel: logType, - TransactionId: TransactionId, - } - return &impl.Elasticsearch{}, param, nil - } - case "Loki": - { - param["Loki"] = impl.LokiParams{ - Expression: Expression, - } - return &impl.Loki{}, nil, nil - } - case "Local": - { - param["Local"] = impl.LokiParams{ - Expression: Expression, - } - return &impl.Local{}, nil, nil - } - default: - { - return nil, nil, fmt.Errorf("unknown log type: %s", logType) - } +func buildElasticSearchFilter() map[string]interface{} { + filter := make(map[string]interface{}) + if LogLevel != "" { + filter["logLevel"] = LogLevel + } + if Module != "" { + filter["module"] = Module } + if XID != "" { + filter["XID"] = XID + } + if BranchID != "" { + filter["BranchID"] = BranchID + } + if ResourceID != "" { + filter["ResourceID"] = ResourceID + } + if Message != "" { + filter["message"] = Message + } + return filter } -func showLogInfo(logs []string) error { - if len(logs) == 0 { - return errors.New("no logs to display") +func buildLokiFilter() map[string]interface{} { + filter := make(map[string]interface{}) + filter["query"] = Label + filter["number"] = Number + if Start != "" { + filter["start"] = Start } - fmt.Println("=========== LOG ENTRIES ===========") - for i, logEntry := range logs { - fmt.Printf("Log #%d:\n", i+1) - fmt.Println("------------------------------") - fmt.Printf("%s\n", logEntry) - fmt.Println("------------------------------") + if End != "" { + filter["end"] = End } - fmt.Println("=========== END OF LOGS ===========") - return nil + + return filter +} + +// ResetAllVariables resets all global variables to their zero values +func ResetAllVariables() { + // Reset ElasticSearch-related variables + LogLevel = "" + Module = "" + XID = "" + BranchID = "" + ResourceID = "" + Message = "" + Number = 0 + + // Reset Loki-related variables + Label = "" + Start = "" + End = "" } diff --git a/action/log/utils/impl/elasticsearch.go b/action/log/utils/impl/elasticsearch.go index 86f922a..1a5c471 100644 --- a/action/log/utils/impl/elasticsearch.go +++ b/action/log/utils/impl/elasticsearch.go @@ -2,133 +2,144 @@ package impl import ( "context" + "crypto/tls" "encoding/json" + "errors" "fmt" + "github.com/olivere/elastic/v7" "github.com/seata/seata-ctl/action/log/utils" "log" - "strings" - "time" - - elasticsearch "github.com/elastic/go-elasticsearch/v8" + "net/http" ) -type LogEntry struct { - Timestamp time.Time `json:"timestamp,omitempty"` // 使用 time.Time 来存储 ISO 8601 格式的时间戳 - LogLevel string `json:"log_level,omitempty"` // 日志级别,例如 "INFO" - Thread string `json:"thread,omitempty"` // 线程名称 - LoggerClass string `json:"logger_class,omitempty"` // 产生日志的类名 - LoggerMethod string `json:"logger_method,omitempty"` // 产生日志的方法名 - LineNumber int `json:"line_number,omitempty"` // 代码的行号 - Message string `json:"message,omitempty"` // 实际的日志消息 - XID string `json:"XID,omitempty"` // 事务的唯一标识 -} - -type Elasticsearch struct { -} - -type ElasticsearchParams struct { - LogLevel string `json:"log_level"` - TransactionId string `json:"transaction_id"` -} - -type Match struct { - Field map[string]string `json:"match"` -} +const ( + ElasticsearchAuth = "elastic" +) -type BoolQuery struct { - Must []Match `json:"must"` -} +type Elasticsearch struct{} -type Query struct { - Bool BoolQuery `json:"bool"` -} +// QueryLogs is a function that queries specific documents +func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *utils.Currency, number int) error { + client, err := createElasticClient(currency) + if err != nil { + return fmt.Errorf("failed to create elasticsearch client: %w", err) + } -type SearchQuery struct { - Query Query `json:"query"` -} + indexName := currency.Source -func newSearchQuery(logLevel, transactionID string) (string, error) { - must := []Match{ - {Field: map[string]string{"log_level": logLevel}}, - {Field: map[string]string{"transaction_id": transactionID}}, - } - boolQuery := BoolQuery{ - Must: must, - } - query := Query{ - Bool: boolQuery, - } - searchQuery := SearchQuery{ - Query: query, + // Build the query based on the filter provided + query, err := BuildQueryFromFilter(filter) + if err != nil { + return err } - queryJSON, err := json.Marshal(searchQuery) + + // Execute the search query + searchResult, err := client.Search(). + Index(indexName). + Size(number). + Query(query). + Do(context.Background()) if err != nil { - return "", err + return fmt.Errorf("error fetching documents: %w", err) } - return string(queryJSON), nil + + fmt.Printf("Found %d hits.\n", searchResult.TotalHits()) + processSearchHits(searchResult) + return nil } -func (e *Elasticsearch) QueryLogs(filter map[string]interface{}) ([]string, error) { - currency, ok := filter["currency"].(utils.Currency) - if !ok { - return nil, fmt.Errorf("error: failed to assert currency type") - } - params, ok := filter["Elasticsearch"].(ElasticsearchParams) - if !ok { - return nil, fmt.Errorf("error: failed to assert elasticsearchParams type") +// createElasticClient configures and creates a new Elasticsearch client +func createElasticClient(currency *utils.Currency) (*elastic.Client, error) { + httpClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, } - cfg := elasticsearch.Config{ - Addresses: []string{currency.Address}, - } - es, err := elasticsearch.NewClient(cfg) - if err != nil { - log.Fatalf("Error creating the client: %s", err) - } - query, err := newSearchQuery(params.LogLevel, params.TransactionId) + + client, err := elastic.NewClient( + elastic.SetURL(currency.Address), + elastic.SetHttpClient(httpClient), + elastic.SetSniff(false), + elastic.SetBasicAuth(ElasticsearchAuth, currency.Auth), + ) if err != nil { return nil, err } + return client, nil +} - res, err := es.Search( - es.Search.WithContext(context.Background()), - es.Search.WithIndex(currency.Source), - es.Search.WithBody(strings.NewReader(query)), - es.Search.WithPretty(), - ) +// processSearchHits handles and formats the search results +func processSearchHits(searchResult *elastic.SearchResult) []string { + var result []string - if err != nil { - log.Fatalf("Error getting response: %s", err) - } + for _, hit := range searchResult.Hits.Hits { + fmt.Printf("=== Document ID: %s ===\n", hit.Id) + + var doc map[string]interface{} + if err := json.Unmarshal(hit.Source, &doc); err != nil { + log.Printf("Error parsing document: %s", err) + continue + } - defer res.Body.Close() + // Pretty print the document content + fmt.Println("Document Source:") + for key, value := range doc { + fmt.Printf(" %s: %v\n", key, value) + } + fmt.Println("----------------------------") - if res.IsError() { - log.Fatalf("Error: %s", res.String()) + result = append(result, hit.Id) // Store document IDs or other relevant data } + return result +} - var r map[string]interface{} - if err := json.NewDecoder(res.Body).Decode(&r); err != nil { - log.Fatalf("Error parsing the response body: %s", err) - } - var logStrings []string - for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) { - var entry LogEntry - source := hit.(map[string]interface{})["_source"] - sourceData, _ := json.Marshal(source) - if err := json.Unmarshal(sourceData, &entry); err != nil { - log.Fatalf("Error unmarshalling log: %s", err) +// BuildQueryFromFilter constructs a BoolQuery from the filter parameters +func BuildQueryFromFilter(filter map[string]interface{}) (*elastic.BoolQuery, error) { + query := elastic.NewBoolQuery() + + for key, value := range filter { + switch key { + case "logLevel": + if v, ok := value.(string); ok { + query.Should(elastic.NewTermQuery("logLevel", v)) + } else { + return nil, errors.New("invalid type for logLevel, expected string") + } + case "module": + if v, ok := value.(string); ok { + query.Should(elastic.NewTermQuery("module", v)) + } else { + return nil, errors.New("invalid type for module, expected string") + } + case "xid": + if v, ok := value.(string); ok { + query.Should(elastic.NewTermQuery("xid", v)) + } else { + return nil, errors.New("invalid type for xid, expected string") + } + case "branchId": + if v, ok := value.(string); ok { + query.Should(elastic.NewTermQuery("branchId", v)) + } else { + return nil, errors.New("invalid type for branchId, expected string") + } + case "resourceId": + if v, ok := value.(string); ok { + query.Should(elastic.NewTermQuery("resourceId", v)) + } else { + return nil, errors.New("invalid type for resourceId, expected string") + } + case "message": + if v, ok := value.(string); ok { + query.Should(elastic.NewMatchQuery("message", v)) + } else { + return nil, errors.New("invalid type for message, expected string") + } + default: + log.Printf("Unknown field: %s\n", key) } - logString := fmt.Sprintf("Timestamp: %s, LogLevel: %s, Thread: %s, LoggerClass: %s, LoggerMethod: %s, LineNumber: %d, Message: %s, XID: %s", - entry.Timestamp.Format(time.RFC3339), - entry.LogLevel, - entry.Thread, - entry.LoggerClass, - entry.LoggerMethod, - entry.LineNumber, - entry.Message, - entry.XID, - ) - logStrings = append(logStrings, logString) } - return logStrings, nil + return query, nil } diff --git a/action/log/utils/impl/local.go b/action/log/utils/impl/local.go index 5d5ae02..4903b79 100644 --- a/action/log/utils/impl/local.go +++ b/action/log/utils/impl/local.go @@ -1,16 +1,5 @@ package impl -import ( - "bufio" - "encoding/json" - "fmt" - "github.com/seata/seata-ctl/action/log/utils" - "io/ioutil" - "log" - "net/http" - "strings" -) - type Local struct{} // 日志响应结构 @@ -19,48 +8,5 @@ type LogsResponse struct { } func (l *Local) QueryLogs(filter map[string]interface{}) ([]string, error) { - - currency, ok := filter["currency"].(utils.Currency) - if !ok { - return nil, fmt.Errorf("error: failed to assert currency type") - } - params, ok := filter["Local"].(LokiParams) - if !ok { - return nil, fmt.Errorf("error: failed to assert lokiParams type") - } - url := fmt.Sprintf("%s/logs/%s", currency.Address, params.Expression) - - resp, err := http.Get(url) - if err != nil { - return nil, fmt.Errorf("failed to send request: %v", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("received non-OK HTTP status: %s", resp.Status) - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("failed to read response body: %v", err) - } - - var logsResponse LogsResponse - err = json.Unmarshal(body, &logsResponse) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %v", err) - } - var allLogs []string - for node, logs := range logsResponse.Logs { - scanner := bufio.NewScanner(strings.NewReader(logs)) - for scanner.Scan() { - line := scanner.Text() - formattedLine := fmt.Sprintf("Node: %s - %s", node, line) - allLogs = append(allLogs, formattedLine) - } - if err := scanner.Err(); err != nil { - log.Printf("Failed to scan logs for node %s: %v", node, err) - } - } return nil, nil } diff --git a/action/log/utils/impl/loki.go b/action/log/utils/impl/loki.go index 8dfe807..8a1b00b 100644 --- a/action/log/utils/impl/loki.go +++ b/action/log/utils/impl/loki.go @@ -5,19 +5,20 @@ import ( "fmt" "github.com/seata/seata-ctl/action/log/utils" "io/ioutil" + "log" "net/http" "net/url" "strconv" "time" ) -type Loki struct { -} +const ( + LokiAddressPath = "/loki/api/v1/query_range?" +) -type LokiParams struct { - Expression string `json:"expression"` -} +type Loki struct{} +// LokiQueryResult represents the structure of the response from Loki type LokiQueryResult struct { Status string `json:"status"` Data struct { @@ -29,64 +30,99 @@ type LokiQueryResult struct { } `json:"data"` } -func ConvertLokiResultToStrings(result LokiQueryResult) ([]string, error) { - var logs []string - for _, res := range result.Data.Result { - for _, value := range res.Values { - timestampNano, err := strconv.ParseInt(value[0], 10, 64) - if err != nil { - return nil, fmt.Errorf("failed to parse timestamp: %w", err) - } - timestamp := time.Unix(0, timestampNano).Format(time.RFC3339) - logLine := value[1] - logs = append(logs, fmt.Sprintf("[%s] %s", timestamp, logLine)) - } - } - return logs, nil -} +// QueryLogs queries logs from Loki based on the filter and settings provided +func (l *Loki) QueryLogs(filter map[string]interface{}, currency *utils.Currency, number int) error { -func (l *Loki) QueryLogs(filter map[string]interface{}) ([]string, error) { - currency, ok := filter["currency"].(utils.Currency) - if !ok { - return nil, fmt.Errorf("error: failed to assert currency type") + // Prepare the query URL with time range + params := url.Values{} + params.Set("query", filter["query"].(string)) + params.Set("limit", strconv.Itoa(filter["number"].(int))) + + // Set start time if provided + if value, ok := filter["start"]; ok { + res, err := parseToTimestamp(value.(string)) + if err != nil { + return err + } + params.Set("start", fmt.Sprintf("%d", res)) } - params, ok := filter["Loki"].(LokiParams) - if !ok { - return nil, fmt.Errorf("error: failed to assert lokiParams type") + // Set end time if provided + if value, ok := filter["end"]; ok { + res, err := parseToTimestamp(value.(string)) + if err != nil { + return err + } + params.Set("end", fmt.Sprintf("%d", res)) } + queryURL := currency.Address + LokiAddressPath + params.Encode() - // 构建 Loki 查询 URL - queryParams := url.Values{} - queryParams.Add("query", currency.Source+params.Expression) - queryURL := fmt.Sprintf("%s/loki/api/v1/query_range?%s", currency.Address, queryParams.Encode()) - - // 发送 HTTP 请求 + // Send GET request to Loki resp, err := http.Get(queryURL) if err != nil { - return nil, fmt.Errorf("failed to send request to Loki: %w", err) + log.Fatalf("Error sending request to Loki: %v", err) } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected response status: %s", resp.Status) - } - - // 读取响应体 + // Read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("failed to read response body: %w", err) + log.Fatalf("Error reading response from Loki: %v", err) } - // 解析 JSON + // Parse the JSON response var result LokiQueryResult - if err := json.Unmarshal(body, &result); err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %w", err) + err = json.Unmarshal(body, &result) + if err != nil { + log.Fatalf("Error parsing Loki response: %v", err) } - //转换格式 - res, err := ConvertLokiResultToStrings(result) + // Process and print logs + if result.Status == "success" { + for _, stream := range result.Data.Result { + for _, entry := range stream.Values { + // Extract timestamp and log message + timestampStr := entry[0] + logLine := entry[1] + + // Convert nanosecond timestamp to int64 + timestampInt, err := strconv.ParseInt(timestampStr, 10, 64) + if err != nil { + fmt.Printf("Failed to convert timestamp: %v\n", err) + continue + } + + // Convert Unix nanosecond timestamp to readable format + readableTime := time.Unix(0, timestampInt).Format("2006-01-02 15:04:05") + + // Print the readable timestamp and log message + fmt.Printf("Timestamp: %s, Log: %s\n", readableTime, logLine) + } + } + } else { + fmt.Printf("Query failed, status: %s\n", result.Status) + } + return nil +} + +// parseToTimestamp parses a time string to a Unix nanosecond timestamp +func parseToTimestamp(timeStr string) (int64, error) { + // Define the time layout to match the input format + const timeLayout = "2006-01-02-15:04:05" + + // Load the specified time zone (UTC in this case) + loc, err := time.LoadLocation("UTC") if err != nil { - return nil, err + return 0, fmt.Errorf("failed to load timezone: %v", err) } - return res, nil + + // Parse the time string using the specified layout and timezone + t, err := time.ParseInLocation(timeLayout, timeStr, loc) + if err != nil { + return 0, fmt.Errorf("failed to parse time: %v", err) + } + + // Convert to Unix nanosecond timestamp + timestamp := t.UnixNano() + + return timestamp, nil } diff --git a/action/log/utils/interface.go b/action/log/utils/interface.go index 8954a6f..2732abf 100644 --- a/action/log/utils/interface.go +++ b/action/log/utils/interface.go @@ -1,11 +1,24 @@ package utils +import "time" + type LogQuery interface { - // QueryLogs 根据查询条件获取日志 - QueryLogs(filter map[string]interface{}) ([]string, error) + // QueryLogs retrieves logs based on the filter criteria + QueryLogs(filter map[string]interface{}, currency *Currency, number int) error } type Currency struct { Address string `json:"address"` Source string `json:"source"` + Auth string `json:"auth"` +} + +type SeataLog struct { + Timestamp time.Time // Timestamp + LogLevel string // Log level, e.g., INFO, ERROR, etc. + Module string // Log module, e.g., RMHandler, UndoLogManager, etc. + XID string // Global transaction ID + BranchID string // Branch transaction ID + ResourceID string // Resource ID + Message string // Log content } diff --git a/action/root.go b/action/root.go index 105b861..fa94086 100644 --- a/action/root.go +++ b/action/root.go @@ -22,6 +22,7 @@ import ( "github.com/seata/seata-ctl/action/config" "github.com/seata/seata-ctl/action/get" "github.com/seata/seata-ctl/action/k8s" + "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/action/prometheus" "github.com/seata/seata-ctl/action/reload" se "github.com/seata/seata-ctl/action/set" @@ -44,6 +45,7 @@ func init() { k8s.StatusCmd, k8s.ScaleCmd, prometheus.MetricsCmd, + log.LogCmd, ) rootCmd.SetHelpTemplate(common.GetHelpTmplWithOnlyAvailableCmd()) rootCmd.CompletionOptions = cobra.CompletionOptions{ diff --git a/cmd/root.go b/cmd/root.go index 4f5c32e..1702ebb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -25,7 +25,6 @@ import ( "github.com/seata/seata-ctl/action/common" "github.com/seata/seata-ctl/seata" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var ( @@ -44,10 +43,10 @@ func init() { rootCmd.PersistentFlags().IntVar(&credential.ServerPort, "port", 7091, "Seata Server Admin Port") rootCmd.PersistentFlags().StringVar(&credential.Username, "username", "seata", "Username") rootCmd.PersistentFlags().StringVar(&credential.Password, "password", "seata", "Password") - viper.BindPFlag("ip", rootCmd.PersistentFlags().Lookup("ip")) - viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port")) - viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) - viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) + //viper.BindPFlag("ip", rootCmd.PersistentFlags().Lookup("ip")) + //viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port")) + //viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) + //viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) rootCmd.SetHelpCommand(&cobra.Command{ Use: "seata-ctl", Short: "seata-ctl is a CLI tool for Seata", diff --git a/config.yml b/config.yml index 338b1ed..38541d6 100644 --- a/config.yml +++ b/config.yml @@ -12,19 +12,38 @@ prometheus: address: "http://localhost:9092" auth: "" log: - clusters: - - name: "" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" + clusters: + - name: "es" + types: "ElasticSearch" + address: "https://localhost:9200" + source: "seata_logs" + auth: "bu4AC50REtt_7rUqddMe" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" + - name: "loki" + types: "Loki" + address: "http://localhost:3100" + source: "" + auth: "" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" context: kubernetes: "cluster1" prometheus: "prometheus" - log: "" \ No newline at end of file + log: "loki" diff --git a/go 2.sum b/go 2.sum new file mode 100644 index 0000000..2be40d7 --- /dev/null +++ b/go 2.sum @@ -0,0 +1,72 @@ +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/guptarohit/asciigraph v0.7.2/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/go.mod b/go.mod index 486340d..68ba0cd 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/elastic/go-elasticsearch/v8 v8.15.0 github.com/guptarohit/asciigraph v0.7.2 github.com/jedib0t/go-pretty/v6 v6.4.7 + github.com/olivere/elastic/v7 v7.0.32 github.com/spf13/cobra v1.8.1 - github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.31.0 @@ -20,65 +20,46 @@ require ( ) require ( - git.sr.ht/~sbinet/gg v0.5.0 // indirect - github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect - github.com/campoy/embedmd v1.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-fonts/liberation v0.3.3 // indirect - github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-pdf/fpdf v0.9.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.4.2 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/image v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.24.0 // indirect - gonum.org/v1/plot v0.14.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect @@ -86,3 +67,11 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) + +replace github.com/imdario/mergo => github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40 + +replace github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.6 + +replace github.com/json-iterator/go => github.com/json-iterator/go v1.1.10 + +replace github.com/magiconair/properties => github.com/magiconair/properties v1.8.6 diff --git a/go.sum b/go.sum index 5389c2b..da50b4b 100644 --- a/go.sum +++ b/go.sum @@ -1,59 +1,3 @@ -cloud.google.com/go v0.26.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.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= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -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.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= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -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/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= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8= -git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo= -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/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= -github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -66,25 +10,10 @@ github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8 github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-fonts/liberation v0.3.3 h1:tM/T2vEOhjia6v5krQu8SDDegfH1SfXVRUNNKpq0Usk= -github.com/go-fonts/liberation v0.3.3/go.mod h1:eUAzNRuJnpSnd1sm2EyloQfSOT79pdw7X7++Ri+3MCU= -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-latex/latex v0.0.0-20240709081214-31cef3c7570e h1:xcdj0LWnMSIU1j8+jIeJyfvk6SjgJedFQssSqFthJ2E= -github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e/go.mod h1:J4SAGzkcl+28QWi7yz72tyC/4aGnppOvya+AEv4TaAQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -97,106 +26,38 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= -github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -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/groupcache v0.0.0-20190702054246-869f871628b6/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.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= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/guptarohit/asciigraph v0.7.2 h1:pBBJYbMl4j7zS4AwmrfAs6tA0VQOEQC933aG72dlrFA= github.com/guptarohit/asciigraph v0.7.2/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= -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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -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.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40 h1:jNLMZ3OPDHinDH9n3OJ8qjrwxcZfVy+yy47YOyrbD74= +github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -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/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -204,84 +65,53 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -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/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.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 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/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= +github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -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 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.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -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= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -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.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= @@ -291,329 +121,58 @@ go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8 go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -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= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -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/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/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw= -golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM= -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= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/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/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-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-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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 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-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= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -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-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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -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= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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-20190606165138-5da285871e9c/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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-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= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -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/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-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-20190621195816-6e04913cbbac/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-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= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -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-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= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -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-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= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -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-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.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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= -gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= -gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= -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= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -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.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= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -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= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -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-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= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -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-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= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -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-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-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= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/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-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= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -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= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -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.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/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= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -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= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= @@ -628,9 +187,6 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/model/config.go b/model/config.go index 8d84b3c..db5a793 100644 --- a/model/config.go +++ b/model/config.go @@ -43,6 +43,7 @@ type Cluster struct { Types string `yaml:"types"` Address string `yaml:"address"` Source string `yaml:"source"` + Auth string `yaml:"auth"` Collection Collection `yaml:"collection"` Analysis Analysis `yaml:"analysis"` Display Display `yaml:"display"` From 86542838e3c2ffc80966aecc8ac5257d44b00da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 18 Oct 2024 23:51:36 +0800 Subject: [PATCH 11/30] =?UTF-8?q?loki=20=E5=B8=B8=E9=87=8F=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/log/utils/impl/loki.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/action/log/utils/impl/loki.go b/action/log/utils/impl/loki.go index 8a1b00b..b62f453 100644 --- a/action/log/utils/impl/loki.go +++ b/action/log/utils/impl/loki.go @@ -14,6 +14,7 @@ import ( const ( LokiAddressPath = "/loki/api/v1/query_range?" + TimeLayout = "2006-01-02-15:04:05" ) type Loki struct{} @@ -106,9 +107,6 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *utils.Currency // parseToTimestamp parses a time string to a Unix nanosecond timestamp func parseToTimestamp(timeStr string) (int64, error) { - // Define the time layout to match the input format - const timeLayout = "2006-01-02-15:04:05" - // Load the specified time zone (UTC in this case) loc, err := time.LoadLocation("UTC") if err != nil { @@ -116,7 +114,7 @@ func parseToTimestamp(timeStr string) (int64, error) { } // Parse the time string using the specified layout and timezone - t, err := time.ParseInLocation(timeLayout, timeStr, loc) + t, err := time.ParseInLocation(TimeLayout, timeStr, loc) if err != nil { return 0, fmt.Errorf("failed to parse time: %v", err) } From c4cc56ed80f9419beb58e154a6eb37b4124965ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sat, 19 Oct 2024 17:02:44 +0800 Subject: [PATCH 12/30] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E7=BB=9F=E4=B8=80=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/config/config.go | 19 +++++++------- action/k8s/deploy.go | 16 ++++++++---- action/k8s/install.go | 13 +++++++--- action/k8s/status.go | 6 ++--- action/k8s/undeploy.go | 2 +- action/k8s/uninstall.go | 36 +++++++++++++++++++++------ action/k8s/utils/http.go | 4 +-- action/k8s/utils/request.go | 10 ++++---- action/log/log.go | 8 +++--- config.yml | 49 ------------------------------------- 10 files changed, 72 insertions(+), 91 deletions(-) delete mode 100644 config.yml diff --git a/action/config/config.go b/action/config/config.go index 1780dad..85e0909 100644 --- a/action/config/config.go +++ b/action/config/config.go @@ -9,7 +9,7 @@ import ( "os" ) -var Path = "/" +var Path string var ConfigCmd = &cobra.Command{ Use: "config", @@ -20,12 +20,11 @@ var ConfigCmd = &cobra.Command{ println("Error creating config:", err.Error()) log.Fatal(err) } - println("Config created successfully!") }, } func init() { - ConfigCmd.PersistentFlags().StringVar(&Path, "path", "/", "Set config path") + ConfigCmd.PersistentFlags().StringVar(&Path, "path", "", "Set config path") } func createSampleConfig() model.Config { @@ -79,14 +78,15 @@ func createSampleConfig() model.Config { // Create a YAML file func createYMLFile(path string) error { // Check if the path exists - if _, err := os.Stat(path); os.IsNotExist(err) { - return fmt.Errorf("path does not exist: %s", path) - } + //if _, err := os.Stat(path); os.IsNotExist(err) { + // return fmt.Errorf("path does not exist: %s", path) + //} // Check if the file already exists - ymlFilePath := path + "config.yml" + ymlFilePath := "config.yml" if _, err := os.Stat(ymlFilePath); err == nil { - return fmt.Errorf("file already exists: %s", path) + fmt.Println("Config file already exists!") + return nil } // Create a sample config object @@ -113,8 +113,7 @@ func createYMLFile(path string) error { if err != nil { log.Fatalf("Failed to write to YAML config: %v", err) } - fmt.Println("YAML config created successfully") - + fmt.Println("Config created successfully!") // Update the path variable Path = path return nil diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index 2c00d53..32f094c 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -10,16 +10,22 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -const Image = "apache/seata-server:latest" -const ServiceName = "seata-server-cluster" -const RequestStorage = "1Gi" -const LimitStorage = "1Gi" +const ( + Image = "apache/seata-server:latest" + ServiceName = "seata-server-cluster" + RequestStorage = "1Gi" + LimitStorage = "1Gi" +) var DeployCmd = &cobra.Command{ Use: "deploy", Short: "deploy seata in k8s", Run: func(cmd *cobra.Command, args []string) { - deploy() + err := deploy() + if err != nil { + fmt.Println(err) + } + }, } diff --git a/action/k8s/install.go b/action/k8s/install.go index 7ca4089..4952b2a 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -19,6 +19,14 @@ import ( "log" ) +const ( + CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" + FilePath = "seata.yaml" + + CRDname = "seataservers.operator.seata.apache.org" + Deployname = "seata-k8s-controller-manager" +) + var InstallCmd = &cobra.Command{ Use: "install", Short: "Install Kubernetes CRD controller", @@ -38,9 +46,6 @@ func init() { InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") } -const CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" -const FilePath = "seata.yaml" - // DeployCRD deploys the custom resource definition. func DeployCRD() error { res, err := utils.CreateRequest(CreateCrdPath, FilePath) @@ -60,7 +65,7 @@ func DeployController() error { } // Define the Deployment name and namespace - deploymentName := "seata-k8s-controller-manager" + deploymentName := Deployname namespace := Namespace // Check if the Deployment already exists diff --git a/action/k8s/status.go b/action/k8s/status.go index 8c8465b..5668ccb 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -56,9 +56,9 @@ func getPodsStatusByLabel(namespace, labelSelector string) ([]string, error) { // Iterate over all Pods and get their status var statuses []string - for _, pod := range pods.Items { - statuses = append(statuses, fmt.Sprintf("Pod %s is in %s phase", pod.Name, pod.Status.Phase)) - } + //for _, pod := range pods.Items { + // statuses = append(statuses, fmt.Sprintf("Pod %s is in %s phase", pod.Name, pod.Status.Phase)) + //} // Build formatted status string for output statuses = append(statuses, fmt.Sprintf("%-25s %-10s", "POD NAME", "STATUS")) // Header diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go index cce5bc3..5b7e6a4 100644 --- a/action/k8s/undeploy.go +++ b/action/k8s/undeploy.go @@ -11,7 +11,7 @@ import ( var UnDeployCmd = &cobra.Command{ Use: "undeploy", - Short: "deploy seata in k8s", + Short: "undeploy seata in k8s", Run: func(cmd *cobra.Command, args []string) { err := undeploy() if err != nil { diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index e3885a9..de99fb3 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -5,13 +5,12 @@ import ( "fmt" "github.com/seata/seata-ctl/action/k8s/utils" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "log" ) -const CRDname = "seataservers.operator.seata.apache.org" - var UnInstallCmd = &cobra.Command{ Use: "uninstall", Short: "uninstall seata in k8s", @@ -43,11 +42,22 @@ func UninstallCRD() error { Resource: "customresourcedefinitions", } + // Assume client and gvr have already been defined err = client.Resource(gvr).Delete(context.TODO(), CRDname, metav1.DeleteOptions{}) if err != nil { - log.Fatalf("delete CRD failed: %v", err) + // Check if the error is a "not found" error + if errors.IsNotFound(err) { + // The resource does not exist, output a message instead of returning an error + fmt.Printf("CRD %s does not exist, no action taken.\n", CRDname) + } else { + // For other errors, log the error and exit the program + log.Fatalf("delete CRD failed: %v", err) + } + } else { + // Successfully deleted the resource + fmt.Printf("CRD %s deleted successfully.\n", CRDname) } - fmt.Printf("delete CRD success,name: %s\n", "seataservers.operator.seata.apache.org") + return nil } @@ -56,10 +66,20 @@ func UnDeploymentController() error { if err != nil { return err } - err = clientset.AppsV1().Deployments(Namespace).Delete(context.TODO(), "seata-k8s-controller-manager", metav1.DeleteOptions{}) + // Assume clientset has already been defined + err = clientset.AppsV1().Deployments(Namespace).Delete(context.TODO(), Deployname, metav1.DeleteOptions{}) if err != nil { - log.Fatalf("Error creating deployment: %s", err.Error()) + // Check if the error is a "not found" error + if errors.IsNotFound(err) { + // The deployment does not exist, output a message instead of returning an error + fmt.Printf("Deployment 'seata-k8s-controller-manager' does not exist in namespace '%s', no action taken.\n", Namespace) + } else { + // For other errors, log the error and exit the program + log.Fatalf("Error deleting deployment: %s", err.Error()) + } + } else { + // Successfully deleted the deployment + fmt.Printf("Deployment 'seata-k8s-controller-manager' deleted successfully from namespace '%s'.\n", Namespace) } - fmt.Println("Deployment created successfully") - return err + return nil } diff --git a/action/k8s/utils/http.go b/action/k8s/utils/http.go index 5011f68..cb002a3 100644 --- a/action/k8s/utils/http.go +++ b/action/k8s/utils/http.go @@ -160,10 +160,10 @@ func sendPostRequest(context *ContextInfo, createCrdPath string, filePath string // Return appropriate response based on status code if resp.StatusCode == http.StatusCreated { - return "create seata crd success", nil + return "Create seata crd success", nil } if resp.StatusCode == http.StatusConflict { - return "seata crd already exists", nil + return "Seata crd already exists", nil } else { return "error: " + string(body), err } diff --git a/action/k8s/utils/request.go b/action/k8s/utils/request.go index 6a21c61..334bc52 100644 --- a/action/k8s/utils/request.go +++ b/action/k8s/utils/request.go @@ -6,26 +6,26 @@ func CreateRequest(createCrdPath string, filePath string) (string, error) { kubeConfigPath, err := GetKubeConfigPath() if err != nil { - return "", fmt.Errorf("failed to get kubeconfig path: %v", err) + return "", fmt.Errorf("Failed to get kubeconfig path: %v", err) } kubeConfig, err := LoadKubeConfig(kubeConfigPath) if err != nil { - return "", fmt.Errorf("failed to load kubeconfig file: %v", err) + return "", fmt.Errorf("Failed to load kubeconfig file: %v", err) } contextInfo, err := GetContextInfo(kubeConfig) if err != nil { - return "", fmt.Errorf("failed to get context info: %v", err) + return "", fmt.Errorf("Failed to get context info: %v", err) } filePath, err = ConvertAndSaveYamlToJSON(filePath) if err != nil { - return "", fmt.Errorf("failed to save yaml: %v", err) + return "", fmt.Errorf("Failed to save yaml: %v", err) } res, err := sendPostRequest(contextInfo, createCrdPath, filePath) if err != nil { - return res, fmt.Errorf("failed to send post request: %v", err) + return res, fmt.Errorf("Failed to send post request: %v", err) } return res, nil } diff --git a/action/log/log.go b/action/log/log.go index 50c5503..0c179a1 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -47,13 +47,13 @@ var Start string var End string func init() { - LogCmd.PersistentFlags().StringVar(&LogLevel, "level", "", "seata log level") - LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") + LogCmd.PersistentFlags().StringVar(&LogLevel, "Level", "", "seata log level") + LogCmd.PersistentFlags().StringVar(&Module, "Module", "", "seata module") LogCmd.PersistentFlags().StringVar(&XID, "XID", "", "seata expression") LogCmd.PersistentFlags().StringVar(&BranchID, "BranchID", "", "seata branchId") LogCmd.PersistentFlags().StringVar(&ResourceID, "ResourceID", "", "seata resourceID") - LogCmd.PersistentFlags().StringVar(&Message, "message", "", "seata message") - LogCmd.PersistentFlags().IntVar(&Number, "number", DefaultNumber, "seata number") + LogCmd.PersistentFlags().StringVar(&Message, "Message", "", "seata message") + LogCmd.PersistentFlags().IntVar(&Number, "Number", DefaultNumber, "seata number") LogCmd.PersistentFlags().StringVar(&Label, "label", "", "seata label") LogCmd.PersistentFlags().StringVar(&Start, "start", "", "seata start") LogCmd.PersistentFlags().StringVar(&End, "end", "", "seata end") diff --git a/config.yml b/config.yml deleted file mode 100644 index 38541d6..0000000 --- a/config.yml +++ /dev/null @@ -1,49 +0,0 @@ -kubernetes: - clusters: - - name: "cluster1" - kubeconfigpath: "/Users/wpy/.kube/config" - ymlpath: "" - - name: "seata" - kubeconfigpath: "/Users/wpy/Documents/Kubernetes/remotekube.txt" - ymlpath: "" -prometheus: - servers: - - name: "prometheus" - address: "http://localhost:9092" - auth: "" -log: - clusters: - - name: "es" - types: "ElasticSearch" - address: "https://localhost:9200" - source: "seata_logs" - auth: "bu4AC50REtt_7rUqddMe" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" - - name: "loki" - types: "Loki" - address: "http://localhost:3100" - source: "" - auth: "" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" -context: - kubernetes: "cluster1" - prometheus: "prometheus" - log: "loki" From 785ff53521262384f67849ee74863c3124fccd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Tue, 22 Oct 2024 23:16:57 +0800 Subject: [PATCH 13/30] =?UTF-8?q?=E5=88=A0=E9=99=A4go2.sum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.yml | 49 +++++++++++++++++++++++++++++++++++++ go 2.sum | 72 ------------------------------------------------------ 2 files changed, 49 insertions(+), 72 deletions(-) create mode 100644 config.yml delete mode 100644 go 2.sum diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..7d311e7 --- /dev/null +++ b/config.yml @@ -0,0 +1,49 @@ +kubernetes: + clusters: + - name: "cluster1" + kubeconfigpath: "/Users/wpy/.kube/config" + ymlpath: "" + - name: "seata" + kubeconfigpath: "/Users/wpy/Documents/Kubernetes/remotekube.txt" + ymlpath: "" +prometheus: + servers: + - name: "prometheus" + address: "http://localhost:9092" + auth: "" +log: + clusters: + - name: "es" + types: "ElasticSearch" + address: "https://localhost:9200" + source: "seata_logs" + auth: "bu4AC50REtt_7rUqddMe" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" + - name: "loki" + types: "Loki" + address: "http://localhost:3100" + source: "" + auth: "" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" +context: + kubernetes: "cluster1" + prometheus: "prometheus" + log: "loki" diff --git a/go 2.sum b/go 2.sum deleted file mode 100644 index 2be40d7..0000000 --- a/go 2.sum +++ /dev/null @@ -1,72 +0,0 @@ -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/guptarohit/asciigraph v0.7.2/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= -github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From d7a6545958390b01daee8746014caf049b2562f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Wed, 23 Oct 2024 00:38:20 +0800 Subject: [PATCH 14/30] fix code --- action/common/parser.go | 34 --------------- action/k8s/deploy.go | 19 ++++---- action/k8s/install.go | 7 ++- action/log/log.go | 43 +++++++++---------- .../impl => logadapter}/elasticsearch.go | 13 +++--- action/log/{utils => logadapter}/interface.go | 2 +- action/log/{utils/impl => logadapter}/loki.go | 5 +-- action/log/utils/impl/local.go | 12 ------ action/prometheus/metrics.go | 4 +- action/root.go | 6 +-- cmd/root.go | 30 ++++++++----- qodana.yaml | 29 ------------- 12 files changed, 69 insertions(+), 135 deletions(-) delete mode 100644 action/common/parser.go rename action/log/{utils/impl => logadapter}/elasticsearch.go (91%) rename action/log/{utils => logadapter}/interface.go (97%) rename action/log/{utils/impl => logadapter}/loki.go (97%) delete mode 100644 action/log/utils/impl/local.go delete mode 100644 qodana.yaml diff --git a/action/common/parser.go b/action/common/parser.go deleted file mode 100644 index bb18dc4..0000000 --- a/action/common/parser.go +++ /dev/null @@ -1,34 +0,0 @@ -package common - -import ( - "fmt" - "github.com/seata/seata-ctl/model" - "gopkg.in/yaml.v3" - "io/ioutil" - "os" -) - -// ReadYMLFile 读取并解析 YAML 文件 -func ReadYMLFile(path string) (model.Config, error) { - var config model.Config - - // 检查文件是否存在 - //ymlFilePath := path + "config.yml" - if _, err := os.Stat("config.yml"); os.IsNotExist(err) { - return config, fmt.Errorf("file does not exist: %s", path) - } - - // 读取文件内容 - data, err := ioutil.ReadFile(path) - if err != nil { - return config, fmt.Errorf("failed to read file: %v", err) - } - - // 解析 YAML 内容 - err = yaml.Unmarshal(data, &config) - if err != nil { - return config, fmt.Errorf("failed to unmarshal YAML: %v", err) - } - - return config, nil -} diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index 32f094c..b5ff21d 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -11,10 +11,10 @@ import ( ) const ( - Image = "apache/seata-server:latest" - ServiceName = "seata-server-cluster" - RequestStorage = "1Gi" - LimitStorage = "1Gi" + DefaultServerImage = "apache/seata-server:latest" + ServiceName = "seata-server-cluster" + RequestStorage = "1Gi" + LimitStorage = "1Gi" ) var DeployCmd = &cobra.Command{ @@ -25,18 +25,21 @@ var DeployCmd = &cobra.Command{ if err != nil { fmt.Println(err) } - }, } -var Name string -var Replicas int32 -var Namespace string +var ( + Name string + Replicas int32 + Namespace string + Image string +) func init() { DeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") DeployCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + DeployCmd.PersistentFlags().StringVar(&Image, "image", DefaultServerImage, "Seata server image") } func deploy() error { diff --git a/action/k8s/install.go b/action/k8s/install.go index 4952b2a..73d09af 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -25,6 +25,8 @@ const ( CRDname = "seataservers.operator.seata.apache.org" Deployname = "seata-k8s-controller-manager" + + DefaultControllerImage = "apache/seata-controller:latest" ) var InstallCmd = &cobra.Command{ @@ -42,8 +44,11 @@ var InstallCmd = &cobra.Command{ }, } +var ControllerImage string + func init() { InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + InstallCmd.PersistentFlags().StringVar(&ControllerImage, "image", DefaultControllerImage, "Namespace name") } // DeployCRD deploys the custom resource definition. @@ -105,7 +110,7 @@ func DeployController() error { Containers: []corev1.Container{ { Name: deploymentName, - Image: "bearslyricattack/seata-controller:latest", + Image: ControllerImage, Ports: []corev1.ContainerPort{ { ContainerPort: 80, diff --git a/action/log/log.go b/action/log/log.go index 0c179a1..346fdd2 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -2,8 +2,7 @@ package log import ( "fmt" - "github.com/seata/seata-ctl/action/log/utils" - "github.com/seata/seata-ctl/action/log/utils/impl" + "github.com/seata/seata-ctl/action/log/logadapter" "github.com/seata/seata-ctl/model" "github.com/spf13/cobra" "gopkg.in/yaml.v3" @@ -31,20 +30,22 @@ var LogCmd = &cobra.Command{ } // ElasticSearch - -var LogLevel string -var Module string -var XID string -var BranchID string -var ResourceID string -var Message string -var Number int +var ( + LogLevel string + Module string + XID string + BranchID string + ResourceID string + Message string + Number int +) // Loki - -var Label string -var Start string -var End string +var ( + Label string + Start string + End string +) func init() { LogCmd.PersistentFlags().StringVar(&LogLevel, "Level", "", "seata log level") @@ -66,24 +67,20 @@ func getLog() error { } logType := context.Types - var client utils.LogQuery + var client logadapter.LogQuery var filter = make(map[string]interface{}) switch logType { case ElasticSearchType: { - client = &impl.Elasticsearch{} + client = &logadapter.Elasticsearch{} filter = buildElasticSearchFilter() } case LokiType: { - client = &impl.Loki{} + client = &logadapter.Loki{} filter = buildLokiFilter() } - //case "Local": - // { - // return &impl.Local{}, nil, nil - // } } if client == nil { @@ -101,7 +98,7 @@ func getLog() error { return nil } -func getContext() (*model.Cluster, *utils.Currency, error) { +func getContext() (*model.Cluster, *logadapter.Currency, error) { file, err := os.ReadFile("config.yml") if err != nil { log.Fatalf("Failed to read config.yml: %v", err) @@ -114,7 +111,7 @@ func getContext() (*model.Cluster, *utils.Currency, error) { contextName := config.Context.Log for _, cluster := range config.Log.Clusters { if cluster.Name == contextName { - currency := utils.Currency{ + currency := logadapter.Currency{ Address: cluster.Address, Source: cluster.Source, Auth: cluster.Auth, diff --git a/action/log/utils/impl/elasticsearch.go b/action/log/logadapter/elasticsearch.go similarity index 91% rename from action/log/utils/impl/elasticsearch.go rename to action/log/logadapter/elasticsearch.go index 1a5c471..d759727 100644 --- a/action/log/utils/impl/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -1,4 +1,4 @@ -package impl +package logadapter import ( "context" @@ -7,7 +7,6 @@ import ( "errors" "fmt" "github.com/olivere/elastic/v7" - "github.com/seata/seata-ctl/action/log/utils" "log" "net/http" ) @@ -19,7 +18,7 @@ const ( type Elasticsearch struct{} // QueryLogs is a function that queries specific documents -func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *utils.Currency, number int) error { +func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { client, err := createElasticClient(currency) if err != nil { return fmt.Errorf("failed to create elasticsearch client: %w", err) @@ -49,7 +48,7 @@ func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *utils } // createElasticClient configures and creates a new Elasticsearch client -func createElasticClient(currency *utils.Currency) (*elastic.Client, error) { +func createElasticClient(currency *Currency) (*elastic.Client, error) { httpClient := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ @@ -75,8 +74,6 @@ func processSearchHits(searchResult *elastic.SearchResult) []string { var result []string for _, hit := range searchResult.Hits.Hits { - fmt.Printf("=== Document ID: %s ===\n", hit.Id) - var doc map[string]interface{} if err := json.Unmarshal(hit.Source, &doc); err != nil { log.Printf("Error parsing document: %s", err) @@ -86,9 +83,9 @@ func processSearchHits(searchResult *elastic.SearchResult) []string { // Pretty print the document content fmt.Println("Document Source:") for key, value := range doc { - fmt.Printf(" %s: %v\n", key, value) + log.Printf(" %s: %v", key, value) } - fmt.Println("----------------------------") + log.Println("----------------------------") result = append(result, hit.Id) // Store document IDs or other relevant data } diff --git a/action/log/utils/interface.go b/action/log/logadapter/interface.go similarity index 97% rename from action/log/utils/interface.go rename to action/log/logadapter/interface.go index 2732abf..b887934 100644 --- a/action/log/utils/interface.go +++ b/action/log/logadapter/interface.go @@ -1,4 +1,4 @@ -package utils +package logadapter import "time" diff --git a/action/log/utils/impl/loki.go b/action/log/logadapter/loki.go similarity index 97% rename from action/log/utils/impl/loki.go rename to action/log/logadapter/loki.go index b62f453..337d511 100644 --- a/action/log/utils/impl/loki.go +++ b/action/log/logadapter/loki.go @@ -1,9 +1,8 @@ -package impl +package logadapter import ( "encoding/json" "fmt" - "github.com/seata/seata-ctl/action/log/utils" "io/ioutil" "log" "net/http" @@ -32,7 +31,7 @@ type LokiQueryResult struct { } // QueryLogs queries logs from Loki based on the filter and settings provided -func (l *Loki) QueryLogs(filter map[string]interface{}, currency *utils.Currency, number int) error { +func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { // Prepare the query URL with time range params := url.Values{} diff --git a/action/log/utils/impl/local.go b/action/log/utils/impl/local.go deleted file mode 100644 index 4903b79..0000000 --- a/action/log/utils/impl/local.go +++ /dev/null @@ -1,12 +0,0 @@ -package impl - -type Local struct{} - -// 日志响应结构 -type LogsResponse struct { - Logs map[string]string `json:"logs"` // 日志内容以节点名为键,日志内容为值 -} - -func (l *Local) QueryLogs(filter map[string]interface{}) ([]string, error) { - return nil, nil -} diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 51767a8..87c2640 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -125,12 +125,12 @@ func generateTerminalLineChart(response *PrometheusResponse, metricName string) if valueStr, ok := result.Value[1].(string); ok { value, err := strconv.ParseFloat(valueStr, 64) if err != nil { - fmt.Println("Value: Invalid number format") + return fmt.Errorf("error converting value to float: %v", err) } else { yValues = append(yValues, value) } } else { - fmt.Println("Value: Invalid value format") + return fmt.Errorf("error converting value to float: %v", result.Value[1]) } } } diff --git a/action/root.go b/action/root.go index fa94086..3e86001 100644 --- a/action/root.go +++ b/action/root.go @@ -1,9 +1,9 @@ /* * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE config distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. - * The ASF licenses this config to You under the Apache License, Version 2.0 - * (the "License"); you may not use this config except in compliance with + * The ASF licenses this file to You 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 diff --git a/cmd/root.go b/cmd/root.go index 1702ebb..47b2ebe 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -25,6 +25,7 @@ import ( "github.com/seata/seata-ctl/action/common" "github.com/seata/seata-ctl/seata" "github.com/spf13/cobra" + "github.com/spf13/viper" ) var ( @@ -43,10 +44,10 @@ func init() { rootCmd.PersistentFlags().IntVar(&credential.ServerPort, "port", 7091, "Seata Server Admin Port") rootCmd.PersistentFlags().StringVar(&credential.Username, "username", "seata", "Username") rootCmd.PersistentFlags().StringVar(&credential.Password, "password", "seata", "Password") - //viper.BindPFlag("ip", rootCmd.PersistentFlags().Lookup("ip")) - //viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port")) - //viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) - //viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) + viper.BindPFlag("ip", rootCmd.PersistentFlags().Lookup("ip")) + viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port")) + viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) + viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) rootCmd.SetHelpCommand(&cobra.Command{ Use: "seata-ctl", Short: "seata-ctl is a CLI tool for Seata", @@ -67,21 +68,28 @@ func Execute() { fmt.Fprintln(os.Stderr, err) os.Exit(1) } + + var address = "" + for _, arg := range os.Args { if arg == "-h" || arg == "--help" || arg == "version" { os.Exit(0) } + if arg == "--login" || arg == "login" { + address = seata.GetAuth().GetAddress() + err := seata.GetAuth().Login() + if err != nil { + fmt.Println("login failed!") + os.Exit(1) + } + } } - //address := seata.GetAuth().GetAddress() - //err := seata.GetAuth().Login() - //if err != nil { - // fmt.Println("login failed!") - // os.Exit(1) - //} var err error for { - //printPrompt(address) + if address != "" { + printPrompt(address) + } err = common.ReadArgs(os.Stdin) if err != nil { fmt.Println(err) diff --git a/qodana.yaml b/qodana.yaml deleted file mode 100644 index 215d808..0000000 --- a/qodana.yaml +++ /dev/null @@ -1,29 +0,0 @@ -#-------------------------------------------------------------------------------# -# Qodana analysis is configured by qodana.yaml file # -# https://www.jetbrains.com/help/qodana/qodana-yaml.html # -#-------------------------------------------------------------------------------# -version: "1.0" - -#Specify inspection profile for code analysis -profile: - name: qodana.starter - -#Enable inspections -#include: -# - name: - -#Disable inspections -#exclude: -# - name: -# paths: -# - - -#Execute shell command before Qodana execution (Applied in CI/CD pipeline) -#bootstrap: sh ./prepare-qodana.sh - -#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) -#plugins: -# - id: #(plugin id can be found at https://plugins.jetbrains.com) - -#Specify Qodana linter for analysis (Applied in CI/CD pipeline) -linter: jetbrains/qodana-go:latest From 175bcd22a8c12884f4dc96e3c89b12ba45d0e69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Fri, 25 Oct 2024 16:40:46 +0800 Subject: [PATCH 15/30] add local log system client and fix bug. --- action/k8s/scale.go | 6 ++- action/log/log.go | 33 +++++++++++---- action/log/logadapter/local.go | 77 ++++++++++++++++++++++++++++++++++ config.yml | 19 ++++++++- seata.json | 1 - 5 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 action/log/logadapter/local.go delete mode 100644 seata.json diff --git a/action/k8s/scale.go b/action/k8s/scale.go index 329e679..e9eef42 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -10,6 +10,10 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +const ( + DefaultReplicas = 1 +) + var ScaleCmd = &cobra.Command{ Use: "scale", Short: "scale seata in k8s", @@ -23,7 +27,7 @@ var ScaleCmd = &cobra.Command{ func init() { ScaleCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") - ScaleCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") + ScaleCmd.PersistentFlags().Int32Var(&Replicas, "replicas", DefaultReplicas, "Replicas number") ScaleCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") } diff --git a/action/log/log.go b/action/log/log.go index 346fdd2..f868637 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -13,11 +13,17 @@ import ( const ( ElasticSearchType = "ElasticSearch" DefaultNumber = 10 + DefaultLogLevel = "" ) + const ( LokiType = "Loki" ) +const ( + LocalType = "Local" +) + var LogCmd = &cobra.Command{ Use: "log", Short: "get seata log", @@ -48,13 +54,13 @@ var ( ) func init() { - LogCmd.PersistentFlags().StringVar(&LogLevel, "Level", "", "seata log level") - LogCmd.PersistentFlags().StringVar(&Module, "Module", "", "seata module") - LogCmd.PersistentFlags().StringVar(&XID, "XID", "", "seata expression") - LogCmd.PersistentFlags().StringVar(&BranchID, "BranchID", "", "seata branchId") - LogCmd.PersistentFlags().StringVar(&ResourceID, "ResourceID", "", "seata resourceID") - LogCmd.PersistentFlags().StringVar(&Message, "Message", "", "seata message") - LogCmd.PersistentFlags().IntVar(&Number, "Number", DefaultNumber, "seata number") + LogCmd.PersistentFlags().StringVar(&LogLevel, "level", DefaultLogLevel, "seata log level") + LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") + LogCmd.PersistentFlags().StringVar(&XID, "xid", "", "seata expression") + LogCmd.PersistentFlags().StringVar(&BranchID, "banchID", "", "seata branchId") + LogCmd.PersistentFlags().StringVar(&ResourceID, "resourceID", "", "seata resourceID") + LogCmd.PersistentFlags().StringVar(&Message, "message", "", "seata message") + LogCmd.PersistentFlags().IntVar(&Number, "number", DefaultNumber, "seata number") LogCmd.PersistentFlags().StringVar(&Label, "label", "", "seata label") LogCmd.PersistentFlags().StringVar(&Start, "start", "", "seata start") LogCmd.PersistentFlags().StringVar(&End, "end", "", "seata end") @@ -81,6 +87,11 @@ func getLog() error { client = &logadapter.Loki{} filter = buildLokiFilter() } + case LocalType: + { + client = &logadapter.Local{} + filter = buildLocalFilter() + } } if client == nil { @@ -148,14 +159,20 @@ func buildElasticSearchFilter() map[string]interface{} { func buildLokiFilter() map[string]interface{} { filter := make(map[string]interface{}) filter["query"] = Label - filter["number"] = Number if Start != "" { filter["start"] = Start } if End != "" { filter["end"] = End } + return filter +} +func buildLocalFilter() map[string]interface{} { + filter := make(map[string]interface{}) + if LogLevel != "" { + filter["logLevel"] = LogLevel + } return filter } diff --git a/action/log/logadapter/local.go b/action/log/logadapter/local.go new file mode 100644 index 0000000..960c10a --- /dev/null +++ b/action/log/logadapter/local.go @@ -0,0 +1,77 @@ +package logadapter + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +const ( + QueryPath = "/query" +) + +// LogData represents a single log entry +type LogData struct { + Timestamp string `json:"timestamp"` + LogLevel string `json:"log_level"` + LogMessage string `json:"log_message"` +} + +// QueryResponse holds the response structure from the /query API +type QueryResponse struct { + ApplicationID string `json:"application_id"` + LogLevel string `json:"log_level"` + Logs []LogData `json:"logs"` +} + +// Local is the struct implementing the logging logic +type Local struct{} + +// QueryLogs sends a request to the /query endpoint and retrieves logs based on the provided filter. +// - filter: A map that holds log filtering parameters such as log level. +// - currency: A struct containing information like the source application and API address. +// - number: The number of logs to fetch (limit). +func (l *Local) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { + logLevel, ok := filter["logLevel"].(string) + if !ok { + return fmt.Errorf("logLevel is missing or invalid in the filter") + } + + // Build the query URL using the filter and currency information + url := fmt.Sprintf("%s%s?application_id=%s&log_level=%s&limit=%d", currency.Address, QueryPath, currency.Source, logLevel, number) + + // Send a GET request to the /query endpoint + resp, err := http.Get(url) + if err != nil { + return fmt.Errorf("failed to make request to %s: %v", url, err) + } + defer resp.Body.Close() + + // Read the response body + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to read response body: %v", err) + } + + // Check if the response status is OK (200) + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("received non-200 response status: %d", resp.StatusCode) + } + + // Parse the JSON response body into QueryResponse struct + var queryResponse QueryResponse + err = json.Unmarshal(body, &queryResponse) + if err != nil { + return fmt.Errorf("failed to parse JSON response: %v", err) + } + + // Print the logs in a structured format + fmt.Printf("Application ID: %s\n", queryResponse.ApplicationID) + fmt.Printf("Log Level: %s\n", queryResponse.LogLevel) + fmt.Println("Logs:") + for _, logData := range queryResponse.Logs { + fmt.Printf("[%s] [%s]: %s\n", logData.Timestamp, logData.LogLevel, logData.LogMessage) + } + return nil +} diff --git a/config.yml b/config.yml index 7d311e7..b8b1775 100644 --- a/config.yml +++ b/config.yml @@ -16,7 +16,7 @@ log: - name: "es" types: "ElasticSearch" address: "https://localhost:9200" - source: "seata_logs" + source: "logstash-2024.10.24" auth: "bu4AC50REtt_7rUqddMe" collection: enable: true @@ -43,7 +43,22 @@ log: displayType: "" path: "" local: "" + - name: "local" + types: "Local" + address: "http://localhost:8080" + source: "seata" + auth: "" + collection: + enable: true + local: "" + analysis: + enable: true + local: "" + display: + displayType: "" + path: "" + local: "" context: kubernetes: "cluster1" prometheus: "prometheus" - log: "loki" + log: "local" diff --git a/seata.json b/seata.json deleted file mode 100644 index 0606a2b..0000000 --- a/seata.json +++ /dev/null @@ -1 +0,0 @@ -{"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{"controller-gen.kubebuilder.io/version":"v0.13.0"},"name":"seataservers.operator.seata.apache.org"},"spec":{"group":"operator.seata.apache.org","names":{"kind":"SeataServer","listKind":"SeataServerList","plural":"seataservers","singular":"seataserver"},"scope":"Namespaced","versions":[{"name":"v1alpha1","schema":{"openAPIV3Schema":{"description":"SeataServer is the Schema for the seataservers 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":"SeataServerSpec defines the desired state of SeataServer","properties":{"containerName":{"default":"seata-server","type":"string"},"env":{"additionalProperties":{"type":"string"},"type":"object"},"image":{"type":"string"},"ports":{"properties":{"consolePort":{"default":7091,"format":"int32","type":"integer"},"raftPort":{"default":9091,"format":"int32","type":"integer"},"servicePort":{"default":8091,"format":"int32","type":"integer"}},"type":"object"},"replicas":{"default":1,"format":"int32","minimum":1,"type":"integer"},"resources":{"description":"ResourceRequirements describes the compute resource requirements.","properties":{"claims":{"description":"Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable. It can only be set for containers.","items":{"description":"ResourceClaim references one entry in PodSpec.ResourceClaims.","properties":{"name":{"description":"Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.","type":"string"}},"required":["name"],"type":"object"},"type":"array","x-kubernetes-list-map-keys":["name"],"x-kubernetes-list-type":"map"},"limits":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"},"requests":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"}},"type":"object"},"serviceName":{"default":"seata-server","type":"string"},"store":{"properties":{"resources":{"description":"ResourceRequirements describes the compute resource requirements.","properties":{"claims":{"description":"Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable. It can only be set for containers.","items":{"description":"ResourceClaim references one entry in PodSpec.ResourceClaims.","properties":{"name":{"description":"Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.","type":"string"}},"required":["name"],"type":"object"},"type":"array","x-kubernetes-list-map-keys":["name"],"x-kubernetes-list-type":"map"},"limits":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"},"requests":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"string"}],"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","x-kubernetes-int-or-string":true},"description":"Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object"}},"type":"object"}},"required":["resources"],"type":"object"}},"required":["image","store"],"type":"object"},"status":{"description":"SeataServerStatus defines the observed state of SeataServer","properties":{"readyReplicas":{"format":"int32","type":"integer"},"replicas":{"format":"int32","type":"integer"},"synchronized":{"type":"boolean"}},"required":["replicas","synchronized"],"type":"object"}},"type":"object"}},"served":true,"storage":true,"subresources":{"status":{}}}]}} \ No newline at end of file From 1d4addff81541f464c66dbc28cac8b9fe63d76de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sat, 26 Oct 2024 18:39:15 +0800 Subject: [PATCH 16/30] fix bug. --- action/k8s/deploy.go | 8 +++--- action/k8s/install.go | 19 +++++++------- action/k8s/scale.go | 8 +++--- action/k8s/status.go | 12 ++++----- action/k8s/undeploy.go | 8 +++--- action/k8s/uninstall.go | 26 +++++++++---------- action/k8s/utils/file.go | 32 ++++++++++++----------- action/log/log.go | 42 ++++++++----------------------- action/log/logadapter/local.go | 19 ++++++++++---- action/log/logadapter/loki.go | 44 +++++++++++++++++--------------- action/prometheus/metrics.go | 46 +++++++++++++++++++++------------- cmd/root.go | 3 +++ config.yml | 4 +-- 13 files changed, 139 insertions(+), 132 deletions(-) diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index b5ff21d..ba235cb 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -23,7 +24,7 @@ var DeployCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := deploy() if err != nil { - fmt.Println(err) + tool.Logger.Errorf("deploy err:%v", err) } }, } @@ -57,8 +58,7 @@ func deploy() error { var seataServer *unstructured.Unstructured seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) if seataServer != nil { - fmt.Println("This seata server already exits!") - return nil + return fmt.Errorf("seata server already exist! name:" + Name) } seataServer = &unstructured.Unstructured{ Object: map[string]interface{}{ @@ -89,6 +89,6 @@ func deploy() error { if err != nil { return err } - fmt.Printf("CR install success,name: %s\n", Name) + tool.Logger.Infof("CR install success,name: %s\n", Name) return nil } diff --git a/action/k8s/install.go b/action/k8s/install.go index 73d09af..c8357db 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" _ "gopkg.in/yaml.v3" _ "io/ioutil" @@ -16,7 +17,6 @@ import ( _ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" _ "k8s.io/apimachinery/pkg/runtime/schema" _ "k8s.io/client-go/applyconfigurations/meta/v1" - "log" ) const ( @@ -35,11 +35,11 @@ var InstallCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := DeployCRD() if err != nil { - log.Fatal(err) + tool.Logger.Errorf("install CRD err: %v", err) } err = DeployController() if err != nil { - log.Fatal(err) + tool.Logger.Errorf("install Controller err: %v", err) } }, } @@ -64,9 +64,9 @@ func DeployCRD() error { // DeployController deploys the controller for the custom resource. func DeployController() error { // Get Kubernetes client - clientset, err := utils.GetClient() + client, err := utils.GetClient() if err != nil { - return fmt.Errorf("error getting clientset: %v", err) + return fmt.Errorf("get client err: %v", err) } // Define the Deployment name and namespace @@ -74,11 +74,10 @@ func DeployController() error { namespace := Namespace // Check if the Deployment already exists - _, err = clientset.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, metav1.GetOptions{}) + _, err = client.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, metav1.GetOptions{}) if err == nil { // If the Deployment exists, output a message and return - fmt.Printf("Deployment '%s' already exists in the '%s' namespace\n", deploymentName, Namespace) - return nil + return fmt.Errorf("Deployment '%s' already exists in the '%s' namespace\n", deploymentName, Namespace) } else if !errors.IsNotFound(err) { // If there is an error other than "not found", return it return fmt.Errorf("error checking for existing deployment: %v", err) @@ -124,10 +123,10 @@ func DeployController() error { } // Create the Deployment - _, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{}) + _, err = client.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { return fmt.Errorf("error creating deployment: %v", err) } - fmt.Println("Deployment created successfully") + tool.Logger.Infof("Deployment created successfully") return nil } diff --git a/action/k8s/scale.go b/action/k8s/scale.go index e9eef42..8f463f4 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -20,7 +21,7 @@ var ScaleCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := scale() if err != nil { - fmt.Println(err) + tool.Logger.Errorf("scale err:%v", err) } }, } @@ -47,8 +48,7 @@ func scale() error { var seataServer *unstructured.Unstructured seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{}) if seataServer == nil { - fmt.Println("This seata server does not exits!") - return nil + return fmt.Errorf("This seata server does not exits!" + Name) } seataServer.Object["spec"].(map[string]interface{})["replicas"] = Replicas @@ -57,6 +57,6 @@ func scale() error { if err != nil { return err } - fmt.Printf("CR scale success,name: %s\n", Name) + tool.Logger.Infof("CR scale success,name: %s\n", Name) return nil } diff --git a/action/k8s/status.go b/action/k8s/status.go index 5668ccb..16bd08a 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -4,23 +4,24 @@ import ( "context" "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const Label = "cr_name" + var StatusCmd = &cobra.Command{ Use: "status", Short: "show seata status in k8s", Run: func(cmd *cobra.Command, args []string) { err := status() if err != nil { - fmt.Println(err) + tool.Logger.Errorf("get k8s status error: %v", err) } }, } -const Label = "cr_name" - func init() { StatusCmd.PersistentFlags().StringVar(&Name, "name", "list", "Seataserver name") StatusCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") @@ -33,7 +34,7 @@ func status() error { } // Print formatted Pod status information for _, status := range statuses { - fmt.Println(status) + tool.Logger.Infof("status: %s", status) } return nil } @@ -56,9 +57,6 @@ func getPodsStatusByLabel(namespace, labelSelector string) ([]string, error) { // Iterate over all Pods and get their status var statuses []string - //for _, pod := range pods.Items { - // statuses = append(statuses, fmt.Sprintf("Pod %s is in %s phase", pod.Name, pod.Status.Phase)) - //} // Build formatted status string for output statuses = append(statuses, fmt.Sprintf("%-25s %-10s", "POD NAME", "STATUS")) // Header diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go index 5b7e6a4..a552d95 100644 --- a/action/k8s/undeploy.go +++ b/action/k8s/undeploy.go @@ -2,8 +2,8 @@ package k8s import ( "context" - "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -15,7 +15,7 @@ var UnDeployCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := undeploy() if err != nil { - fmt.Println(err) + tool.Logger.Errorf("undeploy error: %v", err) } }, } @@ -42,6 +42,8 @@ func undeploy() error { if err != nil { return err } - fmt.Printf("CR delete success,name: %s\n", Name) + + tool.Logger.Infof("CR delete success,name: %s\n", Name) + return nil } diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index de99fb3..5899aca 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -2,13 +2,12 @@ package k8s import ( "context" - "fmt" "github.com/seata/seata-ctl/action/k8s/utils" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "log" ) var UnInstallCmd = &cobra.Command{ @@ -17,11 +16,11 @@ var UnInstallCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := UninstallCRD() if err != nil { - log.Fatal(err) + tool.Logger.Errorf("uninstall CRD err:%v", err) } err = UnDeploymentController() if err != nil { - log.Fatal(err) + tool.Logger.Errorf("uninstall Deployment err:%v", err) } }, } @@ -48,38 +47,39 @@ func UninstallCRD() error { // Check if the error is a "not found" error if errors.IsNotFound(err) { // The resource does not exist, output a message instead of returning an error - fmt.Printf("CRD %s does not exist, no action taken.\n", CRDname) + tool.Logger.Infof("CRD %s does not exist, no action taken.\n", CRDname) } else { // For other errors, log the error and exit the program - log.Fatalf("delete CRD failed: %v", err) + tool.Logger.Errorf("delete CRD failed: %v", err) } } else { // Successfully deleted the resource - fmt.Printf("CRD %s deleted successfully.\n", CRDname) + tool.Logger.Infof("delete CRD %s successfully.\n", CRDname) } return nil } func UnDeploymentController() error { - clientset, err := utils.GetClient() + client, err := utils.GetClient() if err != nil { return err } - // Assume clientset has already been defined - err = clientset.AppsV1().Deployments(Namespace).Delete(context.TODO(), Deployname, metav1.DeleteOptions{}) + + // Assume client has already been defined + err = client.AppsV1().Deployments(Namespace).Delete(context.TODO(), Deployname, metav1.DeleteOptions{}) if err != nil { // Check if the error is a "not found" error if errors.IsNotFound(err) { // The deployment does not exist, output a message instead of returning an error - fmt.Printf("Deployment 'seata-k8s-controller-manager' does not exist in namespace '%s', no action taken.\n", Namespace) + tool.Logger.Infof("Deployment 'seata-k8s-controller-manager' does not exist in namespace '%s', no action taken.\n", Namespace) } else { // For other errors, log the error and exit the program - log.Fatalf("Error deleting deployment: %s", err.Error()) + tool.Logger.Errorf("Error deleting deployment: %s", err.Error()) } } else { // Successfully deleted the deployment - fmt.Printf("Deployment 'seata-k8s-controller-manager' deleted successfully from namespace '%s'.\n", Namespace) + tool.Logger.Infof("deleted Controller %s successfully ", Deployname) } return nil } diff --git a/action/k8s/utils/file.go b/action/k8s/utils/file.go index c03ed6f..e4968b1 100644 --- a/action/k8s/utils/file.go +++ b/action/k8s/utils/file.go @@ -1,31 +1,33 @@ package utils import ( + "fmt" "github.com/seata/seata-ctl/model" "gopkg.in/yaml.v3" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "log" "os" ) +const ConfigFileName = "config.yml" + // GetKubeConfigPath retrieves the kubeConfigPath based on the contents of the config file. func GetKubeConfigPath() (string, error) { // Read the configuration file - file, err := os.ReadFile("config.yml") + file, err := os.ReadFile(ConfigFileName) if err != nil { - log.Fatalf("Failed to read config.yml: %v", err) + return "", fmt.Errorf("failed to read config.yml:" + err.Error()) } var config model.Config err = yaml.Unmarshal(file, &config) if err != nil { - log.Fatalf("Unmarshal: %v", err) + return "", fmt.Errorf("unmarshal failed" + err.Error()) } // Retrieve the context name contextName := config.Context.Kubernetes var contextPath string - // Find the matching kubeconfig path based on the context + // Find the matching KubeConfig path based on the context for _, cluster := range config.Kubernetes.Cluster { if cluster.Name == contextName { contextPath = cluster.KubeConfigPath @@ -33,19 +35,19 @@ func GetKubeConfigPath() (string, error) { } // If no matching context is found, return an error if contextPath == "" { - log.Fatalf("Failed to find context in config.yml") + return "", fmt.Errorf("failed to find context in config.yml") } return contextPath, err } -// GetClient creates and returns a Kubernetes client based on the specified kubeconfig file path. +// GetClient creates and returns a Kubernetes client based on the specified KubeConfigPath file path. func GetClient() (*kubernetes.Clientset, error) { - // Load the kubeconfig file using the client - kubeconfigPath, err := GetKubeConfigPath() + // Load the KubeConfig file using the client + KubeConfigPath, err := GetKubeConfigPath() if err != nil { return nil, err } - config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + config, err := clientcmd.BuildConfigFromFlags("", KubeConfigPath) if err != nil { return nil, err } @@ -59,14 +61,14 @@ func GetClient() (*kubernetes.Clientset, error) { return client, nil } -// GetDynamicClient creates and returns a Kubernetes dynamic client based on the specified kubeconfig file path. +// GetDynamicClient creates and returns a Kubernetes dynamic client based on the specified KubeConfigPath file path. func GetDynamicClient() (*dynamic.DynamicClient, error) { - // Load the kubeconfig file using the client - kubeconfigPath, err := GetKubeConfigPath() + // Load the KubeConfigPath file using the client + KubeConfigPath, err := GetKubeConfigPath() if err != nil { return nil, err } - config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + config, err := clientcmd.BuildConfigFromFlags("", KubeConfigPath) if err != nil { return nil, err } @@ -74,7 +76,7 @@ func GetDynamicClient() (*dynamic.DynamicClient, error) { // Create a dynamic client dynamicClient, err := dynamic.NewForConfig(config) if err != nil { - log.Fatalf("Failed to create dynamic client: %v", err) + return nil, fmt.Errorf("failed to create dynamic client" + err.Error()) } return dynamicClient, nil } diff --git a/action/log/log.go b/action/log/log.go index f868637..9a5575e 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -4,16 +4,16 @@ import ( "fmt" "github.com/seata/seata-ctl/action/log/logadapter" "github.com/seata/seata-ctl/model" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" "gopkg.in/yaml.v3" - "log" "os" ) const ( ElasticSearchType = "ElasticSearch" DefaultNumber = 10 - DefaultLogLevel = "" + DefaultLogLevel = "-" ) const ( @@ -30,14 +30,14 @@ var LogCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := getLog() if err != nil { - fmt.Println(err) + tool.Logger.Errorf("get log error: %s", err) } }, } // ElasticSearch var ( - LogLevel string + Level string Module string XID string BranchID string @@ -54,7 +54,7 @@ var ( ) func init() { - LogCmd.PersistentFlags().StringVar(&LogLevel, "level", DefaultLogLevel, "seata log level") + LogCmd.PersistentFlags().StringVar(&Level, "level", DefaultLogLevel, "seata log level") LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") LogCmd.PersistentFlags().StringVar(&XID, "xid", "", "seata expression") LogCmd.PersistentFlags().StringVar(&BranchID, "banchID", "", "seata branchId") @@ -103,21 +103,18 @@ func getLog() error { return err } - //reset var - //ResetAllVariables() - return nil } func getContext() (*model.Cluster, *logadapter.Currency, error) { file, err := os.ReadFile("config.yml") if err != nil { - log.Fatalf("Failed to read config.yml: %v", err) + return nil, nil, fmt.Errorf("read config.yml error: %s", err) } var config model.Config err = yaml.Unmarshal(file, &config) if err != nil { - log.Fatalf("Unmarshal: %v", err) + return nil, nil, fmt.Errorf("unmarshal config.yml error: %s", err) } contextName := config.Context.Log for _, cluster := range config.Log.Clusters { @@ -135,8 +132,8 @@ func getContext() (*model.Cluster, *logadapter.Currency, error) { func buildElasticSearchFilter() map[string]interface{} { filter := make(map[string]interface{}) - if LogLevel != "" { - filter["logLevel"] = LogLevel + if Level != "" { + filter["logLevel"] = Level } if Module != "" { filter["module"] = Module @@ -170,25 +167,8 @@ func buildLokiFilter() map[string]interface{} { func buildLocalFilter() map[string]interface{} { filter := make(map[string]interface{}) - if LogLevel != "" { - filter["logLevel"] = LogLevel + if Level != "" { + filter["logLevel"] = Level } return filter } - -// ResetAllVariables resets all global variables to their zero values -func ResetAllVariables() { - // Reset ElasticSearch-related variables - LogLevel = "" - Module = "" - XID = "" - BranchID = "" - ResourceID = "" - Message = "" - Number = 0 - - // Reset Loki-related variables - Label = "" - Start = "" - End = "" -} diff --git a/action/log/logadapter/local.go b/action/log/logadapter/local.go index 960c10a..f1384c1 100644 --- a/action/log/logadapter/local.go +++ b/action/log/logadapter/local.go @@ -3,8 +3,10 @@ package logadapter import ( "encoding/json" "fmt" + "github.com/seata/seata-ctl/tool" "io/ioutil" "net/http" + "strings" ) const ( @@ -67,11 +69,18 @@ func (l *Local) QueryLogs(filter map[string]interface{}, currency *Currency, num } // Print the logs in a structured format - fmt.Printf("Application ID: %s\n", queryResponse.ApplicationID) - fmt.Printf("Log Level: %s\n", queryResponse.LogLevel) - fmt.Println("Logs:") - for _, logData := range queryResponse.Logs { - fmt.Printf("[%s] [%s]: %s\n", logData.Timestamp, logData.LogLevel, logData.LogMessage) + for _, value := range queryResponse.Logs { + res := fmt.Sprintf("[%s]: %s\n", value.Timestamp, value.LogMessage) + fmt.Println(value.LogMessage) + if strings.Contains(value.LogMessage, "INFO") { + tool.Logger.Info(fmt.Sprintf("%v", res)) + } + if strings.Contains(value.LogMessage, "ERROR") { + tool.Logger.Error(fmt.Sprintf("%v", res)) + } + if strings.Contains(value.LogMessage, "WARN") { + tool.Logger.Warn(fmt.Sprintf("%v", res)) + } } return nil } diff --git a/action/log/logadapter/loki.go b/action/log/logadapter/loki.go index 337d511..057be9f 100644 --- a/action/log/logadapter/loki.go +++ b/action/log/logadapter/loki.go @@ -3,11 +3,13 @@ package logadapter import ( "encoding/json" "fmt" + "github.com/seata/seata-ctl/tool" + "io" "io/ioutil" - "log" "net/http" "net/url" "strconv" + "strings" "time" ) @@ -36,7 +38,7 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb // Prepare the query URL with time range params := url.Values{} params.Set("query", filter["query"].(string)) - params.Set("limit", strconv.Itoa(filter["number"].(int))) + params.Set("limit", strconv.Itoa(number)) // Set start time if provided if value, ok := filter["start"]; ok { @@ -59,21 +61,26 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb // Send GET request to Loki resp, err := http.Get(queryURL) if err != nil { - log.Fatalf("Error sending request to Loki: %v", err) + return fmt.Errorf("error sending request to Loki: %v", err) } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + tool.Logger.Errorf("Failed to close response body: %v", err) + } + }(resp.Body) // Read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { - log.Fatalf("Error reading response from Loki: %v", err) + return fmt.Errorf("error reading response from Loki: %v", err) } // Parse the JSON response var result LokiQueryResult err = json.Unmarshal(body, &result) if err != nil { - log.Fatalf("Error parsing Loki response: %v", err) + return fmt.Errorf("error parsing Loki response: %v", err) } // Process and print logs @@ -81,21 +88,19 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb for _, stream := range result.Data.Result { for _, entry := range stream.Values { // Extract timestamp and log message - timestampStr := entry[0] - logLine := entry[1] - - // Convert nanosecond timestamp to int64 - timestampInt, err := strconv.ParseInt(timestampStr, 10, 64) - if err != nil { - fmt.Printf("Failed to convert timestamp: %v\n", err) - continue - } - - // Convert Unix nanosecond timestamp to readable format - readableTime := time.Unix(0, timestampInt).Format("2006-01-02 15:04:05") + value := entry[1] // Print the readable timestamp and log message - fmt.Printf("Timestamp: %s, Log: %s\n", readableTime, logLine) + fmt.Printf("%s\n", value) + if strings.Contains(value, "INFO") { + tool.Logger.Info(fmt.Sprintf("%v", value)) + } + if strings.Contains(value, "ERROR") { + tool.Logger.Error(fmt.Sprintf("%v", value)) + } + if strings.Contains(value, "WARN") { + tool.Logger.Warn(fmt.Sprintf("%v", value)) + } } } } else { @@ -120,6 +125,5 @@ func parseToTimestamp(timeStr string) (int64, error) { // Convert to Unix nanosecond timestamp timestamp := t.UnixNano() - return timestamp, nil } diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 87c2640..6bf2e58 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -4,11 +4,13 @@ import ( "encoding/json" "fmt" "github.com/guptarohit/asciigraph" + "github.com/seata/seata-ctl/action/k8s/utils" "github.com/seata/seata-ctl/model" + "github.com/seata/seata-ctl/tool" "github.com/spf13/cobra" "gopkg.in/yaml.v3" + "io" "io/ioutil" - "log" "net/http" "net/url" "os" @@ -20,12 +22,14 @@ var MetricsCmd = &cobra.Command{ Short: "Show Prometheus metrics", Run: func(cmd *cobra.Command, args []string) { if err := showMetrics(); err != nil { - fmt.Println(err) + tool.Logger.Errorf("Failed to show metrics: %v", err) } }, } -var Target string +var ( + Target string +) func init() { MetricsCmd.PersistentFlags().StringVar(&Target, "target", "seata_transaction_summary", "Namespace name") @@ -39,9 +43,9 @@ func showMetrics() error { } // Query Prometheus for metrics - result, err := queryPrometheusMetric(prometheusURL, Target) + result, err := queryPromMetric(prometheusURL, Target) if err != nil { - log.Fatalf("Error querying Prometheus: %v", err) + return fmt.Errorf("query prometheus metrics: %v", err) } // Generate terminal chart from the queried results @@ -53,15 +57,15 @@ func showMetrics() error { // getPrometheusAddress fetches Prometheus server address from configuration func getPrometheusAddress() (string, error) { - file, err := os.ReadFile("config.yml") + file, err := os.ReadFile(utils.ConfigFileName) if err != nil { - log.Fatalf("Failed to read config.yml: %v", err) + return "", fmt.Errorf("failed to read config.yml: %v", err) } // Parse the configuration var config model.Config if err = yaml.Unmarshal(file, &config); err != nil { - log.Fatalf("Failed to unmarshal YAML: %v", err) + return "", fmt.Errorf("failed to unmarshal YAML: %v", err) } // Extract Prometheus address based on context @@ -73,14 +77,13 @@ func getPrometheusAddress() (string, error) { } } if contextPath == "" { - log.Fatalf("Failed to find Prometheus context in config.yml") - return "", err + return "", fmt.Errorf("failed to find Prometheus context in config.yml") } return contextPath, nil } -// PrometheusResponse defines the structure of a Prometheus query response -type PrometheusResponse struct { +// PromResponse defines the structure of a Prometheus query response +type PromResponse struct { Status string `json:"status"` Data struct { ResultType string `json:"resultType"` @@ -91,14 +94,20 @@ type PrometheusResponse struct { } `json:"data"` } -// queryPrometheusMetric sends a query to the Prometheus API and returns the response -func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, error) { +// queryPromsMetric sends a query to the Prometheus API and returns the response +func queryPromMetric(prometheusURL, query string) (*PromResponse, error) { queryURL := fmt.Sprintf("%s/api/v1/query?query=%s", prometheusURL, url.QueryEscape(query)) resp, err := http.Get(queryURL) if err != nil { return nil, fmt.Errorf("error querying Prometheus: %w", err) } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + tool.Logger.Errorf("failed to close response body: %v", err) + return + } + }(resp.Body) // Read the response body body, err := ioutil.ReadAll(resp.Body) @@ -107,7 +116,7 @@ func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, er } // Parse JSON response into the PrometheusResponse structure - var result PrometheusResponse + var result PromResponse if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("error unmarshalling JSON: %w", err) } @@ -115,7 +124,7 @@ func queryPrometheusMetric(prometheusURL, query string) (*PrometheusResponse, er } // generateTerminalLineChart generates and prints an ASCII line chart based on the Prometheus response -func generateTerminalLineChart(response *PrometheusResponse, metricName string) error { +func generateTerminalLineChart(response *PromResponse, metricName string) error { var yValues []float64 // Iterate over the results and extract the values for the specified metric @@ -142,6 +151,7 @@ func generateTerminalLineChart(response *PrometheusResponse, metricName string) // Generate and display the ASCII line chart graph := asciigraph.Plot(yValues, asciigraph.Width(50), asciigraph.Height(10), asciigraph.Caption(metricName)) - fmt.Println(graph) + + tool.Logger.Infof(graph) return nil } diff --git a/cmd/root.go b/cmd/root.go index 47b2ebe..a59b770 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" + "github.com/seata/seata-ctl/tool" "os" "github.com/seata/seata-ctl/action" @@ -69,6 +70,8 @@ func Execute() { os.Exit(1) } + tool.InitLogger() + var address = "" for _, arg := range os.Args { diff --git a/config.yml b/config.yml index b8b1775..d998f26 100644 --- a/config.yml +++ b/config.yml @@ -16,7 +16,7 @@ log: - name: "es" types: "ElasticSearch" address: "https://localhost:9200" - source: "logstash-2024.10.24" + source: "seata_logs" auth: "bu4AC50REtt_7rUqddMe" collection: enable: true @@ -61,4 +61,4 @@ log: context: kubernetes: "cluster1" prometheus: "prometheus" - log: "local" + log: "es" From 4c5e8b0d5563bb306d4766ceb83c47517bd34b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sat, 26 Oct 2024 18:51:45 +0800 Subject: [PATCH 17/30] fix bug. --- action/log/log.go | 10 +++-- action/log/logadapter/elasticsearch.go | 52 +++++++++++++++----------- config.yml | 2 +- tool/log.go | 20 ++++++++++ 4 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 tool/log.go diff --git a/action/log/log.go b/action/log/log.go index 9a5575e..881685e 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -11,9 +11,10 @@ import ( ) const ( - ElasticSearchType = "ElasticSearch" - DefaultNumber = 10 - DefaultLogLevel = "-" + ElasticSearchType = "ElasticSearch" + DefaultNumber = 10 + DefaultLogLevel = "" + DefaultLocalLogLevel = "-" ) const ( @@ -169,6 +170,9 @@ func buildLocalFilter() map[string]interface{} { filter := make(map[string]interface{}) if Level != "" { filter["logLevel"] = Level + } else { + //reset the default value + filter["logLevel"] = DefaultLocalLogLevel } return filter } diff --git a/action/log/logadapter/elasticsearch.go b/action/log/logadapter/elasticsearch.go index d759727..f504567 100644 --- a/action/log/logadapter/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -4,11 +4,11 @@ import ( "context" "crypto/tls" "encoding/json" - "errors" "fmt" "github.com/olivere/elastic/v7" - "log" + "github.com/seata/seata-ctl/tool" "net/http" + "strings" ) const ( @@ -42,8 +42,10 @@ func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *Curre return fmt.Errorf("error fetching documents: %w", err) } - fmt.Printf("Found %d hits.\n", searchResult.TotalHits()) - processSearchHits(searchResult) + err = processSearchHits(searchResult) + if err != nil { + return err + } return nil } @@ -70,26 +72,34 @@ func createElasticClient(currency *Currency) (*elastic.Client, error) { } // processSearchHits handles and formats the search results -func processSearchHits(searchResult *elastic.SearchResult) []string { - var result []string +func processSearchHits(searchResult *elastic.SearchResult) error { + + if len(searchResult.Hits.Hits) == 0 { + return fmt.Errorf("no documents found") + } for _, hit := range searchResult.Hits.Hits { var doc map[string]interface{} if err := json.Unmarshal(hit.Source, &doc); err != nil { - log.Printf("Error parsing document: %s", err) - continue + return fmt.Errorf("failed to unmarshal document: %w", err) } // Pretty print the document content - fmt.Println("Document Source:") for key, value := range doc { - log.Printf(" %s: %v", key, value) + if key == "log" { + if strings.Contains(value.(string), "INFO") { + tool.Logger.Info(fmt.Sprintf("%v", value)) + } + if strings.Contains(value.(string), "ERROR") { + tool.Logger.Error(fmt.Sprintf("%v", value)) + } + if strings.Contains(value.(string), "WARN") { + tool.Logger.Warn(fmt.Sprintf("%v", value)) + } + } } - log.Println("----------------------------") - - result = append(result, hit.Id) // Store document IDs or other relevant data } - return result + return nil } // BuildQueryFromFilter constructs a BoolQuery from the filter parameters @@ -102,40 +112,40 @@ func BuildQueryFromFilter(filter map[string]interface{}) (*elastic.BoolQuery, er if v, ok := value.(string); ok { query.Should(elastic.NewTermQuery("logLevel", v)) } else { - return nil, errors.New("invalid type for logLevel, expected string") + return nil, fmt.Errorf("invalid type for logLevel, expected string") } case "module": if v, ok := value.(string); ok { query.Should(elastic.NewTermQuery("module", v)) } else { - return nil, errors.New("invalid type for module, expected string") + return nil, fmt.Errorf("invalid type for module, expected string") } case "xid": if v, ok := value.(string); ok { query.Should(elastic.NewTermQuery("xid", v)) } else { - return nil, errors.New("invalid type for xid, expected string") + return nil, fmt.Errorf("invalid type for xid, expected string") } case "branchId": if v, ok := value.(string); ok { query.Should(elastic.NewTermQuery("branchId", v)) } else { - return nil, errors.New("invalid type for branchId, expected string") + return nil, fmt.Errorf("invalid type for branchId, expected string") } case "resourceId": if v, ok := value.(string); ok { query.Should(elastic.NewTermQuery("resourceId", v)) } else { - return nil, errors.New("invalid type for resourceId, expected string") + return nil, fmt.Errorf("invalid type for resourceId, expected string") } case "message": if v, ok := value.(string); ok { query.Should(elastic.NewMatchQuery("message", v)) } else { - return nil, errors.New("invalid type for message, expected string") + return nil, fmt.Errorf("invalid type for message, expected string") } default: - log.Printf("Unknown field: %s\n", key) + return nil, fmt.Errorf("unknown field: %s", key) } } return query, nil diff --git a/config.yml b/config.yml index d998f26..a732b3e 100644 --- a/config.yml +++ b/config.yml @@ -16,7 +16,7 @@ log: - name: "es" types: "ElasticSearch" address: "https://localhost:9200" - source: "seata_logs" + source: "test" auth: "bu4AC50REtt_7rUqddMe" collection: enable: true diff --git a/tool/log.go b/tool/log.go new file mode 100644 index 0000000..d194d65 --- /dev/null +++ b/tool/log.go @@ -0,0 +1,20 @@ +package tool + +import ( + "github.com/sirupsen/logrus" + "sync" +) + +// Logger Global logger instance +var Logger *logrus.Logger +var once sync.Once + +// InitLogger initializes the global logger instance +func InitLogger() *logrus.Logger { + once.Do(func() { // Ensures initialization is only done once + Logger = logrus.New() + Logger.SetFormatter(&logrus.TextFormatter{ForceColors: true}) + Logger.SetLevel(logrus.InfoLevel) + }) + return Logger +} From cb6b1c6d9fc8fd0beff62ccb0a58fc768e3529f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sat, 26 Oct 2024 19:00:13 +0800 Subject: [PATCH 18/30] fix bug. --- config.yml | 2 +- go.mod | 38 +++++------ go.sum | 195 ----------------------------------------------------- 3 files changed, 19 insertions(+), 216 deletions(-) delete mode 100644 go.sum diff --git a/config.yml b/config.yml index a732b3e..653a6a4 100644 --- a/config.yml +++ b/config.yml @@ -61,4 +61,4 @@ log: context: kubernetes: "cluster1" prometheus: "prometheus" - log: "es" + log: "loki" diff --git a/go.mod b/go.mod index 68ba0cd..75bd62f 100644 --- a/go.mod +++ b/go.mod @@ -2,30 +2,30 @@ module github.com/seata/seata-ctl go 1.22.0 -toolchain go1.22.6 +toolchain go1.23.1 require ( - github.com/elastic/go-elasticsearch/v8 v8.15.0 - github.com/guptarohit/asciigraph v0.7.2 + github.com/guptarohit/asciigraph v0.7.3 github.com/jedib0t/go-pretty/v6 v6.4.7 github.com/olivere/elastic/v7 v7.0.32 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 + github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.31.0 - k8s.io/apiextensions-apiserver v0.31.0 - k8s.io/apimachinery v0.31.0 - k8s.io/client-go v0.31.0 + k8s.io/api v0.31.2 + k8s.io/apiextensions-apiserver v0.31.2 + k8s.io/apimachinery v0.31.2 + k8s.io/client-go v0.31.2 sigs.k8s.io/yaml v1.4.0 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect @@ -35,23 +35,28 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.21.0 // indirect @@ -60,6 +65,7 @@ require ( golang.org/x/time v0.3.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect @@ -67,11 +73,3 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) - -replace github.com/imdario/mergo => github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40 - -replace github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.6 - -replace github.com/json-iterator/go => github.com/json-iterator/go v1.1.10 - -replace github.com/magiconair/properties => github.com/magiconair/properties v1.8.6 diff --git a/go.sum b/go.sum deleted file mode 100644 index da50b4b..0000000 --- a/go.sum +++ /dev/null @@ -1,195 +0,0 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= -github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= -github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.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/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/guptarohit/asciigraph v0.7.2 h1:pBBJYbMl4j7zS4AwmrfAs6tA0VQOEQC933aG72dlrFA= -github.com/guptarohit/asciigraph v0.7.2/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= -github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40 h1:jNLMZ3OPDHinDH9n3OJ8qjrwxcZfVy+yy47YOyrbD74= -github.com/imdario/mergo v0.0.0-20180119075120-dc972c8e7a40/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= -github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -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/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -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/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -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.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -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/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= -github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -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= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From eb1051e770e7084758c5bf8c3bdcbfa27065a925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Sun, 27 Oct 2024 17:49:35 +0800 Subject: [PATCH 19/30] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E6=95=B4=E7=90=86=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E4=B8=8E=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F=E5=AD=98=E6=94=BE?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +- action/k8s/common.go | 27 ++ action/k8s/deploy.go | 18 +- action/k8s/install.go | 19 +- action/k8s/scale.go | 8 +- action/k8s/status.go | 4 +- action/k8s/undeploy.go | 4 +- action/k8s/uninstall.go | 8 +- action/k8s/utils/http.go | 9 +- action/k8s/utils/request.go | 10 +- action/log/common.go | 36 ++ action/log/log.go | 35 +- action/log/logadapter/elasticsearch.go | 7 +- action/log/logadapter/interface.go | 18 - action/log/logadapter/local.go | 29 +- action/log/logadapter/loki.go | 23 +- action/log/logadapter/types.go | 45 ++ action/prometheus/common.go | 9 + action/prometheus/metrics.go | 8 +- go.sum | 608 +++++++++++++++++++++++++ 20 files changed, 777 insertions(+), 158 deletions(-) create mode 100644 action/k8s/common.go create mode 100644 action/log/common.go create mode 100644 action/log/logadapter/types.go create mode 100644 action/prometheus/common.go create mode 100644 go.sum diff --git a/README.md b/README.md index 6356e02..ad16ae8 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ Available Commands: Flags: -h, --help help for seata-ctl - --ip string Seata Server IP (default "127.0.0.1") - --password string Password (default "seata") - --port int Seata Server Admin Port (default 7091) - --username string Username (default "seata") + --ip string Seata Server IP (constants "127.0.0.1") + --password string Password (constants "seata") + --port int Seata Server Admin Port (constants 7091) + --username string Username (constants "seata") Use "seata-ctl [command] --help" for more information about a command. ``` @@ -161,7 +161,7 @@ Usage: Flags: --config-center If set configuration center conf - --data string Configuration map (default "{}") + --data string Configuration map (constants "{}") -h, --help help for config --registry If set registry conf ``` diff --git a/action/k8s/common.go b/action/k8s/common.go new file mode 100644 index 0000000..a93e2f2 --- /dev/null +++ b/action/k8s/common.go @@ -0,0 +1,27 @@ +package k8s + +const ( + DefaultCRName = "example-seataserver" + DefaultServerImage = "apache/seata-server:latest" + DefaultNamespace = "constants" + DefaultDeployName = "seata-k8s-controller-manager" + DefaultControllerImage = "apache/seata-controller:latest" + DefaultReplicas = 1 + + Label = "cr_name" + CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" + FilePath = "seata.yaml" + CRDname = "seataservers.operator.seata.apache.org" + ServiceName = "seata-server-cluster" + RequestStorage = "1Gi" + LimitStorage = "1Gi" +) + +var ( + Name string + Replicas int32 + Namespace string + Image string + ControllerImage string + DeployName string +) diff --git a/action/k8s/deploy.go b/action/k8s/deploy.go index ba235cb..3499a32 100644 --- a/action/k8s/deploy.go +++ b/action/k8s/deploy.go @@ -11,13 +11,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -const ( - DefaultServerImage = "apache/seata-server:latest" - ServiceName = "seata-server-cluster" - RequestStorage = "1Gi" - LimitStorage = "1Gi" -) - var DeployCmd = &cobra.Command{ Use: "deploy", Short: "deploy seata in k8s", @@ -29,17 +22,10 @@ var DeployCmd = &cobra.Command{ }, } -var ( - Name string - Replicas int32 - Namespace string - Image string -) - func init() { - DeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") + DeployCmd.PersistentFlags().StringVar(&Name, "name", DefaultCRName, "Seataserver name") DeployCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number") - DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") DeployCmd.PersistentFlags().StringVar(&Image, "image", DefaultServerImage, "Seata server image") } diff --git a/action/k8s/install.go b/action/k8s/install.go index c8357db..fdcd70d 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -19,16 +19,6 @@ import ( _ "k8s.io/client-go/applyconfigurations/meta/v1" ) -const ( - CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions" - FilePath = "seata.yaml" - - CRDname = "seataservers.operator.seata.apache.org" - Deployname = "seata-k8s-controller-manager" - - DefaultControllerImage = "apache/seata-controller:latest" -) - var InstallCmd = &cobra.Command{ Use: "install", Short: "Install Kubernetes CRD controller", @@ -44,20 +34,19 @@ var InstallCmd = &cobra.Command{ }, } -var ControllerImage string - func init() { - InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") InstallCmd.PersistentFlags().StringVar(&ControllerImage, "image", DefaultControllerImage, "Namespace name") + InstallCmd.PersistentFlags().StringVar(&DeployName, "name", DefaultDeployName, "Deployment name") } // DeployCRD deploys the custom resource definition. func DeployCRD() error { res, err := utils.CreateRequest(CreateCrdPath, FilePath) - fmt.Println(res) if err != nil { return err } + tool.Logger.Infof(res) return nil } @@ -70,7 +59,7 @@ func DeployController() error { } // Define the Deployment name and namespace - deploymentName := Deployname + deploymentName := DeployName namespace := Namespace // Check if the Deployment already exists diff --git a/action/k8s/scale.go b/action/k8s/scale.go index 8f463f4..1b091c3 100644 --- a/action/k8s/scale.go +++ b/action/k8s/scale.go @@ -11,10 +11,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -const ( - DefaultReplicas = 1 -) - var ScaleCmd = &cobra.Command{ Use: "scale", Short: "scale seata in k8s", @@ -27,9 +23,9 @@ var ScaleCmd = &cobra.Command{ } func init() { - ScaleCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") + ScaleCmd.PersistentFlags().StringVar(&Name, "name", DefaultCRName, "Seataserver name") ScaleCmd.PersistentFlags().Int32Var(&Replicas, "replicas", DefaultReplicas, "Replicas number") - ScaleCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + ScaleCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") } func scale() error { diff --git a/action/k8s/status.go b/action/k8s/status.go index 16bd08a..bda1a70 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -9,8 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const Label = "cr_name" - var StatusCmd = &cobra.Command{ Use: "status", Short: "show seata status in k8s", @@ -24,7 +22,7 @@ var StatusCmd = &cobra.Command{ func init() { StatusCmd.PersistentFlags().StringVar(&Name, "name", "list", "Seataserver name") - StatusCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + StatusCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") } func status() error { diff --git a/action/k8s/undeploy.go b/action/k8s/undeploy.go index a552d95..90bb84d 100644 --- a/action/k8s/undeploy.go +++ b/action/k8s/undeploy.go @@ -21,8 +21,8 @@ var UnDeployCmd = &cobra.Command{ } func init() { - UnDeployCmd.PersistentFlags().StringVar(&Name, "name", "example-seataserver", "Seataserver name") - UnDeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + UnDeployCmd.PersistentFlags().StringVar(&Name, "name", DefaultCRName, "Seataserver name") + UnDeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") } func undeploy() error { diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index 5899aca..9d1a842 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -26,7 +26,7 @@ var UnInstallCmd = &cobra.Command{ } func init() { - UnInstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", "default", "Namespace name") + UnInstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") } func UninstallCRD() error { @@ -67,19 +67,19 @@ func UnDeploymentController() error { } // Assume client has already been defined - err = client.AppsV1().Deployments(Namespace).Delete(context.TODO(), Deployname, metav1.DeleteOptions{}) + err = client.AppsV1().Deployments(Namespace).Delete(context.TODO(), DeployName, metav1.DeleteOptions{}) if err != nil { // Check if the error is a "not found" error if errors.IsNotFound(err) { // The deployment does not exist, output a message instead of returning an error - tool.Logger.Infof("Deployment 'seata-k8s-controller-manager' does not exist in namespace '%s', no action taken.\n", Namespace) + tool.Logger.Infof("Deployment '%s' does not exist in namespace '%s', no action taken.\n", DeployName, Namespace) } else { // For other errors, log the error and exit the program tool.Logger.Errorf("Error deleting deployment: %s", err.Error()) } } else { // Successfully deleted the deployment - tool.Logger.Infof("deleted Controller %s successfully ", Deployname) + tool.Logger.Infof("deleted Controller %s successfully ", DeployName) } return nil } diff --git a/action/k8s/utils/http.go b/action/k8s/utils/http.go index cb002a3..c3776fa 100644 --- a/action/k8s/utils/http.go +++ b/action/k8s/utils/http.go @@ -5,6 +5,8 @@ import ( "crypto/tls" "crypto/x509" "fmt" + "github.com/seata/seata-ctl/tool" + "io" "io/ioutil" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" @@ -150,7 +152,12 @@ func sendPostRequest(context *ContextInfo, createCrdPath string, filePath string if err != nil { return "", fmt.Errorf("failed to send request: %v", err) } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + tool.Logger.Error("failed to close response body: %v", err) + } + }(resp.Body) // Read response body body, err := ioutil.ReadAll(resp.Body) diff --git a/action/k8s/utils/request.go b/action/k8s/utils/request.go index 334bc52..6a21c61 100644 --- a/action/k8s/utils/request.go +++ b/action/k8s/utils/request.go @@ -6,26 +6,26 @@ func CreateRequest(createCrdPath string, filePath string) (string, error) { kubeConfigPath, err := GetKubeConfigPath() if err != nil { - return "", fmt.Errorf("Failed to get kubeconfig path: %v", err) + return "", fmt.Errorf("failed to get kubeconfig path: %v", err) } kubeConfig, err := LoadKubeConfig(kubeConfigPath) if err != nil { - return "", fmt.Errorf("Failed to load kubeconfig file: %v", err) + return "", fmt.Errorf("failed to load kubeconfig file: %v", err) } contextInfo, err := GetContextInfo(kubeConfig) if err != nil { - return "", fmt.Errorf("Failed to get context info: %v", err) + return "", fmt.Errorf("failed to get context info: %v", err) } filePath, err = ConvertAndSaveYamlToJSON(filePath) if err != nil { - return "", fmt.Errorf("Failed to save yaml: %v", err) + return "", fmt.Errorf("failed to save yaml: %v", err) } res, err := sendPostRequest(contextInfo, createCrdPath, filePath) if err != nil { - return res, fmt.Errorf("Failed to send post request: %v", err) + return res, fmt.Errorf("failed to send post request: %v", err) } return res, nil } diff --git a/action/log/common.go b/action/log/common.go new file mode 100644 index 0000000..8a473df --- /dev/null +++ b/action/log/common.go @@ -0,0 +1,36 @@ +package log + +const ( + ElasticSearchType = "ElasticSearch" + LokiType = "Loki" + LocalType = "Local" + + DefaultNumber = 10 + DefaultLogLevel = "" + DefaultLocalLogLevel = "-" + + LokiAddressPath = "/loki/api/v1/query_range?" + TimeLayout = "2006-01-02-15:04:05" + + LocalQueryPath = "/query" + + ElasticsearchAuth = "elastic" +) + +// ElasticSearch +var ( + Level string + Module string + XID string + BranchID string + ResourceID string + Message string + Number int +) + +// Loki +var ( + Label string + Start string + End string +) diff --git a/action/log/log.go b/action/log/log.go index 881685e..3ef4a10 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -10,21 +10,6 @@ import ( "os" ) -const ( - ElasticSearchType = "ElasticSearch" - DefaultNumber = 10 - DefaultLogLevel = "" - DefaultLocalLogLevel = "-" -) - -const ( - LokiType = "Loki" -) - -const ( - LocalType = "Local" -) - var LogCmd = &cobra.Command{ Use: "log", Short: "get seata log", @@ -36,24 +21,6 @@ var LogCmd = &cobra.Command{ }, } -// ElasticSearch -var ( - Level string - Module string - XID string - BranchID string - ResourceID string - Message string - Number int -) - -// Loki -var ( - Label string - Start string - End string -) - func init() { LogCmd.PersistentFlags().StringVar(&Level, "level", DefaultLogLevel, "seata log level") LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") @@ -171,7 +138,7 @@ func buildLocalFilter() map[string]interface{} { if Level != "" { filter["logLevel"] = Level } else { - //reset the default value + //reset the constants value filter["logLevel"] = DefaultLocalLogLevel } return filter diff --git a/action/log/logadapter/elasticsearch.go b/action/log/logadapter/elasticsearch.go index f504567..27701ba 100644 --- a/action/log/logadapter/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -6,15 +6,12 @@ import ( "encoding/json" "fmt" "github.com/olivere/elastic/v7" + "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" "net/http" "strings" ) -const ( - ElasticsearchAuth = "elastic" -) - type Elasticsearch struct{} // QueryLogs is a function that queries specific documents @@ -63,7 +60,7 @@ func createElasticClient(currency *Currency) (*elastic.Client, error) { elastic.SetURL(currency.Address), elastic.SetHttpClient(httpClient), elastic.SetSniff(false), - elastic.SetBasicAuth(ElasticsearchAuth, currency.Auth), + elastic.SetBasicAuth(log.ElasticsearchAuth, currency.Auth), ) if err != nil { return nil, err diff --git a/action/log/logadapter/interface.go b/action/log/logadapter/interface.go index b887934..a626b99 100644 --- a/action/log/logadapter/interface.go +++ b/action/log/logadapter/interface.go @@ -1,24 +1,6 @@ package logadapter -import "time" - type LogQuery interface { // QueryLogs retrieves logs based on the filter criteria QueryLogs(filter map[string]interface{}, currency *Currency, number int) error } - -type Currency struct { - Address string `json:"address"` - Source string `json:"source"` - Auth string `json:"auth"` -} - -type SeataLog struct { - Timestamp time.Time // Timestamp - LogLevel string // Log level, e.g., INFO, ERROR, etc. - Module string // Log module, e.g., RMHandler, UndoLogManager, etc. - XID string // Global transaction ID - BranchID string // Branch transaction ID - ResourceID string // Resource ID - Message string // Log content -} diff --git a/action/log/logadapter/local.go b/action/log/logadapter/local.go index f1384c1..a6e0277 100644 --- a/action/log/logadapter/local.go +++ b/action/log/logadapter/local.go @@ -3,30 +3,14 @@ package logadapter import ( "encoding/json" "fmt" + "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" + "io" "io/ioutil" "net/http" "strings" ) -const ( - QueryPath = "/query" -) - -// LogData represents a single log entry -type LogData struct { - Timestamp string `json:"timestamp"` - LogLevel string `json:"log_level"` - LogMessage string `json:"log_message"` -} - -// QueryResponse holds the response structure from the /query API -type QueryResponse struct { - ApplicationID string `json:"application_id"` - LogLevel string `json:"log_level"` - Logs []LogData `json:"logs"` -} - // Local is the struct implementing the logging logic type Local struct{} @@ -41,14 +25,19 @@ func (l *Local) QueryLogs(filter map[string]interface{}, currency *Currency, num } // Build the query URL using the filter and currency information - url := fmt.Sprintf("%s%s?application_id=%s&log_level=%s&limit=%d", currency.Address, QueryPath, currency.Source, logLevel, number) + url := fmt.Sprintf("%s%s?application_id=%s&log_level=%s&limit=%d", currency.Address, log.LocalQueryPath, currency.Source, logLevel, number) // Send a GET request to the /query endpoint resp, err := http.Get(url) if err != nil { return fmt.Errorf("failed to make request to %s: %v", url, err) } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + tool.Logger.Error("failed to close response body: %v", err) + } + }(resp.Body) // Read the response body body, err := ioutil.ReadAll(resp.Body) diff --git a/action/log/logadapter/loki.go b/action/log/logadapter/loki.go index 057be9f..e267675 100644 --- a/action/log/logadapter/loki.go +++ b/action/log/logadapter/loki.go @@ -3,6 +3,7 @@ package logadapter import ( "encoding/json" "fmt" + "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" "io" "io/ioutil" @@ -13,25 +14,8 @@ import ( "time" ) -const ( - LokiAddressPath = "/loki/api/v1/query_range?" - TimeLayout = "2006-01-02-15:04:05" -) - type Loki struct{} -// LokiQueryResult represents the structure of the response from Loki -type LokiQueryResult struct { - Status string `json:"status"` - Data struct { - ResultType string `json:"resultType"` - Result []struct { - Stream map[string]string `json:"stream"` - Values [][]string `json:"values"` - } `json:"result"` - } `json:"data"` -} - // QueryLogs queries logs from Loki based on the filter and settings provided func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { @@ -56,7 +40,7 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb } params.Set("end", fmt.Sprintf("%d", res)) } - queryURL := currency.Address + LokiAddressPath + params.Encode() + queryURL := currency.Address + log.LokiAddressPath + params.Encode() // Send GET request to Loki resp, err := http.Get(queryURL) @@ -91,7 +75,6 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb value := entry[1] // Print the readable timestamp and log message - fmt.Printf("%s\n", value) if strings.Contains(value, "INFO") { tool.Logger.Info(fmt.Sprintf("%v", value)) } @@ -118,7 +101,7 @@ func parseToTimestamp(timeStr string) (int64, error) { } // Parse the time string using the specified layout and timezone - t, err := time.ParseInLocation(TimeLayout, timeStr, loc) + t, err := time.ParseInLocation(log.TimeLayout, timeStr, loc) if err != nil { return 0, fmt.Errorf("failed to parse time: %v", err) } diff --git a/action/log/logadapter/types.go b/action/log/logadapter/types.go new file mode 100644 index 0000000..4717916 --- /dev/null +++ b/action/log/logadapter/types.go @@ -0,0 +1,45 @@ +package logadapter + +import "time" + +type Currency struct { + Address string `json:"address"` + Source string `json:"source"` + Auth string `json:"auth"` +} + +type SeataLog struct { + Timestamp time.Time // Timestamp + LogLevel string // Log level, e.g., INFO, ERROR, etc. + Module string // Log module, e.g., RMHandler, UndoLogManager, etc. + XID string // Global transaction ID + BranchID string // Branch transaction ID + ResourceID string // Resource ID + Message string // Log content +} + +// LokiQueryResult represents the structure of the response from Loki +type LokiQueryResult struct { + Status string `json:"status"` + Data struct { + ResultType string `json:"resultType"` + Result []struct { + Stream map[string]string `json:"stream"` + Values [][]string `json:"values"` + } `json:"result"` + } `json:"data"` +} + +// LogData represents a single log entry +type LogData struct { + Timestamp string `json:"timestamp"` + LogLevel string `json:"log_level"` + LogMessage string `json:"log_message"` +} + +// QueryResponse holds the response structure from the /query API +type QueryResponse struct { + ApplicationID string `json:"application_id"` + LogLevel string `json:"log_level"` + Logs []LogData `json:"logs"` +} diff --git a/action/prometheus/common.go b/action/prometheus/common.go new file mode 100644 index 0000000..10f60eb --- /dev/null +++ b/action/prometheus/common.go @@ -0,0 +1,9 @@ +package prometheus + +const ( + DefaultPromTarget = "seata_transaction_summary" +) + +var ( + Target string +) diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index 6bf2e58..d7072f8 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -17,6 +17,9 @@ import ( "strconv" ) + + +DefaultPromTarget var MetricsCmd = &cobra.Command{ Use: "metrics", Short: "Show Prometheus metrics", @@ -27,12 +30,9 @@ var MetricsCmd = &cobra.Command{ }, } -var ( - Target string -) func init() { - MetricsCmd.PersistentFlags().StringVar(&Target, "target", "seata_transaction_summary", "Namespace name") + MetricsCmd.PersistentFlags().StringVar(&Target, "target", DefaultPromTarget, "seata prometheus metrics name") } // showMetrics executes the metrics collection and chart generation diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a65cec1 --- /dev/null +++ b/go.sum @@ -0,0 +1,608 @@ +cloud.google.com/go v0.26.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.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= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +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.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= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +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/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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +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-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.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= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/guptarohit/asciigraph v0.7.3 h1:p05XDDn7cBTWiBqWb30mrwxd6oU0claAjqeytllnsPY= +github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +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.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= +github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +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/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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +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/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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +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/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= +github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +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 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.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +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= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +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= +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= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +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= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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-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= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/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/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-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-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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +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-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= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +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-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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-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-20190606165138-5da285871e9c/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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-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= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +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= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-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-20190621195816-6e04913cbbac/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-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= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +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-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= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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-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= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +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-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.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +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= +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= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +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.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= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +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-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= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +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-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= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +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-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-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= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/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-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= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +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= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +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.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/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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= +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= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= +k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= +k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= +k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= +k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= +k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= +k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From 87082f4b7b32a651f3b6bb9a92ef8e3ca1fa7c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 13:31:58 +0800 Subject: [PATCH 20/30] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E6=8F=90=E5=8D=87es-client=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/config/config.go | 20 +-- action/log/common.go | 7 - action/log/log.go | 29 +--- action/log/logadapter/common.go | 8 + action/log/logadapter/elasticsearch.go | 227 +++++++++++++++++++------ action/log/logadapter/local.go | 6 +- action/log/logadapter/loki.go | 7 +- action/prometheus/metrics.go | 4 - config.yml | 46 ++--- go.mod | 6 + go.sum | 15 ++ model/config.go | 33 +--- 12 files changed, 243 insertions(+), 165 deletions(-) create mode 100644 action/log/logadapter/common.go diff --git a/action/config/config.go b/action/config/config.go index 85e0909..ddfa5e3 100644 --- a/action/config/config.go +++ b/action/config/config.go @@ -50,20 +50,12 @@ func createSampleConfig() model.Config { Log: model.Log{ Clusters: []model.Cluster{ { - Name: "", - Collection: model.Collection{ - Enable: true, - Local: "", - }, - Analysis: model.Analysis{ - Enable: true, - Local: "", - }, - Display: model.Display{ - DisplayType: "", - Path: "", - Local: "", - }, + Name: "", + Types: "", + Address: "", + Source: "", + Username: "", + Password: "", }, }, }, diff --git a/action/log/common.go b/action/log/common.go index 8a473df..d8783a2 100644 --- a/action/log/common.go +++ b/action/log/common.go @@ -8,13 +8,6 @@ const ( DefaultNumber = 10 DefaultLogLevel = "" DefaultLocalLogLevel = "-" - - LokiAddressPath = "/loki/api/v1/query_range?" - TimeLayout = "2006-01-02-15:04:05" - - LocalQueryPath = "/query" - - ElasticsearchAuth = "elastic" ) // ElasticSearch diff --git a/action/log/log.go b/action/log/log.go index 3ef4a10..03dba2d 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -29,7 +29,7 @@ func init() { LogCmd.PersistentFlags().StringVar(&ResourceID, "resourceID", "", "seata resourceID") LogCmd.PersistentFlags().StringVar(&Message, "message", "", "seata message") LogCmd.PersistentFlags().IntVar(&Number, "number", DefaultNumber, "seata number") - LogCmd.PersistentFlags().StringVar(&Label, "label", "", "seata label") + LogCmd.PersistentFlags().StringVar(&Label, "label", "{}", "seata label") LogCmd.PersistentFlags().StringVar(&Start, "start", "", "seata start") LogCmd.PersistentFlags().StringVar(&End, "end", "", "seata end") } @@ -88,9 +88,11 @@ func getContext() (*model.Cluster, *logadapter.Currency, error) { for _, cluster := range config.Log.Clusters { if cluster.Name == contextName { currency := logadapter.Currency{ - Address: cluster.Address, - Source: cluster.Source, - Auth: cluster.Auth, + Address: cluster.Address, + Source: cluster.Source, + Username: cluster.Username, + Password: cluster.Password, + Index: cluster.Index, } return &cluster, ¤cy, nil } @@ -100,24 +102,7 @@ func getContext() (*model.Cluster, *logadapter.Currency, error) { func buildElasticSearchFilter() map[string]interface{} { filter := make(map[string]interface{}) - if Level != "" { - filter["logLevel"] = Level - } - if Module != "" { - filter["module"] = Module - } - if XID != "" { - filter["XID"] = XID - } - if BranchID != "" { - filter["BranchID"] = BranchID - } - if ResourceID != "" { - filter["ResourceID"] = ResourceID - } - if Message != "" { - filter["message"] = Message - } + filter["query"] = Label return filter } diff --git a/action/log/logadapter/common.go b/action/log/logadapter/common.go new file mode 100644 index 0000000..d325c75 --- /dev/null +++ b/action/log/logadapter/common.go @@ -0,0 +1,8 @@ +package logadapter + +const ( + LokiAddressPath = "/loki/api/v1/query_range?" + TimeLayout = "2006-01-02-15:04:05" + + LocalQueryPath = "/query" +) diff --git a/action/log/logadapter/elasticsearch.go b/action/log/logadapter/elasticsearch.go index 27701ba..8a8ec5f 100644 --- a/action/log/logadapter/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -5,15 +5,16 @@ import ( "crypto/tls" "encoding/json" "fmt" + "github.com/elastic/go-elasticsearch/v8" + "github.com/elastic/go-elasticsearch/v8/esapi" "github.com/olivere/elastic/v7" - "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" + "io" + "log" "net/http" "strings" ) -type Elasticsearch struct{} - // QueryLogs is a function that queries specific documents func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { client, err := createElasticClient(currency) @@ -23,8 +24,11 @@ func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *Curre indexName := currency.Source - // Build the query based on the filter provided - query, err := BuildQueryFromFilter(filter) + indexFields, err := getEsIndexList(currency) + if err != nil { + return err + } + query, err := buildQuery(filter, indexFields) if err != nil { return err } @@ -39,7 +43,7 @@ func (e *Elasticsearch) QueryLogs(filter map[string]interface{}, currency *Curre return fmt.Errorf("error fetching documents: %w", err) } - err = processSearchHits(searchResult) + err = processSearchHits(searchResult, currency) if err != nil { return err } @@ -60,7 +64,7 @@ func createElasticClient(currency *Currency) (*elastic.Client, error) { elastic.SetURL(currency.Address), elastic.SetHttpClient(httpClient), elastic.SetSniff(false), - elastic.SetBasicAuth(log.ElasticsearchAuth, currency.Auth), + elastic.SetBasicAuth(currency.Username, currency.Password), ) if err != nil { return nil, err @@ -68,9 +72,31 @@ func createElasticClient(currency *Currency) (*elastic.Client, error) { return client, nil } -// processSearchHits handles and formats the search results -func processSearchHits(searchResult *elastic.SearchResult) error { +// createElasticClient configures and creates a new Elasticsearch client +func createEsDefaultClient(currency *Currency) (*elasticsearch.Client, error) { + // 配置 Elasticsearch 客户端 + cfg := elasticsearch.Config{ + Addresses: []string{ + currency.Address, + }, + Username: currency.Username, + Password: currency.Password, + // 如果是自签名证书,跳过证书验证 + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + // 创建客户端实例 + es, err := elasticsearch.NewClient(cfg) + if err != nil { + log.Fatalf("Error creating the client: %s", err) + } + return es, nil +} +// processSearchHits handles and formats the search results +func processSearchHits(searchResult *elastic.SearchResult, currency *Currency) error { if len(searchResult.Hits.Hits) == 0 { return fmt.Errorf("no documents found") } @@ -83,7 +109,7 @@ func processSearchHits(searchResult *elastic.SearchResult) error { // Pretty print the document content for key, value := range doc { - if key == "log" { + if key == currency.Index { if strings.Contains(value.(string), "INFO") { tool.Logger.Info(fmt.Sprintf("%v", value)) } @@ -99,50 +125,155 @@ func processSearchHits(searchResult *elastic.SearchResult) error { return nil } -// BuildQueryFromFilter constructs a BoolQuery from the filter parameters -func BuildQueryFromFilter(filter map[string]interface{}) (*elastic.BoolQuery, error) { - query := elastic.NewBoolQuery() +// getFieldNames recursively extracts field names under the "fields" key +func getFieldNames(properties map[string]interface{}, prefix string) []string { + fieldNames := []string{} - for key, value := range filter { - switch key { - case "logLevel": - if v, ok := value.(string); ok { - query.Should(elastic.NewTermQuery("logLevel", v)) - } else { - return nil, fmt.Errorf("invalid type for logLevel, expected string") - } - case "module": - if v, ok := value.(string); ok { - query.Should(elastic.NewTermQuery("module", v)) - } else { - return nil, fmt.Errorf("invalid type for module, expected string") - } - case "xid": - if v, ok := value.(string); ok { - query.Should(elastic.NewTermQuery("xid", v)) - } else { - return nil, fmt.Errorf("invalid type for xid, expected string") + for fieldName, fieldValue := range properties { + // Generate the full path for the current field + fullName := fieldName + if prefix != "" { + fullName = prefix + "." + fieldName + } + + // Check if the field contains a "fields" node + if fieldMap, ok := fieldValue.(map[string]interface{}); ok { + if fields, ok := fieldMap["fields"].(map[string]interface{}); ok { + // If there is a "fields" node, iterate through its fields and add to the result + for subField := range fields { + fieldNames = append(fieldNames, fullName+"."+subField) + } } - case "branchId": - if v, ok := value.(string); ok { - query.Should(elastic.NewTermQuery("branchId", v)) - } else { - return nil, fmt.Errorf("invalid type for branchId, expected string") + + // If the field contains nested "properties", recursively parse subfields + if nestedProperties, ok := fieldMap["properties"].(map[string]interface{}); ok { + fieldNames = append(fieldNames, getFieldNames(nestedProperties, fullName)...) } - case "resourceId": - if v, ok := value.(string); ok { - query.Should(elastic.NewTermQuery("resourceId", v)) - } else { - return nil, fmt.Errorf("invalid type for resourceId, expected string") + } + } + + return fieldNames +} + +// extractFields extracts all field names from a nested map structure +func extractFields(data map[string]interface{}) []string { + var allFields []string + + // Iterate through each index to get its field names + for _, indexData := range data { + if indexMap, ok := indexData.(map[string]interface{}); ok { + if mappings, ok := indexMap["mappings"].(map[string]interface{}); ok { + if properties, ok := mappings["properties"].(map[string]interface{}); ok { + // Get all field names under "fields" and merge into the result + allFields = append(allFields, getFieldNames(properties, "")...) + } } - case "message": - if v, ok := value.(string); ok { - query.Should(elastic.NewMatchQuery("message", v)) + } + } + + return allFields +} + +// ParseJobString parses the input string and returns a map +func ParseJobString(input string) (map[string]string, error) { + // Remove curly braces + input = strings.Trim(input, "{}") + + // Split by ',' + parts := strings.Split(input, ",") + kvMap := make(map[string]string) + + for _, part := range parts { + // Split by '=' to get key-value pairs + kv := strings.Split(part, "=") + if len(kv) != 2 { + return nil, fmt.Errorf("invalid key=value pair: %s", part) + } + kvMap[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) + } + + return kvMap, nil +} + +// Contains checks if a string exists in a slice of strings +func Contains(slice []string, str string) bool { + for _, item := range slice { + if item == str { + return true + } + } + return false +} + +// getEsIndexList retrieves field names from the specified Elasticsearch index +func getEsIndexList(currency *Currency) ([]string, error) { + es, err := createEsDefaultClient(currency) + if err != nil { + return nil, fmt.Errorf("failed to create Elasticsearch client: %w", err) + } + + // Build the request to get the mappings + req := esapi.IndicesGetMappingRequest{ + Index: []string{currency.Source}, // Specify the index name + } + + // Execute the request + res, err := req.Do(context.Background(), es) + if err != nil { + log.Fatalf("Error getting mapping: %s", err) + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + log.Println("Failed to close body reader:", err) + } + }(res.Body) + + // Check if the response is successful + if res.IsError() { + log.Fatalf("Error response: %s", res.String()) + } + + // Read and parse the response + var result map[string]interface{} + if err := json.NewDecoder(res.Body).Decode(&result); err != nil { + log.Fatalf("Error parsing the response body: %s", err) + } + + // Call method to extract field names + indexFields := extractFields(result) + indexFields = RemoveKeywordSuffix(indexFields) + return indexFields, nil +} + +// RemoveKeywordSuffix removes ".keyword" suffix from each string in the slice +func RemoveKeywordSuffix(input []string) []string { + var result []string + for _, str := range input { + // Check if the string ends with ".keyword" + if strings.HasSuffix(str, ".keyword") { + // Remove the ".keyword" suffix + str = strings.TrimSuffix(str, ".keyword") + } + result = append(result, str) // Add the processed string to the result slice + } + return result +} + +// buildQuery constructs a BoolQuery based on the provided filter and index fields +func buildQuery(filter map[string]interface{}, indexFields []string) (*elastic.BoolQuery, error) { + query := elastic.NewBoolQuery() + if filter["query"].(string) != "{}" { + indexMap, err := ParseJobString(filter["query"].(string)) + if err != nil { + return query, err + } + for k, v := range indexMap { + if Contains(indexFields, k) { + query.Should(elastic.NewTermQuery(k, v)) } else { - return nil, fmt.Errorf("invalid type for message, expected string") + return query, fmt.Errorf("invalid index: %s", k) } - default: - return nil, fmt.Errorf("unknown field: %s", key) } } return query, nil diff --git a/action/log/logadapter/local.go b/action/log/logadapter/local.go index a6e0277..5a39f56 100644 --- a/action/log/logadapter/local.go +++ b/action/log/logadapter/local.go @@ -3,7 +3,6 @@ package logadapter import ( "encoding/json" "fmt" - "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" "io" "io/ioutil" @@ -11,9 +10,6 @@ import ( "strings" ) -// Local is the struct implementing the logging logic -type Local struct{} - // QueryLogs sends a request to the /query endpoint and retrieves logs based on the provided filter. // - filter: A map that holds log filtering parameters such as log level. // - currency: A struct containing information like the source application and API address. @@ -25,7 +21,7 @@ func (l *Local) QueryLogs(filter map[string]interface{}, currency *Currency, num } // Build the query URL using the filter and currency information - url := fmt.Sprintf("%s%s?application_id=%s&log_level=%s&limit=%d", currency.Address, log.LocalQueryPath, currency.Source, logLevel, number) + url := fmt.Sprintf("%s%s?application_id=%s&log_level=%s&limit=%d", currency.Address, LocalQueryPath, currency.Source, logLevel, number) // Send a GET request to the /query endpoint resp, err := http.Get(url) diff --git a/action/log/logadapter/loki.go b/action/log/logadapter/loki.go index e267675..d3ed7e3 100644 --- a/action/log/logadapter/loki.go +++ b/action/log/logadapter/loki.go @@ -3,7 +3,6 @@ package logadapter import ( "encoding/json" "fmt" - "github.com/seata/seata-ctl/action/log" "github.com/seata/seata-ctl/tool" "io" "io/ioutil" @@ -14,8 +13,6 @@ import ( "time" ) -type Loki struct{} - // QueryLogs queries logs from Loki based on the filter and settings provided func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, number int) error { @@ -40,7 +37,7 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb } params.Set("end", fmt.Sprintf("%d", res)) } - queryURL := currency.Address + log.LokiAddressPath + params.Encode() + queryURL := currency.Address + LokiAddressPath + params.Encode() // Send GET request to Loki resp, err := http.Get(queryURL) @@ -101,7 +98,7 @@ func parseToTimestamp(timeStr string) (int64, error) { } // Parse the time string using the specified layout and timezone - t, err := time.ParseInLocation(log.TimeLayout, timeStr, loc) + t, err := time.ParseInLocation(TimeLayout, timeStr, loc) if err != nil { return 0, fmt.Errorf("failed to parse time: %v", err) } diff --git a/action/prometheus/metrics.go b/action/prometheus/metrics.go index d7072f8..9030cba 100644 --- a/action/prometheus/metrics.go +++ b/action/prometheus/metrics.go @@ -17,9 +17,6 @@ import ( "strconv" ) - - -DefaultPromTarget var MetricsCmd = &cobra.Command{ Use: "metrics", Short: "Show Prometheus metrics", @@ -30,7 +27,6 @@ var MetricsCmd = &cobra.Command{ }, } - func init() { MetricsCmd.PersistentFlags().StringVar(&Target, "target", DefaultPromTarget, "seata prometheus metrics name") } diff --git a/config.yml b/config.yml index 653a6a4..1fe7607 100644 --- a/config.yml +++ b/config.yml @@ -16,49 +16,25 @@ log: - name: "es" types: "ElasticSearch" address: "https://localhost:9200" - source: "test" - auth: "bu4AC50REtt_7rUqddMe" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" + source: "logstash-2024.10.24" + username: "elastic" + password: "bu4AC50REtt_7rUqddMe" + index: "log" - name: "loki" types: "Loki" address: "http://localhost:3100" source: "" - auth: "" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" + username: "" + password: "" + index: "" - name: "local" types: "Local" address: "http://localhost:8080" source: "seata" - auth: "" - collection: - enable: true - local: "" - analysis: - enable: true - local: "" - display: - displayType: "" - path: "" - local: "" + username: "" + password: "" + index: "" context: kubernetes: "cluster1" prometheus: "prometheus" - log: "loki" + log: "es" diff --git a/go.mod b/go.mod index 75bd62f..7ed6998 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 toolchain go1.23.1 require ( + github.com/elastic/go-elasticsearch/v8 v8.15.0 github.com/guptarohit/asciigraph v0.7.3 github.com/jedib0t/go-pretty/v6 v6.4.7 github.com/olivere/elastic/v7 v7.0.32 @@ -22,10 +23,12 @@ require ( require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect @@ -57,6 +60,9 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/go.sum b/go.sum index a65cec1..f2bea78 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= +github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -71,8 +75,11 @@ github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXE 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -263,6 +270,14 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/model/config.go b/model/config.go index db5a793..f63c080 100644 --- a/model/config.go +++ b/model/config.go @@ -19,7 +19,7 @@ type Log struct { Clusters []Cluster `yaml:"clusters"` } -// Context 依据Context字段选择使用哪个配置 +// Context Select the appropriate configuration based on the Context field type Context struct { Kubernetes string `yaml:"kubernetes"` Prometheus string `yaml:"prometheus"` @@ -39,28 +39,11 @@ type Server struct { } type Cluster struct { - Name string `yaml:"name"` - Types string `yaml:"types"` - Address string `yaml:"address"` - Source string `yaml:"source"` - Auth string `yaml:"auth"` - Collection Collection `yaml:"collection"` - Analysis Analysis `yaml:"analysis"` - Display Display `yaml:"display"` -} - -type Collection struct { - Enable bool `yaml:"enable"` - Local string `yaml:"local"` -} - -type Analysis struct { - Enable bool `yaml:"enable"` - Local string `yaml:"local"` -} - -type Display struct { - DisplayType string `yaml:"displayType"` - Path string `yaml:"path"` - Local string `yaml:"local"` + Name string `yaml:"name"` + Types string `yaml:"types"` + Address string `yaml:"address"` + Source string `yaml:"source"` + Username string `yaml:"username"` + Password string `yaml:"password"` + Index string `yaml:"index"` } From 4928ec0586d582f03bf983cd41f15e02717f4527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 13:32:05 +0800 Subject: [PATCH 21/30] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E6=8F=90=E5=8D=87es-client=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/log/logadapter/types.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/action/log/logadapter/types.go b/action/log/logadapter/types.go index 4717916..58035f4 100644 --- a/action/log/logadapter/types.go +++ b/action/log/logadapter/types.go @@ -2,10 +2,18 @@ package logadapter import "time" +type Elasticsearch struct{} + +type Loki struct{} + +type Local struct{} + type Currency struct { - Address string `json:"address"` - Source string `json:"source"` - Auth string `json:"auth"` + Address string `json:"address"` + Source string `json:"source"` + Username string `json:"username"` + Password string `json:"password"` + Index string `json:"index"` } type SeataLog struct { From c95fca7f5fad0cca1a929decbbbb367c76b527a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 15:34:04 +0800 Subject: [PATCH 22/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9login=E7=99=BB=E9=99=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20=E6=8F=90=E5=8D=87=E5=8F=AF=E6=8B=93?= =?UTF-8?q?=E5=B1=95=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/log/log.go | 5 ----- action/log/logadapter/elasticsearch.go | 27 ++++++++++++-------------- action/root.go | 2 ++ cmd/root.go | 24 +++-------------------- 4 files changed, 17 insertions(+), 41 deletions(-) diff --git a/action/log/log.go b/action/log/log.go index 03dba2d..dcb958c 100644 --- a/action/log/log.go +++ b/action/log/log.go @@ -23,11 +23,6 @@ var LogCmd = &cobra.Command{ func init() { LogCmd.PersistentFlags().StringVar(&Level, "level", DefaultLogLevel, "seata log level") - LogCmd.PersistentFlags().StringVar(&Module, "module", "", "seata module") - LogCmd.PersistentFlags().StringVar(&XID, "xid", "", "seata expression") - LogCmd.PersistentFlags().StringVar(&BranchID, "banchID", "", "seata branchId") - LogCmd.PersistentFlags().StringVar(&ResourceID, "resourceID", "", "seata resourceID") - LogCmd.PersistentFlags().StringVar(&Message, "message", "", "seata message") LogCmd.PersistentFlags().IntVar(&Number, "number", DefaultNumber, "seata number") LogCmd.PersistentFlags().StringVar(&Label, "label", "{}", "seata label") LogCmd.PersistentFlags().StringVar(&Start, "start", "", "seata start") diff --git a/action/log/logadapter/elasticsearch.go b/action/log/logadapter/elasticsearch.go index 8a8ec5f..dd5a871 100644 --- a/action/log/logadapter/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -10,7 +10,6 @@ import ( "github.com/olivere/elastic/v7" "github.com/seata/seata-ctl/tool" "io" - "log" "net/http" "strings" ) @@ -72,25 +71,25 @@ func createElasticClient(currency *Currency) (*elastic.Client, error) { return client, nil } -// createElasticClient configures and creates a new Elasticsearch client +// createEsDefaultClient configures and creates a new Elasticsearch client func createEsDefaultClient(currency *Currency) (*elasticsearch.Client, error) { - // 配置 Elasticsearch 客户端 + // Configure the Elasticsearch client cfg := elasticsearch.Config{ Addresses: []string{ currency.Address, }, Username: currency.Username, Password: currency.Password, - // 如果是自签名证书,跳过证书验证 + // Skip certificate verification if using a self-signed certificate Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, } - // 创建客户端实例 + // Create the client instance es, err := elasticsearch.NewClient(cfg) if err != nil { - log.Fatalf("Error creating the client: %s", err) + return nil, fmt.Errorf("error creating the client: %s", err) } return es, nil } @@ -220,34 +219,34 @@ func getEsIndexList(currency *Currency) ([]string, error) { // Execute the request res, err := req.Do(context.Background(), es) if err != nil { - log.Fatalf("Error getting mapping: %s", err) + return nil, fmt.Errorf("error getting mapping: %s", err) } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { - log.Println("Failed to close body reader:", err) + tool.Logger.Error("error closing body") } }(res.Body) // Check if the response is successful if res.IsError() { - log.Fatalf("Error response: %s", res.String()) + return nil, fmt.Errorf("error response: %s", res.String()) } // Read and parse the response var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { - log.Fatalf("Error parsing the response body: %s", err) + return nil, fmt.Errorf("failed to make request to %s", err) } // Call method to extract field names indexFields := extractFields(result) - indexFields = RemoveKeywordSuffix(indexFields) + indexFields = removeKeywordSuffix(indexFields) return indexFields, nil } -// RemoveKeywordSuffix removes ".keyword" suffix from each string in the slice -func RemoveKeywordSuffix(input []string) []string { +// removeKeywordSuffix removes ".keyword" suffix from each string in the slice +func removeKeywordSuffix(input []string) []string { var result []string for _, str := range input { // Check if the string ends with ".keyword" @@ -271,8 +270,6 @@ func buildQuery(filter map[string]interface{}, indexFields []string) (*elastic.B for k, v := range indexMap { if Contains(indexFields, k) { query.Should(elastic.NewTermQuery(k, v)) - } else { - return query, fmt.Errorf("invalid index: %s", k) } } } diff --git a/action/root.go b/action/root.go index 3e86001..b8949c6 100644 --- a/action/root.go +++ b/action/root.go @@ -23,6 +23,7 @@ import ( "github.com/seata/seata-ctl/action/get" "github.com/seata/seata-ctl/action/k8s" "github.com/seata/seata-ctl/action/log" + "github.com/seata/seata-ctl/action/login" "github.com/seata/seata-ctl/action/prometheus" "github.com/seata/seata-ctl/action/reload" se "github.com/seata/seata-ctl/action/set" @@ -33,6 +34,7 @@ import ( func init() { rootCmd.AddCommand( quitCmd, + login.LoginCmd, get.GetCmd, del.TryCmd, reload.ReloadCmd, diff --git a/cmd/root.go b/cmd/root.go index a59b770..a32bc82 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,14 +19,13 @@ package cmd import ( "fmt" + "github.com/seata/seata-ctl/action/login" "github.com/seata/seata-ctl/tool" "os" "github.com/seata/seata-ctl/action" "github.com/seata/seata-ctl/action/common" - "github.com/seata/seata-ctl/seata" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var ( @@ -40,15 +39,6 @@ var ( ) func init() { - credential := seata.GetAuth() - rootCmd.PersistentFlags().StringVar(&credential.ServerIP, "ip", "127.0.0.1", "Seata Server IP") - rootCmd.PersistentFlags().IntVar(&credential.ServerPort, "port", 7091, "Seata Server Admin Port") - rootCmd.PersistentFlags().StringVar(&credential.Username, "username", "seata", "Username") - rootCmd.PersistentFlags().StringVar(&credential.Password, "password", "seata", "Password") - viper.BindPFlag("ip", rootCmd.PersistentFlags().Lookup("ip")) - viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port")) - viper.BindPFlag("username", rootCmd.PersistentFlags().Lookup("username")) - viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password")) rootCmd.SetHelpCommand(&cobra.Command{ Use: "seata-ctl", Short: "seata-ctl is a CLI tool for Seata", @@ -62,6 +52,7 @@ func init() { DisableDescriptions: true, HiddenDefaultCmd: true, } + } func Execute() { @@ -78,19 +69,10 @@ func Execute() { if arg == "-h" || arg == "--help" || arg == "version" { os.Exit(0) } - if arg == "--login" || arg == "login" { - address = seata.GetAuth().GetAddress() - err := seata.GetAuth().Login() - if err != nil { - fmt.Println("login failed!") - os.Exit(1) - } - } } var err error - for { - if address != "" { + if login.Address != "" { printPrompt(address) } err = common.ReadArgs(os.Stdin) From cc784c407bb9745ef202355e977a9ffdd2721768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 15:34:12 +0800 Subject: [PATCH 23/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9login=E7=99=BB=E9=99=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20=E6=8F=90=E5=8D=87=E5=8F=AF=E6=8B=93?= =?UTF-8?q?=E5=B1=95=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- action/log/common.go | 20 +++++-------------- action/login/login.go | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 action/login/login.go diff --git a/action/log/common.go b/action/log/common.go index d8783a2..7e480df 100644 --- a/action/log/common.go +++ b/action/log/common.go @@ -10,20 +10,10 @@ const ( DefaultLocalLogLevel = "-" ) -// ElasticSearch var ( - Level string - Module string - XID string - BranchID string - ResourceID string - Message string - Number int -) - -// Loki -var ( - Label string - Start string - End string + Label string + Number int + Start string + End string + Level string ) diff --git a/action/login/login.go b/action/login/login.go new file mode 100644 index 0000000..5cf6141 --- /dev/null +++ b/action/login/login.go @@ -0,0 +1,45 @@ +package login + +import ( + "fmt" + "github.com/seata/seata-ctl/seata" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "os" +) + +var Address string + +// LoginCmd 定义 login 子命令 +var LoginCmd = &cobra.Command{ + Use: "login", + Short: "Login to Seata server", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Attempting to login...") + Address = seata.GetAuth().GetAddress() + err := seata.GetAuth().Login() + if err != nil { + fmt.Println("Login failed!") + os.Exit(1) + } else { + fmt.Printf("Login successful to address: %s\n", Address) + printPrompt(Address) + } + }, +} + +func init() { + credential := seata.GetAuth() + LoginCmd.PersistentFlags().StringVar(&credential.ServerIP, "ip", "127.0.0.1", "Seata Server IP") + LoginCmd.PersistentFlags().IntVar(&credential.ServerPort, "port", 7091, "Seata Server Admin Port") + LoginCmd.PersistentFlags().StringVar(&credential.Username, "username", "seata", "Username") + LoginCmd.PersistentFlags().StringVar(&credential.Password, "password", "seata", "Password") + viper.BindPFlag("ip", LoginCmd.PersistentFlags().Lookup("ip")) + viper.BindPFlag("port", LoginCmd.PersistentFlags().Lookup("port")) + viper.BindPFlag("username", LoginCmd.PersistentFlags().Lookup("username")) + viper.BindPFlag("password", LoginCmd.PersistentFlags().Lookup("password")) +} + +func printPrompt(address string) { + fmt.Printf("%s > ", address) +} From e2ffae318291f0eadb0fa40b679a821a99863d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 17:13:08 +0800 Subject: [PATCH 24/30] fix k8s part output and fix readme --- README.md | 393 +++++++++++++++++++++++++++++++++++- action/k8s/common.go | 2 +- action/k8s/install.go | 3 +- action/k8s/status.go | 6 + action/k8s/uninstall.go | 5 +- action/k8s/utils/http.go | 5 +- action/k8s/utils/request.go | 1 - config.yml | 2 +- 8 files changed, 406 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ad16ae8..8064830 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,16 @@ go build . # How to use +# Seata + +Some Seata commands are used to connect to the Seata server for configuration browsing, transaction simulation, and other functions. To use these features, you must first log in using the `Login` command. + ## Login +Use this command to log in to the seata section. If the login is successful, the login information will be displayed at the beginning of the command line. + ```shell -$ seata-ctl --ip 127.0.0.1 --port 7091 --username seata --password seata +$ seata-ctl login --ip=127.0.0.1 --port=7091 --username=seata --password=seata 127.0.0.1:7091 > # input command here ``` @@ -299,4 +305,387 @@ Quit the session: ```shell 127.0.0.1:7091 > quit Quit the session -``` \ No newline at end of file +``` + +# Config + +Seata-ctl uses a YAML configuration file to set up various cluster addresses and connection details. Since manually creating this file can be complex for users, Seata-ctl provides a template for the configuration file. + +## Config + +### Describe + +Used to initialize the configuration file with no parameters required. + +After execution, a file named `config.yaml` will be created in the same directory as the terminal. If the file already exists, a message will indicate this. Currently, selecting a different location is not supported. + +### Usage + +``` +seata-ctl +config +``` + +After use, a file named 'config. yaml' will be created in the same directory as the terminal. If the file already exists, it will prompt that it already exists. We currently do not support selecting other locations. + +Each cluster can fill in multiple instances, using a context mechanism similar to kubeconfig to select which cluster and service to use. + +The format of the file and the meanings of each field are as follows:(The parameters of the log section will be explained in detail later in the log section) + +``` +kubernetes: + clusters: + - name: "" //kubernetes cluster name + kubeconfigpath: "" //kubeconfig path + ymlpath: "" //yml config path,not currently supported +prometheus: + servers: + - name: "" //prometheus name + address: "" //prometheus address + auth: "" //prometheus auth info,not currently supported +log: + clusters: + - name: "" //log name + types: "" //log type:ElasticSearch,Loki,Local + address: "" //log server address + source: "" //index name + username: "" //auth username + password: "" //auth password + index: "" //index name +context: + kubernetes: "" //choose which clusters to use,depend on name + prometheus: "" //choose which clusters to use,depend on name + log: "" //choose which clusters to use,depend on name +``` + +### Example + +If everything is normal, it will output: + +``` +seata-ctl +config + +Config created successfully! +``` + +If the file already exists, it will be output as follows: + +``` +seata-ctl +config + +Config file already exists! +``` + +The example of writing a configuration file is as follows: + +``` +kubernetes: + clusters: + - name: "cluster1" + kubeconfigpath: "/Users/wpy/.kube/config" + ymlpath: "" + - name: "seata" + kubeconfigpath: "/Users/wpy/Documents/Kubernetes/remotekube.txt" + ymlpath: "" +prometheus: + servers: + - name: "prometheus" + address: "http://localhost:9092" + auth: "" +log: + clusters: + - name: "es" + types: "ElasticSearch" + address: "https://localhost:9200" + source: "logstash-2024.10.24" + username: "elastic" + password: "bu4AC50REtt_7rUqddMe" + index: "log" + - name: "loki" + types: "Loki" + address: "http://localhost:3100" + source: "" + username: "" + password: "" + index: "" + - name: "local" + types: "Local" + address: "http://localhost:8080" + source: "seata" + username: "" + password: "" + index: "" +context: + kubernetes: "cluster1" + prometheus: "prometheus" + log: "es" +``` + +# Kubernetes + +Seata ctl provides various commands to operate Seata servers on Kubernetes clusters. + +## Install + +### Describe + +Use this command to apply CRD (Custom Resource Definition) and deploy controllers on a Kubernetes cluster` Seata tl 'will use these definitions to complete the deployment of Seata. + +### Usage + +``` +seata-ctl +install --namespace=default --image=apache/seata-controller:latest --name=seata-k8s-controller-manager +``` + +#### Arguments + +- `namespace`: Specifies the namespace to use (optional). If not specified, it defaults to `default`. +- `image`: Specifies the name of the image to use (optional). If not specified, it defaults to `apache/seata-controller:latest`. +- `name`: Specifies the name of the deployed controller (optional). If not specified, it defaults to `seata-k8s-controller-manager`. + +### Example + +If the CRD is deployed successfully, a message will display: `create seata crd success`, indicating that a CRD named `seataservers.operator.seata.apache.org` has been deployed in the specified namespace. + +If the Deployment is successful, a message will display: `Deployment created successfully`, indicating that a Deployment named `seata-k8s-controller-manager` has been created in the specified namespace, containing a single Pod. + +``` +install --namespace=default --image=apache/seata-controller:latest --name=seata-k8s-controller-manager + +INFO[0007] Create seata crd success +INFO[0007] Deployment created successfully +``` + +If the CRD already exists, a message will display: `seata crd already exists`. + +If the Deployment already exists, a message will display: `Deployment 'seata-k8s-controller-manager' already exists in the 'default' namespace`. + +``` +install --namespace=default --image=apache/seata-controller:latest --name=seata-k8s-controller-manager + +ERRO[0001] install CRD err: failed to send post request: seata crd already exists +ERRO[0001] install Controller err: Deployment 'seata-k8s-controller-manager' already exists in the 'default' namespace +``` + +## Uninstall + +### Describe + +Use this command to uninstall the CRD and the controller. + +### Usage + +``` +seata-ctl +uninstall --namespace=default --name=seata-k8s-controller-manager +``` + +#### Arguments + +- `namespace`: Specifies the namespace to use (optional). If not specified, it defaults to `default`. +- `name`: Specifies the name of the deployed controller (optional). If not specified, it defaults to `seata-k8s-controller-manager`. + +### Example + +If the CRD is deleted successfully, a message will display: `CRD seataservers.operator.seata.apache.org deleted successfully`. If the Deployment is deleted successfully, a message will display: `Deployment 'seata-k8s-controller-manager' deleted successfully from namespace 'default'`. + +``` +uninstall --namespace=default --name=seata-k8s-controller-manager + +INFO[0017] delete CRD seataservers.operator.seata.apache.org successfully. +INFO[0017] deleted Controller seata-k8s-controller-manager successfully +``` + +If the CRD does not exist, a message will display: `CRD seataservers.operator.seata.apache.org does not exist, no action taken`. If the Deployment does not exist, a message will display: `Deployment 'seata-k8s-controller-manager' does not exist in namespace 'default', no action taken`. + +``` +uninstall --namespace=default --name=seata-k8s-controller-manager + +ERRO[0005] CRD seataservers.operator.seata.apache.org does not exist, no action taken. +ERRO[0005] Deployment 'seata-k8s-controller-manager' does not exist in namespace 'default', no action taken. +``` + +# Deploy + +## Describe + +Use this command to deploy the Seata server on the Kubernetes cluster. + +## Usage + +``` +seata-ctl +deploy --name=test --replicas=1 --namespace=default --image=apache/seata-server:latest +``` + +After the CR is successfully deployed, the controller will automatically deploy the Seata server instance. + +> **Note**: Since the specific namespace where the CRD and controller are installed is uncertain, the Deployment command will not check whether the CRD and controller have been successfully deployed. Before using this command, please ensure that the Seata CRD and controller have been successfully deployed in your cluster. + +#### Arguments + +- `namespace`: Specifies the namespace. If not specified, it defaults to `default`. +- `replicas`: Number of deployment replicas. If not specified, it defaults to `1`. +- `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. +- `image`: Specifies the name of the image to use (optional). If not specified, it defaults to `apache/seata-server:latest`. + +## Example + +If the deployment is successful, a message will display: `CR install success, name: example-seataserver`. + +``` +deploy --name=test --replicas=1 --namespace=default --image=apache/seata-server:latest + +INFO[0013] CR install success,name: test +``` + +If the deployment already exists, a message will display: `This seata server already exists!`. + +``` +deploy --name=test --replicas=1 --namespace=default --image=apache/seata-server:latest + +ERRO[0007] deploy err:seata server already exist! name:test +``` + +If the deployment fails, a message displaying the relevant error information will appear. + +``` +deploy --name=test --replicas=1 --namespace=default --image=apache/seata-server:latest + +ERRO[0065] deploy err:the server could not find the requested resource +``` + +If this error occurs, it indicates that the CRD and controller were not successfully deployed. Please check your deployment status. + +# UnDeploy + +## Describe + +Use this command to uninstall the deployed Seata server. + +## Usage + +``` +seata-ctl +undeploy --name=test --namespace=default +``` + +After deletion, the controller will automatically remove the Seata server instance. + +#### Arguments + +- `namespace`: Specifies the namespace. If not specified, it defaults to `default`. +- `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. + +## Example + +If the uninstallation is successful, a message will display: `CR delete success, name: example-seataserver`, indicating that the CR has been successfully uninstalled, and the controller will automatically delete the Seata server from the cluster. + +``` +undeploy --name=test --namespace=default + +INFO[0308] CR delete success,name: test +``` + +If the CR is not found, a message will display: `seataservers.operator.seata.apache.org "example-seataserver" not found`. + +``` +undeploy --name=test --namespace=default + +ERRO[0290] undeploy error: seataservers.operator.seata.apache.org "test" not found +``` + +If an exception occurs, the relevant error information will be displayed. + +``` +undeploy --name=test --namespace=default + +ERRO[0284] undeploy error: the server could not find the requested resource +``` + +If this error occurs, it indicates that the CRD and controller were not successfully deployed. Please check your deployment status. + +# Scale + +## Describe + +Use this command to modify the number of replicas for the deployed Seata server. + +## Usage + +``` +seata-ctl + +scale --name=test --replicas=2 --namespace=default +``` + +After the operation, the controller will automatically adjust the replica count, which may take some time. + +#### Arguments + +- `namespace`: Specifies the namespace. If not specified, it defaults to `default`. +- `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. +- `replicas`: Number of deployment replicas. If not specified, it defaults to `1`. + +## Example + +If the modification is successful, a message will display: `CR scale success, name: example-seataserver`, indicating that the CR has been successfully updated, and the controller will automatically adjust the number of Seata server replicas in the cluster. + +``` +scale --name=test --replicas=2 --namespace=default + +INFO[0070] CR scale success,name: test +``` + +If the CR is not found, a message will display: `This seata server does not exist!`. + +``` +scale --name=test --replicas=2 --namespace=default + +ERRO[0058] scale err:This seata server does not exits!test +``` + +# Status + +## Describe + +Use this command to view the status of the deployed Seata server on the cluster. + +## Usage + +``` +seata-ctl +status --name=example-seataserver --namespace=default +``` + +> **Note**: This command essentially filters and displays Pods based on their labels. If Seata server Pods were created using other methods (for example, outside of the controller), the relevant Pods may not be found. + +#### Arguments + +`namespace`: Specifies the namespace. If not specified, it defaults to `default`. + +`name`: The name of the CR created when deploying the Seata server. If not specified, it defaults to `example-seataserver`. + +## Example + +If everything is functioning correctly, a list of `seata-pods` will be displayed. + +``` +status --name=example-seataserver --namespace=default + +INFO[0319] status: POD NAME STATUS +INFO[0319] status: ------------------------------------------- +INFO[0319] status: example-seataserver-0 Running +``` + +If no pods are found, an error message will be displayed. + +``` +status --name=example-seataserver1 --namespace=default + +ERRO[0002] get k8s status error: no matching pods found +``` + diff --git a/action/k8s/common.go b/action/k8s/common.go index a93e2f2..f8b52fb 100644 --- a/action/k8s/common.go +++ b/action/k8s/common.go @@ -3,7 +3,7 @@ package k8s const ( DefaultCRName = "example-seataserver" DefaultServerImage = "apache/seata-server:latest" - DefaultNamespace = "constants" + DefaultNamespace = "default" DefaultDeployName = "seata-k8s-controller-manager" DefaultControllerImage = "apache/seata-controller:latest" DefaultReplicas = 1 diff --git a/action/k8s/install.go b/action/k8s/install.go index fdcd70d..3434b2c 100644 --- a/action/k8s/install.go +++ b/action/k8s/install.go @@ -42,11 +42,10 @@ func init() { // DeployCRD deploys the custom resource definition. func DeployCRD() error { - res, err := utils.CreateRequest(CreateCrdPath, FilePath) + _, err := utils.CreateRequest(CreateCrdPath, FilePath) if err != nil { return err } - tool.Logger.Infof(res) return nil } diff --git a/action/k8s/status.go b/action/k8s/status.go index bda1a70..72bfc49 100644 --- a/action/k8s/status.go +++ b/action/k8s/status.go @@ -49,10 +49,16 @@ func getPodsStatusByLabel(namespace, labelSelector string) ([]string, error) { pods, err := client.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ LabelSelector: labelSelector, }) + if err != nil { return nil, fmt.Errorf("failed to list pods: %v", err) } + // Check if any pods were found + if len(pods.Items) == 0 { + return nil, fmt.Errorf("no matching pods found") // Alternatively, return a specific error message as needed + } + // Iterate over all Pods and get their status var statuses []string diff --git a/action/k8s/uninstall.go b/action/k8s/uninstall.go index 9d1a842..3a683f0 100644 --- a/action/k8s/uninstall.go +++ b/action/k8s/uninstall.go @@ -27,6 +27,7 @@ var UnInstallCmd = &cobra.Command{ func init() { UnInstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name") + UnInstallCmd.PersistentFlags().StringVar(&DeployName, "name", DefaultDeployName, "Deployment name") } func UninstallCRD() error { @@ -47,7 +48,7 @@ func UninstallCRD() error { // Check if the error is a "not found" error if errors.IsNotFound(err) { // The resource does not exist, output a message instead of returning an error - tool.Logger.Infof("CRD %s does not exist, no action taken.\n", CRDname) + tool.Logger.Errorf("CRD %s does not exist, no action taken.\n", CRDname) } else { // For other errors, log the error and exit the program tool.Logger.Errorf("delete CRD failed: %v", err) @@ -72,7 +73,7 @@ func UnDeploymentController() error { // Check if the error is a "not found" error if errors.IsNotFound(err) { // The deployment does not exist, output a message instead of returning an error - tool.Logger.Infof("Deployment '%s' does not exist in namespace '%s', no action taken.\n", DeployName, Namespace) + tool.Logger.Errorf("Deployment '%s' does not exist in namespace '%s', no action taken.\n", DeployName, Namespace) } else { // For other errors, log the error and exit the program tool.Logger.Errorf("Error deleting deployment: %s", err.Error()) diff --git a/action/k8s/utils/http.go b/action/k8s/utils/http.go index c3776fa..e06ade3 100644 --- a/action/k8s/utils/http.go +++ b/action/k8s/utils/http.go @@ -167,10 +167,11 @@ func sendPostRequest(context *ContextInfo, createCrdPath string, filePath string // Return appropriate response based on status code if resp.StatusCode == http.StatusCreated { - return "Create seata crd success", nil + tool.Logger.Infof("Create seata crd success") + return "", nil } if resp.StatusCode == http.StatusConflict { - return "Seata crd already exists", nil + return "", fmt.Errorf("seata crd already exists") } else { return "error: " + string(body), err } diff --git a/action/k8s/utils/request.go b/action/k8s/utils/request.go index 6a21c61..797c35f 100644 --- a/action/k8s/utils/request.go +++ b/action/k8s/utils/request.go @@ -3,7 +3,6 @@ package utils import "fmt" func CreateRequest(createCrdPath string, filePath string) (string, error) { - kubeConfigPath, err := GetKubeConfigPath() if err != nil { return "", fmt.Errorf("failed to get kubeconfig path: %v", err) diff --git a/config.yml b/config.yml index 1fe7607..a7b4f50 100644 --- a/config.yml +++ b/config.yml @@ -37,4 +37,4 @@ log: context: kubernetes: "cluster1" prometheus: "prometheus" - log: "es" + log: "es" \ No newline at end of file From 88e1219349034fc6588e008df9ef681fc5bc062f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 17:25:31 +0800 Subject: [PATCH 25/30] fix readme and add prometheus part. --- README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8064830..387de5d 100644 --- a/README.md +++ b/README.md @@ -508,13 +508,13 @@ ERRO[0005] CRD seataservers.operator.seata.apache.org does not exist, no action ERRO[0005] Deployment 'seata-k8s-controller-manager' does not exist in namespace 'default', no action taken. ``` -# Deploy +## Deploy -## Describe +### Describe Use this command to deploy the Seata server on the Kubernetes cluster. -## Usage +### Usage ``` seata-ctl @@ -532,7 +532,7 @@ After the CR is successfully deployed, the controller will automatically deploy - `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. - `image`: Specifies the name of the image to use (optional). If not specified, it defaults to `apache/seata-server:latest`. -## Example +### Example If the deployment is successful, a message will display: `CR install success, name: example-seataserver`. @@ -560,13 +560,13 @@ ERRO[0065] deploy err:the server could not find the requested resource If this error occurs, it indicates that the CRD and controller were not successfully deployed. Please check your deployment status. -# UnDeploy +## UnDeploy -## Describe +### Describe Use this command to uninstall the deployed Seata server. -## Usage +### Usage ``` seata-ctl @@ -580,7 +580,7 @@ After deletion, the controller will automatically remove the Seata server instan - `namespace`: Specifies the namespace. If not specified, it defaults to `default`. - `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. -## Example +### Example If the uninstallation is successful, a message will display: `CR delete success, name: example-seataserver`, indicating that the CR has been successfully uninstalled, and the controller will automatically delete the Seata server from the cluster. @@ -608,13 +608,13 @@ ERRO[0284] undeploy error: the server could not find the requested resource If this error occurs, it indicates that the CRD and controller were not successfully deployed. Please check your deployment status. -# Scale +## Scale -## Describe +### Describe Use this command to modify the number of replicas for the deployed Seata server. -## Usage +### Usage ``` seata-ctl @@ -630,7 +630,7 @@ After the operation, the controller will automatically adjust the replica count, - `name`: Name of the CR. If not specified, it defaults to `example-seataserver`. - `replicas`: Number of deployment replicas. If not specified, it defaults to `1`. -## Example +### Example If the modification is successful, a message will display: `CR scale success, name: example-seataserver`, indicating that the CR has been successfully updated, and the controller will automatically adjust the number of Seata server replicas in the cluster. @@ -648,13 +648,13 @@ scale --name=test --replicas=2 --namespace=default ERRO[0058] scale err:This seata server does not exits!test ``` -# Status +## Status -## Describe +### Describe Use this command to view the status of the deployed Seata server on the cluster. -## Usage +### Usage ``` seata-ctl @@ -669,7 +669,7 @@ status --name=example-seataserver --namespace=default `name`: The name of the CR created when deploying the Seata server. If not specified, it defaults to `example-seataserver`. -## Example +### Example If everything is functioning correctly, a list of `seata-pods` will be displayed. @@ -689,3 +689,56 @@ status --name=example-seataserver1 --namespace=default ERRO[0002] get k8s status error: no matching pods found ``` +# Prometheus + +Use this command to display data retrieved from Prometheus. + +Before using this command, you need to ensure that Prometheus is properly set up and is correctly collecting metrics from Seata. + +## Metrics + +### Describe + +Use this command to show the data retrieved from Prometheus. + +### Usage + +``` +seata-ctl +metrics --target=seata_transaction_summary +``` + +#### Arguments + +`target`: Specify the metric entry to query. This may vary depending on the system and version, so make sure it aligns with the metrics in Prometheus. + +### Example + +If everything is functioning correctly, the relevant Prometheus metrics will be displayed in the form of a line chart. + +``` +metrics --target=seata_transaction_summary + +INFO[0095] 10.00 ┼─────────╮ + 9.01 ┤ │ + 8.02 ┤ ╰╮ + 7.03 ┤ │ + 6.04 ┤ ╰╮ + 5.05 ┤ │ + 4.06 ┤ ╰╮ + 3.07 ┤ ╰╮ + 2.08 ┤ ╰─────────╮ + 1.09 ┤ ╰───────────╮ + 0.10 ┤ ╰───────────── + seata_transaction_summary +``` + +If an error occurs, an error message will be displayed. + +``` +metrics --target=seata_transaction_summary + +ERRO[0093] Failed to show metrics: no data found for metric: seata_transaction_summary +``` + +This error may indicate that the metric was not found. Please check your Prometheus metrics. \ No newline at end of file From 215e9d85aea8317d76c3505ba7b30d6e357d434e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 19:53:55 +0800 Subject: [PATCH 26/30] =?UTF-8?q?fix=20readme=20=EF=BC=8Cfix=20code=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 221 ++++++++++++++++++++++++- action/log/logadapter/elasticsearch.go | 2 + action/log/logadapter/loki.go | 4 +- config.yml | 2 +- 4 files changed, 225 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 387de5d..d0b5940 100644 --- a/README.md +++ b/README.md @@ -710,7 +710,7 @@ metrics --target=seata_transaction_summary #### Arguments -`target`: Specify the metric entry to query. This may vary depending on the system and version, so make sure it aligns with the metrics in Prometheus. +- `target`: Specify the metric entry to query. This may vary depending on the system and version, so make sure it aligns with the metrics in Prometheus. ### Example @@ -741,4 +741,221 @@ metrics --target=seata_transaction_summary ERRO[0093] Failed to show metrics: no data found for metric: seata_transaction_summary ``` -This error may indicate that the metric was not found. Please check your Prometheus metrics. \ No newline at end of file +This error may indicate that the metric was not found. Please check your Prometheus metrics. + +# Log + +Use this command to view logs on Kubernetes, currently supporting ElasticSearch, Loki, and a custom-developed logging platform. Configuration files and query parameters vary between platforms. + +## Log + +### Describe + +Use this command to retrieve Seata logs from different logging platforms. + +Before using this command, please ensure that your logging system is fully deployed and functioning properly. + +### Usage + +#### ElasticSearch + +``` +seata-ctl + +log --label={stream=stderr} --number=3 +``` + +Before using ES, you need to make the following configurations in the global configuration file. The meanings of the related parameters are as follows,An example of the configuration is as follows: + +``` + - name: "es" //name + types: "ElasticSearch" //es type + address: "https://localhost:9200" //es address + source: "logstash-2024.10.24" //es index name + username: "elastic" // es auth username + password: "bu4AC50REtt_7rUqddMe" //es auth password + index: "log" //doc type +``` + +> Note: Currently, only login with a username and password is supported for ES. If your ES has TLS encryption enabled, it is not supported at this time. + +Note: Currently, only login with a username and password is supported for ES. If your ES has TLS encryption enabled, it is not supported at this time. + +n the chart, the `index` field represents the output field for the final log display, which may vary across different index structures in ES.The source contains our index structure and the returned document content, but most of the fields are unnecessary for us. We use the index entry to select among these, and only the matching logs will be outputted. + +For example, if the returned structure of our query is this: + +``` +{ + "took": 2, + "timed_out": false, + "_shards": { + "total": 1, + "successful": 1, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": { + "value": 38, + "relation": "eq" + }, + "max_score": 1.0, + "hits": [ + { + "_index": "logstash-2024.10.24", + "_id": "KyvwyJIB5EKHPP6lI9Os", + "_score": 1.0, + "_ignored": ["log.keyword"], + "_source": { + "@timestamp": "2024-10-24T17:39:45.771Z", + "log": "2024-10-24T17:39:45Z\tINFO\tCreating a new SeataServer Service {default:seata-server-cluster}\t{\"controller\": \"seataserver\", \"controllerGroup\": \"operator.seata.apache.org\", \"controllerKind\": \"SeataServer\", \"SeataServer\": {\"name\":\"example-seataserver\",\"namespace\":\"default\"}, \"namespace\": \"default\", \"name\": \"example-seataserver\", \"reconcileID\": \"5912d1c4-6afd-4d66-8f11-eea6c54a1e4c\"}\n", + "stream": "stderr", + "time": "2024-10-24T17:39:45.771071Z", + "kubernetes": { + "pod_name": "seata-k8s-controller-manager-6448b86796-6l46n", + "namespace_name": "default", + "pod_id": "966edd0e-bc15-4276-9e6a-e255e84859ce", + "labels": { + "app": "seata-k8s-controller-manager", + "pod-template-hash": "6448b86796" + }, + "host": "minikube", + "container_name": "seata-k8s-controller-manager", + "docker_id": "b87df4627de30b0aab402aef4621fa46f45b3a1976dd6f466ab4a42bb8265455", + "container_hash": "bearslyricattack/seata-controller@sha256:84ddedd9fa63c4a3ab8aa3a5017065014826dc3a9cac8c8fff328fbf9c600f11", + "container_image": "bearslyricattack/seata-controller:latest" + } + } + } + ] + } +} + +``` + +We only need the logs related to the `log` field, so you can set `index` to `log`. + +##### Arguments + +- `label`: Specify the query entries in the format `{key1=value1, key2=value2, ...}`, where `key` is the name of the index in ES and `value` is the index's value. Neither the key nor the value requires quotation marks in the query.The default value is `{}`. +- `number`: The number of log entries returned, with a default value of 10. + +> Note: To accommodate different ES index structures, a preliminary index structure check will be conducted during log queries. If the index does not contain this structure, the query will not proceed and an error will be returned. + +#### Loki + +``` +seata-ctl + +log --label={job="seata-transaction"} --start=2025-10-18-14:21:21 --end=2025-10-18-22:16:14 --number=3 +``` + +Before using Loki, you also need to configure it in the configuration file. + +``` + - name: "loki" //loki name + types: "Loki" //type name + address: "http://localhost:3100" //loki address + source: "" + username: "" + password: "" +``` + +##### Arguments + +- **query**: The label for the query, following the native format, e.g., `{job="seata-transaction"}`, depending on the overall log format created. +- **start**: Start time in UTC timezone, formatted as `2024-10-18-12:32:54`. +- **end**: End time in UTC timezone, formatted as `2024-10-18-12:32:54`. +- **number**: The number of log entries returned. + +#### Local + +``` +seata-ctl + +log --level=INFO --number=5 +``` + +Similarly, to meet more diverse needs, we have developed a custom logging system for Seata applications on Kubernetes. This system will continue to evolve along with the Seata-K8s project. + +At first,configure it in the configuration file. + +``` + - name: "local" //name + types: "Local" //type + address: "http://localhost:8080" //address + source: "seata" //application + username: "" + password: "" + index: "" +``` + +### Example + +#### ElasticSearch + +If everything is functioning correctly, the specified log entries will be returned. + +``` +log --label={stream=stderr} --number=3 + +INFO[0015] 2024-10-24T17:39:45Z INFO Creating a new SeataServer Service {default:seata-server-cluster} {"controller": "seataserver", "controllerGroup": "operator.seata.apache.org", "controllerKind": "SeataServer", "SeataServer": {"name":"example-seataserver","namespace":"default"}, "namespace": "default", "name": "example-seataserver", "reconcileID": "5912d1c4-6afd-4d66-8f11-eea6c54a1e4c"} +INFO[0015] 2024-10-24T17:39:45Z INFO Creating a new SeataServer StatefulSet {default:example-seataserver} {"controller": "seataserver", "controllerGroup": "operator.seata.apache.org", "controllerKind": "SeataServer", "SeataServer": {"name":"example-seataserver","namespace":"default"}, "namespace": "default", "name": "example-seataserver", "reconcileID": "5912d1c4-6afd-4d66-8f11-eea6c54a1e4c"} +INFO[0015] 2024-10-24T17:39:45Z INFO SeataServer(default/example-seataserver) has not been synchronized yet, requeue in 10 seconds {"controller": "seataserver", "controllerGroup": "operator.seata.apache.org", "controllerKind": "SeataServer", "SeataServer": {"name":"example-seataserver","namespace":"default"}, "namespace": "default", "name": "example-seataserver", "reconcileID": "5912d1c4-6afd-4d66-8f11-eea6c54a1e4c"} +``` + +If the index does not exist, an error message will be displayed. + +``` +log --label={stream1111=stderr} --number=3 + +ERRO[0001] get log error: invalid index key: stream1111 +``` + +If no documents are found, an error indicating "no results found" will be returned. + +``` +log --label={stream=stderr11} --number=3 + +ERRO[0060] get log error: no documents found +``` + +If any other errors occur, an error message will be displayed. + +#### Loki + +If everything is functioning correctly, the specified log entries will be returned. + +``` +log --label={job="seata-transaction"} --start=2024-10-18-14:21:21 --end=2024-10-18-22:16:14 --number=2 + +INFO[0098] 2023-10-17 14:15:23.363 INFO [TransactionManager] --- Transaction [XID: 172.16.20.1:8091:123456789] ends with SUCCESS. +INFO[0098] 2023-10-17 14:15:23.360 INFO [RMHandler] --- Transaction resource committed successfully: ResourceId: jdbc:mysql://localhost:3306/seata_test, XID: 172.16.20.1:8091:123456789 +``` + +If no documents are found, an error indicating "no results found" will be returned. + +``` +log --label={job="seata-transaction"} --start=2025-10-18-14:21:21 --end=2025-10-18-22:16:14 --number=3 + +ERRO[0058] get log error: loki query returned no results +``` + +If any other errors occur, an error message will be displayed. + +#### Local + +If everything is functioning correctly, the specified log entries will be returned. + +``` +log --level=INFO --number=5 + +Peer example-seataserver-2.seata-server-cluster:9091 is connected +Peer example-seataserver-1.seata-server-cluster:9091 is connected +Node term 4 start preVote. +Peer example-seataserver-2.seata-server-cluster:9091 is connected +Peer example-seataserver-1.seata-server-cluster:9091 is connected +``` + +If any other errors occur, an error message will be displayed. \ No newline at end of file diff --git a/action/log/logadapter/elasticsearch.go b/action/log/logadapter/elasticsearch.go index dd5a871..29b1842 100644 --- a/action/log/logadapter/elasticsearch.go +++ b/action/log/logadapter/elasticsearch.go @@ -270,6 +270,8 @@ func buildQuery(filter map[string]interface{}, indexFields []string) (*elastic.B for k, v := range indexMap { if Contains(indexFields, k) { query.Should(elastic.NewTermQuery(k, v)) + } else { + return query, fmt.Errorf("invalid index key: %s", k) } } } diff --git a/action/log/logadapter/loki.go b/action/log/logadapter/loki.go index d3ed7e3..99b9385 100644 --- a/action/log/logadapter/loki.go +++ b/action/log/logadapter/loki.go @@ -66,11 +66,13 @@ func (l *Loki) QueryLogs(filter map[string]interface{}, currency *Currency, numb // Process and print logs if result.Status == "success" { + if len(result.Data.Result) == 0 { + return fmt.Errorf("loki query returned no results") + } for _, stream := range result.Data.Result { for _, entry := range stream.Values { // Extract timestamp and log message value := entry[1] - // Print the readable timestamp and log message if strings.Contains(value, "INFO") { tool.Logger.Info(fmt.Sprintf("%v", value)) diff --git a/config.yml b/config.yml index a7b4f50..9257f47 100644 --- a/config.yml +++ b/config.yml @@ -37,4 +37,4 @@ log: context: kubernetes: "cluster1" prometheus: "prometheus" - log: "es" \ No newline at end of file + log: "local" \ No newline at end of file From bcb9f3e12f41ce5c13fa4c8bd48956fa97ed9ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 19:55:09 +0800 Subject: [PATCH 27/30] =?UTF-8?q?fix=20readme=20=EF=BC=8Cfix=20code=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 81 ---------------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 go.mod diff --git a/go.mod b/go.mod deleted file mode 100644 index 7ed6998..0000000 --- a/go.mod +++ /dev/null @@ -1,81 +0,0 @@ -module github.com/seata/seata-ctl - -go 1.22.0 - -toolchain go1.23.1 - -require ( - github.com/elastic/go-elasticsearch/v8 v8.15.0 - github.com/guptarohit/asciigraph v0.7.3 - github.com/jedib0t/go-pretty/v6 v6.4.7 - github.com/olivere/elastic/v7 v7.0.32 - github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.8.1 - github.com/spf13/viper v1.16.0 - github.com/stretchr/testify v1.9.0 - gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.31.2 - k8s.io/apiextensions-apiserver v0.31.2 - k8s.io/apimachinery v0.31.2 - k8s.io/client-go v0.31.2 - sigs.k8s.io/yaml v1.4.0 -) - -require ( - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.4.2 // indirect - github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect -) From 19d2011a2092acc460fd164e38ba9c6b2bb8d73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 19:55:36 +0800 Subject: [PATCH 28/30] =?UTF-8?q?fix=20readme=20=EF=BC=8Cfix=20code=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.sum | 623 --------------------------------------------------------- 1 file changed, 623 deletions(-) delete mode 100644 go.sum diff --git a/go.sum b/go.sum deleted file mode 100644 index f2bea78..0000000 --- a/go.sum +++ /dev/null @@ -1,623 +0,0 @@ -cloud.google.com/go v0.26.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.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= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -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.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= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -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/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= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= -github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= -github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.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= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/guptarohit/asciigraph v0.7.3 h1:p05XDDn7cBTWiBqWb30mrwxd6oU0claAjqeytllnsPY= -github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= -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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -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.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= -github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -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/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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -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/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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -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/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= -github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -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 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.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -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= -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= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -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.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -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= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -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/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-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= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/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/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-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-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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -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-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= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -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-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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -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= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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-20190606165138-5da285871e9c/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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-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= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -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= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-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-20190621195816-6e04913cbbac/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-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= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -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-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= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -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-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= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -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-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.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -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= -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= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -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.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= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -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= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -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-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= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -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-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= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -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-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-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= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/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-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= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -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= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -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.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/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= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -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= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= -k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= -k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= -k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= -k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= -k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= -k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From 86bee6347d92cb196ac729bd95f74be23847e240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 19:58:16 +0800 Subject: [PATCH 29/30] =?UTF-8?q?fix=20readme=20=EF=BC=8Cfix=20code=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 81 +++++++++ go.sum | 531 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 612 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7ed6998 --- /dev/null +++ b/go.mod @@ -0,0 +1,81 @@ +module github.com/seata/seata-ctl + +go 1.22.0 + +toolchain go1.23.1 + +require ( + github.com/elastic/go-elasticsearch/v8 v8.15.0 + github.com/guptarohit/asciigraph v0.7.3 + github.com/jedib0t/go-pretty/v6 v6.4.7 + github.com/olivere/elastic/v7 v7.0.32 + github.com/sirupsen/logrus v1.9.3 + github.com/spf13/cobra v1.8.1 + github.com/spf13/viper v1.16.0 + github.com/stretchr/testify v1.9.0 + gopkg.in/yaml.v3 v3.0.1 + k8s.io/api v0.31.2 + k8s.io/apiextensions-apiserver v0.31.2 + k8s.io/apimachinery v0.31.2 + k8s.io/client-go v0.31.2 + sigs.k8s.io/yaml v1.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3999bbe --- /dev/null +++ b/go.sum @@ -0,0 +1,531 @@ +cloud.google.com/go v0.26.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.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= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +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.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= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +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/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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +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/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +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= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +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.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +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/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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +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= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +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= +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= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +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.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +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= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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-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= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +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/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/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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/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/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-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-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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +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-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= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +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-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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-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-20190606165138-5da285871e9c/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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-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= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +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= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-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-20190621195816-6e04913cbbac/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-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= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +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-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= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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-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= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +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-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/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= +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= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +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.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= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +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-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= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +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-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= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +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-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-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= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/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-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= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +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.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +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= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +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.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/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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= +k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= +k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +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-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From dd4ea29963fc7089d45ba96ce805b20a5b58949d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Mon, 28 Oct 2024 21:45:09 +0800 Subject: [PATCH 30/30] fix go.mod --- go.mod | 4 +-- go.sum | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7ed6998..a0001ea 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/seata/seata-ctl -go 1.22.0 - -toolchain go1.23.1 +go 1.23.1 require ( github.com/elastic/go-elasticsearch/v8 v8.15.0 diff --git a/go.sum b/go.sum index 3999bbe..f2bea78 100644 --- a/go.sum +++ b/go.sum @@ -50,9 +50,13 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= @@ -60,18 +64,32 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m 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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -98,9 +116,11 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -112,8 +132,10 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.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= @@ -128,22 +150,32 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/guptarohit/asciigraph v0.7.3 h1:p05XDDn7cBTWiBqWb30mrwxd6oU0claAjqeytllnsPY= github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= 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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 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.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +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= @@ -152,34 +184,62 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +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/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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +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/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +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 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.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -194,8 +254,11 @@ github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -207,8 +270,13 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -282,6 +350,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -292,6 +361,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -340,8 +410,10 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= 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= @@ -351,10 +423,12 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -405,6 +479,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f 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.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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= @@ -497,17 +573,23 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= 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= @@ -516,16 +598,26 @@ 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.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= +k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= +k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=