├── .gitignore ├── src ├── helmtrans.go ├── k8s │ ├── interface.go │ └── client.go └── util.go ├── templates └── chart │ ├── .helmignore │ ├── templates │ ├── service.yaml │ ├── _helpers.tpl │ └── deployment.yaml │ ├── Chart.yaml │ └── values.yaml ├── cmd ├── version.go ├── root.go └── helmtrans_cmd.go ├── main.go ├── README.md ├── go.mod ├── LICENSE └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | assets 18 | test -------------------------------------------------------------------------------- /src/helmtrans.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | // yaml to helm 4 | func YamltoHelm(filePath, outPutPath string) { 5 | defer Catch() 6 | ScanResFile(filePath, outPutPath, "") 7 | } 8 | 9 | 10 | // helm to yaml 11 | func HelmtoYaml(yamlStr string) { 12 | defer Catch() 13 | } 14 | 15 | 16 | // helm check 17 | func HelmCheck(filePath string) { 18 | defer Catch() 19 | } 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /templates/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | func init() { 9 | rootCmd.AddCommand(versionCmd) 10 | } 11 | 12 | var versionCmd = &cobra.Command{ 13 | Use: "version", 14 | Short: "Print the version number of helmtrans", 15 | Long: `All software has versions. This is helmtrans's`, 16 | Run: func(cmd *cobra.Command, args []string) { 17 | fmt.Println("helmtrans version is v0.1.0") 18 | }, 19 | } -------------------------------------------------------------------------------- /templates/chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceEnabled -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include ".name" . }} 6 | {{- if .Values.service.annotations }} 7 | {{- with .Values.service.annotations }} 8 | annotations: 9 | {{ toYaml . | indent 4 }} 10 | {{- end }} 11 | {{- end }} 12 | spec: 13 | selector: 14 | {{- include ".selectorLabels" . | nindent 4 }} 15 | type: {{ .Values.service.type | default "ClusterIP" }} 16 | ports: 17 | {{- range $key, $value := .Values.service.ports }} 18 | - name: {{ $key }} 19 | {{ toYaml $value | indent 6 }} 20 | {{- end }} 21 | {{- end }} -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 NAME HERE 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package main 17 | 18 | import ( 19 | "helmtrans/cmd" 20 | ) 21 | 22 | func main() { 23 | cmd.Execute() 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # helmtrans 2 | Yaml to helm 3 | 4 | ## Install 5 | 6 | ```sh 7 | ➜ curl -fsSl https://codeandcode.cn/apps/helmtrans/install.sh | bash 8 | ``` 9 | 10 | ## Usage: 11 | 12 | ### Yaml to Helm 13 | 14 | ```sh 15 | ➜ helmtrans -h 16 | 17 | helmtrans is a CLI library for Go that support yaml to helm. 18 | 19 | Usage: 20 | helmtrans [command] 21 | 22 | Available Commands: 23 | help Help about any command 24 | version Print the version number of helmtrans 25 | yamltohelm Transform yaml to helm 26 | 27 | Flags: 28 | -h, --help help for helmtrans 29 | ``` 30 | 31 | use yamltohelm command 32 | 33 | ```sh 34 | ➜ helmtrans yamltohelm -p [source path] -o [output path] 35 | ``` 36 | -o is optional param (default is output) 37 | 38 | 39 | ### Helm to Yaml 40 | 41 | you can use [**schelm**](https://github.com/databus23/schelm) to render a helm manifest to a directory. 42 | 43 | ## Maintainer 44 | - roancsu@163.com 45 | - codeandcode0x@gmail.com -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module helmtrans 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 // indirect 7 | github.com/drone/envsubst v1.0.2 8 | github.com/fatih/color v1.9.0 // indirect 9 | github.com/ghodss/yaml v1.0.0 10 | github.com/go-sql-driver/mysql v1.5.0 // indirect 11 | github.com/googleapis/gnostic v0.5.1 // indirect 12 | github.com/imdario/mergo v0.3.11 // indirect 13 | github.com/rs/xid v1.2.1 14 | github.com/spf13/cobra v1.1.1 15 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect 16 | golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect 17 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect 18 | golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect 19 | gopkg.in/yaml.v2 v2.3.0 20 | k8s.io/api v0.19.0 21 | k8s.io/apimachinery v0.19.0 22 | k8s.io/client-go v0.19.0 23 | k8s.io/klog v1.0.0 // indirect 24 | k8s.io/utils v0.0.0-20200912215256-4140de9c8800 // indirect 25 | ) 26 | -------------------------------------------------------------------------------- /src/k8s/interface.go: -------------------------------------------------------------------------------- 1 | package k8s 2 | 3 | import ( 4 | corev1 "k8s.io/api/core/v1" 5 | appsv1 "k8s.io/api/apps/v1" 6 | // metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 7 | ) 8 | 9 | //interface 10 | type K8sClientInf interface{ 11 | //service 12 | UnmarshalService(bytes []byte) corev1.Service 13 | GetServices(apps ...string) []*corev1.Service 14 | DeployService(svc corev1.Service) error 15 | //deployment 16 | UnmarshalDeployment(bytes []byte) appsv1.Deployment 17 | DeployDeployment(deploy appsv1.Deployment) error 18 | GetDeployments(apps ...string) []*appsv1.Deployment 19 | //configmap 20 | UnmarshalConfigMap(bytes []byte) corev1.ConfigMap 21 | DeployConfigMap(cm corev1.ConfigMap) error 22 | GetConfigMaps(cms ...string) []*corev1.ConfigMap 23 | //statefulset 24 | //pod 25 | GetPodsByLabel(app string) *corev1.PodList 26 | PodExecCommand(namespace, podName, command, containerName string) (string, string, error) 27 | 28 | //resource delete 29 | ResDelete(resourceType string, bytes []byte) 30 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 codeandcode0x 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: "" 3 | description: "" 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: "" -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 NAME HERE 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package cmd 17 | 18 | import ( 19 | "fmt" 20 | "github.com/spf13/cobra" 21 | "os" 22 | ) 23 | 24 | var cfgFile string 25 | 26 | // rootCmd represents the base command when called without any subcommands 27 | var rootCmd = &cobra.Command{ 28 | Use: "helmtrans [command] [options]", 29 | Short: "helmtrans can transform yaml to helm and the other way around", 30 | Long: ` 31 | helmtrans is a CLI library for Go that support yaml to helm.`, 32 | // Uncomment the following line if your bare application 33 | // has an action associated with it: 34 | // Run: func(cmd *cobra.Command, args []string) { }, 35 | } 36 | 37 | // Execute adds all child commands to the root command and sets flags appropriately. 38 | // This is called by main.main(). It only needs to happen once to the rootCmd. 39 | func Execute() { 40 | if err := rootCmd.Execute(); err != nil { 41 | fmt.Println(err) 42 | os.Exit(1) 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /cmd/helmtrans_cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | helmtrans "helmtrans/src" 6 | ) 7 | 8 | var filePath, outPutPath string 9 | 10 | //init 11 | func init() { 12 | //migration data 13 | helmtransYamltoHelmCmd.Flags().StringVarP(&filePath, "path", "p", "", "file path") 14 | helmtransYamltoHelmCmd.Flags().StringVarP(&outPutPath, "outpath", "o", "output", "output file path") 15 | rootCmd.AddCommand(helmtransYamltoHelmCmd) 16 | 17 | helmtransHelmtoYamlCmd.Flags().StringVarP(&filePath, "path", "p", "", "file path") 18 | // rootCmd.AddCommand(helmtransHelmtoYamlCmd) 19 | 20 | helmtransCheckCmd.Flags().StringVarP(&filePath, "path", "p", "", "file path") 21 | // rootCmd.AddCommand(helmtransCheckCmd) 22 | } 23 | 24 | //register deploy command 25 | var helmtransYamltoHelmCmd = &cobra.Command{ 26 | Use: "yamltohelm", 27 | Short: "Transform yaml to helm", 28 | Long: `Transform yaml to helm`, 29 | Run: func(cmd *cobra.Command, args []string) { 30 | //TO-DO 31 | helmtrans.YamltoHelm(filePath, outPutPath) 32 | }, 33 | } 34 | 35 | //register reset command 36 | var helmtransHelmtoYamlCmd = &cobra.Command{ 37 | Use: "helmtoyaml", 38 | Short: "Transform helm to yaml", 39 | Long: `Transform helm to yaml`, 40 | Run: func(cmd *cobra.Command, args []string) { 41 | //TO-DO 42 | }, 43 | } 44 | 45 | //register analyse command 46 | var helmtransCheckCmd = &cobra.Command{ 47 | Use: "check", 48 | Short: "Check helm", 49 | Long: `Check helm`, 50 | Run: func(cmd *cobra.Command, args []string) { 51 | //TO-DO 52 | 53 | }, 54 | } 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /templates/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define ".name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define ".fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define ".chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define ".labels" -}} 37 | helm.sh/chart: {{ include ".chart" . }} 38 | {{ include ".selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define ".selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include ".name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | app: {{ include ".name" . }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define ".serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include ".fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | 65 | 66 | {{/* 67 | Convert octal to decimal (e.g 644 => 420). For file permission modes, many people are more familiar with octal notation. 68 | However, due to yaml/json limitations, all the Kubernetes resources require file modes to be reported in decimal. 69 | */}} 70 | {{- define ".fileModeOctalToDecimal" -}} 71 | {{- $digits := splitList "" (toString .) -}} 72 | 73 | {{/* Make sure there are exactly 3 digits */}} 74 | {{- if ne (len $digits) 3 -}} 75 | {{- fail (printf "File mode octal expects exactly 3 digits: %s" .) -}} 76 | {{- end -}} 77 | 78 | {{/* Go Templates do not support variable updating, so we simulate it using dictionaries */}} 79 | {{- $accumulator := dict "res" 0 -}} 80 | {{- range $idx, $digit := $digits -}} 81 | {{- $digitI := atoi $digit -}} 82 | 83 | {{/* atoi from sprig swallows conversion errors, so we double check to make sure it is a valid conversion */}} 84 | {{- if and (eq $digitI 0) (ne $digit "0") -}} 85 | {{- fail (printf "Digit %d of %s is not a number: %s" $idx . $digit) -}} 86 | {{- end -}} 87 | 88 | {{/* Make sure each digit is less than 8 */}} 89 | {{- if ge $digitI 8 -}} 90 | {{- fail (printf "%s is not a valid octal digit" $digit) -}} 91 | {{- end -}} 92 | 93 | {{/* Since we don't have math.Pow, we hard code */}} 94 | {{- if eq $idx 0 -}} 95 | {{/* 8^2 */}} 96 | {{- $_ := set $accumulator "res" (add (index $accumulator "res") (mul $digitI 64)) -}} 97 | {{- else if eq $idx 1 -}} 98 | {{/* 8^1 */}} 99 | {{- $_ := set $accumulator "res" (add (index $accumulator "res") (mul $digitI 8)) -}} 100 | {{- else -}} 101 | {{/* 8^0 */}} 102 | {{- $_ := set $accumulator "res" (add (index $accumulator "res") (mul $digitI 1)) -}} 103 | {{- end -}} 104 | {{- end -}} 105 | {{- "res" | index $accumulator | toString | printf -}} 106 | {{- end -}} 107 | 108 | -------------------------------------------------------------------------------- /src/k8s/client.go: -------------------------------------------------------------------------------- 1 | package k8s 2 | 3 | import ( 4 | "k8s.io/client-go/kubernetes" 5 | corev1 "k8s.io/api/core/v1" 6 | appsv1 "k8s.io/api/apps/v1" 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "k8s.io/client-go/kubernetes/scheme" 9 | "k8s.io/client-go/tools/remotecommand" 10 | "k8s.io/client-go/tools/clientcmd" 11 | "k8s.io/apimachinery/pkg/labels" 12 | "github.com/ghodss/yaml" 13 | "path/filepath" 14 | "context" 15 | "strings" 16 | "log" 17 | "reflect" 18 | "os" 19 | "bytes" 20 | ) 21 | 22 | type K8sClient struct{ 23 | Clientset *kubernetes.Clientset 24 | Namespace string 25 | } 26 | 27 | //decode Service 28 | func (c *K8sClient) UnmarshalService(bytes []byte) corev1.Service{ 29 | var spec corev1.Service 30 | err := yaml.Unmarshal(bytes, &spec) 31 | if err != nil { 32 | panic(err.Error()) 33 | } 34 | return spec 35 | } 36 | 37 | //deploy service 38 | func (c *K8sClient) DeployService(svc corev1.Service) error{ 39 | _, err := c.Clientset.CoreV1().Services(c.Namespace).Create(context.TODO(), &svc, metav1.CreateOptions{}) 40 | if err != nil { 41 | if strings.Contains(err.Error(), "already exists") { 42 | existSvc := c.GetServices(svc.Name) 43 | resourceVersion := existSvc[0].ObjectMeta.ResourceVersion 44 | clusterIP := existSvc[0].Spec.ClusterIP 45 | svc.ObjectMeta.ResourceVersion = resourceVersion 46 | svc.Spec.ClusterIP = clusterIP 47 | _, errUpdate := c.Clientset.CoreV1().Services(c.Namespace).Update(context.TODO(), &svc, metav1.UpdateOptions{}) 48 | if errUpdate !=nil { 49 | log.Println("failed services updated error!", errUpdate) 50 | }else{ 51 | // //PrintLog() 52 | log.Print("success services ", "\""+svc.Name+"\"") 53 | } 54 | } 55 | return err 56 | }else{ 57 | // //PrintLog() 58 | log.Print("success services ", "\""+svc.Name+"\"") 59 | return nil 60 | } 61 | } 62 | 63 | //get services 64 | func (c *K8sClient) GetServices(apps ...string) []*corev1.Service { 65 | var svcs []*corev1.Service 66 | if len(apps) > 0 { 67 | for _, app := range apps { 68 | svc, _ := c.Clientset.CoreV1().Services(c.Namespace).Get(context.TODO(), app, metav1.GetOptions{}) 69 | if svc.Name == "" { 70 | log.Println("service not exists!") 71 | }else{ 72 | svcs = append(svcs, svc) 73 | } 74 | } 75 | }else{ 76 | svcList, _ := c.Clientset.CoreV1().Services(c.Namespace).List(context.TODO(), metav1.ListOptions{}) 77 | log.Printf("there are %d svc in the cluster\n", len(svcList.Items)) 78 | for _, svc := range svcList.Items { 79 | svcs = append(svcs, &svc) 80 | } 81 | } 82 | return svcs 83 | } 84 | 85 | //decode Deployment 86 | func (c *K8sClient) UnmarshalDeployment(bytes []byte) appsv1.Deployment{ 87 | var spec appsv1.Deployment 88 | err := yaml.Unmarshal(bytes, &spec) 89 | if err != nil { 90 | panic(err.Error()) 91 | } 92 | return spec 93 | } 94 | 95 | //deploy deployment 96 | func (c *K8sClient) DeployDeployment(deploy appsv1.Deployment) error{ 97 | _, err := c.Clientset.AppsV1().Deployments(c.Namespace).Create(context.TODO(), &deploy, metav1.CreateOptions{}) 98 | if err != nil { 99 | if strings.Contains(err.Error(), "already exists") { 100 | existDeploys := c.GetDeployments(deploy.Name) 101 | if !reflect.DeepEqual(existDeploys[0], deploy) { 102 | deploymentUpdate, errUpdate := c.Clientset.AppsV1().Deployments(c.Namespace).Update(context.TODO(), &deploy, metav1.UpdateOptions{}) 103 | if errUpdate !=nil { 104 | log.Println("failed deployments updated error!") 105 | }else{ 106 | if deploymentUpdate.Status.Replicas > 0 { 107 | log.Print("success deployments ", "\""+deploy.Name+"\"") 108 | // log.Println("~~~:replicas:", deploymentUpdate.Status.Replicas) 109 | // for _, st := range deploymentUpdate.Status.Conditions { 110 | // log.Println("~~~:conditions:", "->", st.Type, ":", st.Status) 111 | // } 112 | } 113 | } 114 | }else{ 115 | //PrintLog() 116 | log.Print("no need update") 117 | } 118 | } 119 | return err 120 | }else{ 121 | //PrintLog() 122 | log.Print("success deployments ", "\""+deploy.Name+"\"") 123 | return nil 124 | } 125 | } 126 | 127 | //get deploys 128 | func (c *K8sClient) GetDeployments(apps ...string) []*appsv1.Deployment{ 129 | var deploys []*appsv1.Deployment 130 | if len(apps) > 0 { 131 | for _, app := range apps { 132 | deploy, _ := c.Clientset.AppsV1().Deployments(c.Namespace).Get(context.TODO(), app, metav1.GetOptions{}) 133 | if deploy.Status.Replicas == 0 { 134 | // log.Println("resource not found!") 135 | }else{ 136 | // log.Println("resource already exists!") 137 | deploys = append(deploys, deploy) 138 | } 139 | } 140 | }else{ 141 | deployList, _ := c.Clientset.AppsV1().Deployments(c.Namespace).List(context.TODO(), metav1.ListOptions{}) 142 | log.Printf("there are %d deployment in the cluster\n", len(deployList.Items)) 143 | for _, deploy := range deployList.Items { 144 | deploys = append(deploys, &deploy) 145 | } 146 | } 147 | return deploys 148 | } 149 | 150 | //decode ConfigMap 151 | func (c *K8sClient) UnmarshalConfigMap(bytes []byte) corev1.ConfigMap{ 152 | var spec corev1.ConfigMap 153 | err := yaml.Unmarshal(bytes, &spec) 154 | if err != nil { 155 | panic(err.Error()) 156 | } 157 | return spec 158 | } 159 | 160 | //deploy Configmap 161 | func (c *K8sClient) DeployConfigMap(cm corev1.ConfigMap) error{ 162 | _, err := c.Clientset.CoreV1().ConfigMaps(c.Namespace).Create(context.TODO(), &cm, metav1.CreateOptions{}) 163 | if err != nil { 164 | if strings.Contains(err.Error(), "already exists") { 165 | _, errUpdate := c.Clientset.CoreV1().ConfigMaps(c.Namespace).Update(context.TODO(), &cm, metav1.UpdateOptions{}) 166 | if errUpdate !=nil { 167 | log.Println("failed configmaps updated error!") 168 | }else{ 169 | //PrintLog() 170 | log.Print("success configmaps ", "\""+cm.Name+"\"") 171 | } 172 | } 173 | return err 174 | }else{ 175 | //PrintLog() 176 | log.Print("success configmaps ", "\""+cm.Name+"\"") 177 | return nil 178 | } 179 | } 180 | 181 | //get Configmaps 182 | func (c *K8sClient) GetConfigMaps(cms ...string) []*corev1.ConfigMap{ 183 | var configmaps []*corev1.ConfigMap 184 | if len(cms) > 0 { 185 | for _, cm := range cms { 186 | configmap, _ := c.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(context.TODO(), cm, metav1.GetOptions{}) 187 | if configmap.Name == "" { 188 | log.Println("configmap not exists!") 189 | }else{ 190 | configmaps = append(configmaps, configmap) 191 | } 192 | } 193 | }else{ 194 | cms, _ := c.Clientset.CoreV1().ConfigMaps(c.Namespace).List(context.TODO(), metav1.ListOptions{}) 195 | log.Printf("there are %d cm in the cluster\n", len(cms.Items)) 196 | for _, cm := range cms.Items { 197 | configmaps = append(configmaps, &cm) 198 | } 199 | } 200 | return configmaps 201 | } 202 | 203 | //get pods by label 204 | func (c *K8sClient) GetPodsByLabel(app string) *corev1.PodList{ 205 | labelSelector := metav1.LabelSelector{MatchLabels: map[string]string{"app": "mariadb"}} 206 | listOptions := metav1.ListOptions{ 207 | LabelSelector: labels.Set(labelSelector.MatchLabels).String(), 208 | Limit: 100, 209 | } 210 | pods, _:= c.Clientset.CoreV1().Pods(c.Namespace).List(context.TODO(), listOptions) 211 | return pods 212 | } 213 | 214 | //pod exec command 215 | func (c *K8sClient) PodExecCommand(namespace, podName, command, containerName string) (string, string, error) { 216 | kubecfgpath := filepath.Join(os.Getenv("HOME"), ".kube", "config") 217 | //kubeconfig 218 | config, err := clientcmd.BuildConfigFromFlags("", kubecfgpath) 219 | if err != nil { 220 | kubecfgpath = filepath.Join("./run/", "kubeconfig") 221 | config, err = clientcmd.BuildConfigFromFlags("", kubecfgpath) 222 | if err != nil { 223 | panic(err) 224 | } 225 | } 226 | 227 | k8sCli, err := kubernetes.NewForConfig(config) 228 | if err != nil { 229 | return "", "", err 230 | } 231 | 232 | //command 233 | cmd := []string{ 234 | "sh", 235 | "-c", 236 | command, 237 | } 238 | const tty = false 239 | req := k8sCli.CoreV1().RESTClient().Post(). 240 | Resource("pods"). 241 | Name(podName). 242 | Namespace(namespace).SubResource("exec").Param("container", containerName) 243 | req.VersionedParams( 244 | &corev1.PodExecOptions{ 245 | Command: cmd, 246 | Stdin: false, 247 | Stdout: true, 248 | Stderr: true, 249 | TTY: tty, 250 | }, 251 | scheme.ParameterCodec, 252 | ) 253 | 254 | var stdout, stderr bytes.Buffer 255 | exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) 256 | if err != nil { 257 | return "", "", err 258 | } 259 | err = exec.Stream(remotecommand.StreamOptions{ 260 | Stdin: nil, 261 | Stdout: &stdout, 262 | Stderr: &stderr, 263 | }) 264 | if err != nil { 265 | return "", "", err 266 | } 267 | return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err 268 | } 269 | 270 | //resource delete 271 | func (c *K8sClient) ResDelete(resourceType string, bytes []byte) { 272 | switch(resourceType) { 273 | case "Service": 274 | name := c.UnmarshalService(bytes).Name 275 | err := c.Clientset.CoreV1().Services(c.Namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) 276 | if err != nil { 277 | log.Println("delete service error!", err) 278 | } 279 | log.Print("delete success services ", "\""+name+"\"") 280 | break 281 | case "Deployment": 282 | name := c.UnmarshalDeployment(bytes).Name 283 | err := c.Clientset.AppsV1().Deployments(c.Namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) 284 | if err != nil { 285 | log.Println("delete deployment error!", err) 286 | } 287 | log.Print("delete success deployment ", "\""+name+"\"") 288 | break 289 | case "ConfigMap": 290 | name := c.UnmarshalConfigMap(bytes).Name 291 | err := c.Clientset.CoreV1().ConfigMaps(c.Namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) 292 | if err != nil { 293 | log.Println("delete configmap error!", err) 294 | } 295 | log.Print("delete success configmap ", "\""+name+"\"") 296 | break 297 | case "StatefulSet": 298 | break 299 | } 300 | } 301 | 302 | 303 | 304 | -------------------------------------------------------------------------------- /src/util.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "github.com/ghodss/yaml" 5 | "k8s.io/client-go/kubernetes" 6 | "path/filepath" 7 | "encoding/json" 8 | "io/ioutil" 9 | "path" 10 | "log" 11 | "strings" 12 | "fmt" 13 | "os" 14 | "os/user" 15 | "helmtrans/src/k8s" 16 | "runtime" 17 | "bytes" 18 | "errors" 19 | "os/exec" 20 | "bufio" 21 | "io" 22 | ) 23 | 24 | var clientset *kubernetes.Clientset 25 | var apiClient k8s.K8sClientInf 26 | var configPath string 27 | var namespace string 28 | 29 | //init 30 | func init() { 31 | apiClient = &k8s.K8sClient{ 32 | nil, 33 | "default", 34 | } 35 | } 36 | 37 | //get resource yaml 38 | func GetResourceYaml(filePath string) []byte { 39 | bytes, err := ioutil.ReadFile(filePath) 40 | if err != nil { 41 | panic(err.Error()) 42 | } 43 | return bytes 44 | } 45 | 46 | //getResourceType 47 | func GetResourceType(bytes []byte) string{ 48 | typeJson, err := yaml.YAMLToJSON(bytes) 49 | if err != nil { 50 | panic("get resource type error !") 51 | } 52 | var typeIn interface{} 53 | json.Unmarshal(typeJson, &typeIn) 54 | return typeIn.(map[string]interface{})["kind"].(string) 55 | } 56 | 57 | //scan data file 58 | func ScanResFile(pathName, outPutPath ,subSourcePath string) { 59 | // mkdir output path 60 | if !FFExists(outPutPath) { 61 | mkErr := os.Mkdir(outPutPath, 0755) 62 | if mkErr != nil { 63 | log.Fatal(mkErr) 64 | } 65 | } 66 | // set source path 67 | sourcePath:= outPutPath 68 | // read dir 69 | rd, err := ioutil.ReadDir(pathName) 70 | if err != nil { 71 | log.Fatalln("scan data file - read file error!", err) 72 | } 73 | //resource delete 74 | for _, fi := range rd { 75 | // create dir 76 | if fi.IsDir() { 77 | err = os.Mkdir(sourcePath+"/"+fi.Name(), 0755) 78 | if err != nil { 79 | log.Fatal(err) 80 | } 81 | // copy templates 82 | CopyDir("templates/chart/", sourcePath+"/"+fi.Name()+"/") 83 | // subpath 84 | subSourcePath = sourcePath+"/"+fi.Name() 85 | } 86 | 87 | // scan files 88 | if !fi.IsDir() { 89 | dataExt := path.Ext(fi.Name()) 90 | if dataExt == ".yaml" { 91 | ScanFile(pathName, subSourcePath) 92 | } 93 | }else{ 94 | ScanResFile(pathName+"/"+fi.Name(), outPutPath, subSourcePath) 95 | } 96 | } 97 | } 98 | 99 | // scan res files 100 | func ScanFile(pathName, sourcePath string) { 101 | rd, err := ioutil.ReadDir(pathName) 102 | if err != nil { 103 | log.Fatalln("scan data file - read file error!", err) 104 | } 105 | 106 | for _, fi := range rd { 107 | // scan file 108 | if !fi.IsDir() { 109 | dataExt := path.Ext(fi.Name()) 110 | switch(dataExt) { 111 | case ".yaml": 112 | bytes := GetResourceYaml(pathName+"/"+fi.Name()) 113 | resourceType := GetResourceType(bytes) 114 | //write file 115 | switch(resourceType) { 116 | case "ConfigMap": 117 | spec := apiClient.UnmarshalConfigMap(bytes) 118 | t := readYaml(sourcePath+"/values.yaml") 119 | t["env"] = spec.Data 120 | WriteDataFile(JsonToYaml(t), sourcePath+"/values.yaml") 121 | break 122 | case "Deployment": 123 | spec := apiClient.UnmarshalDeployment(bytes) 124 | containerCount := len(spec.Spec.Template.Spec.Containers) 125 | // read values yaml 126 | t := readYaml(sourcePath+"/values.yaml") 127 | appName := spec.Name 128 | // just one container 129 | if containerCount == 1 { 130 | annotations := spec.Annotations 131 | env := spec.Spec.Template.Spec.Containers[0].Env 132 | image := spec.Spec.Template.Spec.Containers[0].Image 133 | imagePullPolicy := spec.Spec.Template.Spec.Containers[0].ImagePullPolicy 134 | ports := spec.Spec.Template.Spec.Containers[0].Ports 135 | readinessProbe := spec.Spec.Template.Spec.Containers[0].ReadinessProbe 136 | livenessProbe := spec.Spec.Template.Spec.Containers[0].LivenessProbe 137 | resources := spec.Spec.Template.Spec.Containers[0].Resources 138 | lifecycle := spec.Spec.Template.Spec.Containers[0].Lifecycle 139 | // image split 140 | imageSlice := strings.Split(image, ":") 141 | imageVersion := "master" 142 | if len(imageSlice) > 0 { 143 | imageVersion = imageSlice[1] 144 | } 145 | 146 | t["applicationName"] = appName 147 | t["deploymentAnnotations"] = annotations 148 | t["image"] = map[string]interface{}{"pullPolicy":imagePullPolicy, "repository":imageSlice[0], "tag":imageVersion} 149 | t["livenessProbe"] = livenessProbe 150 | t["readinessProbe"] = readinessProbe 151 | t["resources"] = resources 152 | t["containerPorts"] = ports 153 | envVars := make(map[string]string, 0) 154 | // merge env 155 | for key, val := range t["env"].(map[string]interface{}) { 156 | envVars[key] = val.(string) 157 | } 158 | 159 | for _, val := range env { 160 | envVars[val.Name] = val.Value 161 | } 162 | 163 | t["env"] = envVars 164 | 165 | if lifecycle != nil { 166 | t["shutdownDelay"] =1 167 | t["lifecycle"] = lifecycle 168 | } 169 | }else { // multi containers 170 | t["containers"] = spec.Spec.Template.Spec.Containers 171 | t["env"] = make(map[string]interface{}, 0) 172 | } 173 | 174 | // container count 175 | t["containerCount"] = containerCount 176 | // add image pull secrets 177 | imagePullSecrets := spec.Spec.Template.Spec.ImagePullSecrets 178 | secrets := []string{} 179 | for _, val := range imagePullSecrets { 180 | secrets = append(secrets, val.Name) 181 | } 182 | t["imagePullSecrets"] = secrets 183 | 184 | // write data to file 185 | WriteDataFile(JsonToYaml(t), sourcePath+"/values.yaml") 186 | 187 | // read chart yaml 188 | c := readYaml(sourcePath+"/Chart.yaml") 189 | c["name"] = appName 190 | // write data to file 191 | WriteDataFile(JsonToYaml(c), sourcePath+"/Chart.yaml") 192 | 193 | break 194 | case "Service": 195 | spec := apiClient.UnmarshalService(bytes) 196 | t := readYaml(sourcePath+"/values.yaml") 197 | t["serviceEnabled"]=true 198 | t["service"] = spec.Spec 199 | WriteDataFile(JsonToYaml(t), sourcePath+"/values.yaml") 200 | break 201 | } 202 | 203 | break 204 | } 205 | }else{ 206 | ScanFile(pathName+"/"+fi.Name(), sourcePath) 207 | } 208 | } 209 | } 210 | 211 | //map to string 212 | func createKeyValuePairs(m map[string]string) string { 213 | b := new(bytes.Buffer) 214 | for key, value := range m { 215 | fmt.Fprintf(b, "%s: \"%s\"\n", key, value) 216 | } 217 | return b.String() 218 | } 219 | 220 | //josn to 221 | func JsonToYaml(t map[string]interface {}) string{ 222 | jsonStr, _ := json.Marshal(t) 223 | yamlStr, err := yaml.JSONToYAML(jsonStr) 224 | if err != nil { 225 | fmt.Printf("err: %v\n", err) 226 | } 227 | return string(yamlStr) 228 | } 229 | 230 | //read yaml 231 | func readYaml(path string) map[string]interface{}{ 232 | t := map[string]interface{}{} 233 | buffer, err := ioutil.ReadFile(path) 234 | err = yaml.Unmarshal(buffer, &t) 235 | if err != nil { 236 | log.Fatalf(err.Error()) 237 | } 238 | return t 239 | } 240 | 241 | //read data file 242 | func ReadDataFile(path string) []byte { 243 | data, err := ioutil.ReadFile(path) 244 | if err != nil { 245 | log.Fatalln("read "+path+" file failed!", err) 246 | } 247 | return data 248 | } 249 | 250 | //write data file 251 | func WriteDataFile(yamlStr, filePath string) { 252 | //create file 253 | dataFile, err := os.Create(filePath) 254 | if err != nil { 255 | log.Fatalln("create data file failed!", err) 256 | } 257 | //close file 258 | defer dataFile.Close() 259 | //create bufio write 260 | dataFileWriter := bufio.NewWriter(dataFile) 261 | _, errWrite := dataFileWriter.WriteString(string(yamlStr)) 262 | if errWrite != nil { 263 | log.Fatalln("write data to file err!", errWrite) 264 | } 265 | dataFileWriter.Flush() 266 | } 267 | 268 | // copy dir 269 | func CopyDir(srcPath string, destPath string) error { 270 | //检测目录正确性 271 | if srcInfo, err := os.Stat(srcPath); err != nil { 272 | fmt.Println(err.Error()) 273 | return err 274 | } else { 275 | if !srcInfo.IsDir() { 276 | e := errors.New("src 不是一个正确的目录!") 277 | fmt.Println(e.Error()) 278 | return e 279 | } 280 | } 281 | if destInfo, err := os.Stat(destPath); err != nil { 282 | fmt.Println(err.Error()) 283 | return err 284 | } else { 285 | if !destInfo.IsDir() { 286 | e := errors.New("dest 不是一个正确的目录!") 287 | fmt.Println(e.Error()) 288 | return e 289 | } 290 | } 291 | 292 | err := filepath.Walk(srcPath, func(path string, f os.FileInfo, err error) error { 293 | if f == nil { 294 | return err 295 | } 296 | if !f.IsDir() { 297 | path := strings.Replace(path, "\\", "/", -1) 298 | destNewPath := strings.Replace(path, srcPath, destPath, -1) 299 | copyFile(path, destNewPath) 300 | } 301 | return nil 302 | }) 303 | if err != nil { 304 | fmt.Printf(err.Error()) 305 | } 306 | return err 307 | } 308 | 309 | // copy files 310 | func copyFile(src, dest string) (w int64, err error) { 311 | srcFile, err := os.Open(src) 312 | if err != nil { 313 | fmt.Println(err.Error()) 314 | return 315 | } 316 | defer srcFile.Close() 317 | //分割path目录 318 | destSplitPathDirs := strings.Split(dest, "/") 319 | 320 | //检测时候存在目录 321 | destSplitPath := "" 322 | for index, dir := range destSplitPathDirs { 323 | if index < len(destSplitPathDirs)-1 { 324 | destSplitPath = destSplitPath + dir + "/" 325 | b, _ := pathExists(destSplitPath) 326 | if b == false { 327 | // fmt.Println("创建目录:" + destSplitPath) 328 | //创建目录 329 | err := os.Mkdir(destSplitPath, os.ModePerm) 330 | if err != nil { 331 | fmt.Println(err) 332 | } 333 | } 334 | } 335 | } 336 | dstFile, err := os.Create(dest) 337 | if err != nil { 338 | fmt.Println(err.Error()) 339 | return 340 | } 341 | defer dstFile.Close() 342 | 343 | return io.Copy(dstFile, srcFile) 344 | } 345 | 346 | //检测文件夹路径时候存在 347 | func pathExists(path string) (bool, error) { 348 | _, err := os.Stat(path) 349 | if err == nil { 350 | return true, nil 351 | } 352 | if os.IsNotExist(err) { 353 | return false, nil 354 | } 355 | return false, err 356 | } 357 | 358 | //file exist 359 | func FileExist(path string) bool { 360 | _, err := os.Lstat(path) 361 | return !os.IsNotExist(err) 362 | } 363 | 364 | //get Home 365 | func GetHome() (string, error) { 366 | user, err := user.Current() 367 | if nil == err { 368 | return user.HomeDir, nil 369 | } 370 | 371 | // cross compile support 372 | if "windows" == runtime.GOOS { 373 | return homeWindows() 374 | } 375 | 376 | // Unix-like system, so just assume Unix 377 | return homeUnix() 378 | } 379 | 380 | func homeUnix() (string, error) { 381 | // First prefer the HOME environmental variable 382 | if home := os.Getenv("HOME"); home != "" { 383 | return home, nil 384 | } 385 | 386 | // If that fails, try the shell 387 | var stdout bytes.Buffer 388 | cmd := exec.Command("sh", "-c", "eval echo ~$USER") 389 | cmd.Stdout = &stdout 390 | if err := cmd.Run(); err != nil { 391 | return "", err 392 | } 393 | 394 | result := strings.TrimSpace(stdout.String()) 395 | if result == "" { 396 | return "", errors.New("blank output when reading home directory") 397 | } 398 | 399 | return result, nil 400 | } 401 | 402 | func homeWindows() (string, error) { 403 | drive := os.Getenv("HOMEDRIVE") 404 | path := os.Getenv("HOMEPATH") 405 | home := drive + path 406 | if drive == "" || path == "" { 407 | home = os.Getenv("USERPROFILE") 408 | } 409 | if home == "" { 410 | return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank") 411 | } 412 | 413 | return home, nil 414 | } 415 | 416 | //file or folder check exists 417 | func FFExists(path string) bool { 418 | _, err := os.Stat(path) 419 | if err != nil { 420 | if os.IsExist(err) { 421 | return true 422 | } 423 | return false 424 | } 425 | return true 426 | } 427 | 428 | //catch 429 | func Catch() { 430 | if r := recover(); r != nil { 431 | fmt.Println("ERROR:", r) 432 | var err error 433 | switch x := r.(type) { 434 | case string: 435 | err = errors.New(x) 436 | case error: 437 | err = x 438 | default: 439 | err = errors.New("") 440 | } 441 | if err != nil { 442 | } 443 | } 444 | } 445 | 446 | //check error 447 | func checkErr(err error) { 448 | if err != nil { 449 | log.Fatal(err) 450 | } 451 | } 452 | 453 | 454 | -------------------------------------------------------------------------------- /templates/chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- /* 2 | The main Deployment Controller for the application being deployed. This resource manages the creation and replacement 3 | of the Pods backing your application. 4 | */ -}} 5 | {{- /* 6 | We must decide whether or not there are volumes to inject. The logic to decide whether or not to inject is based on 7 | whether or not there are configMaps OR secrets that are specified as volume mounts (`as: volume` attributes). We do this 8 | by using a map to track whether or not we have seen a volume type. We have to use a map because we can't update a 9 | variable in helm chart templates. 10 | 11 | Similarly, we need to decide whether or not there are environment variables to add 12 | 13 | We need this because certain sections are omitted if there are no volumes or environment variables to add. 14 | */ -}} 15 | {{/* Go Templates do not support variable updating, so we simulate it using dictionaries */}} 16 | {{- $hasInjectionTypes := dict "hasVolume" false "hasEnvVars" false "hasIRSA" false "exposePorts" false -}} 17 | {{- if .Values.envVars -}} 18 | {{- $_ := set $hasInjectionTypes "hasEnvVars" true -}} 19 | {{- end -}} 20 | {{- if .Values.additionalContainerEnv -}} 21 | {{- $_ := set $hasInjectionTypes "hasEnvVars" true -}} 22 | {{- end -}} 23 | {{- if gt (len .Values.aws.irsa.role_arn) 0 -}} 24 | {{- $_ := set $hasInjectionTypes "hasEnvVars" true -}} 25 | {{- $_ := set $hasInjectionTypes "hasVolume" true -}} 26 | {{- $_ := set $hasInjectionTypes "hasIRSA" true -}} 27 | {{- end -}} 28 | {{- $allSecrets := values .Values.secrets -}} 29 | {{- range $allSecrets -}} 30 | {{- if eq (index . "as") "volume" -}} 31 | {{- $_ := set $hasInjectionTypes "hasVolume" true -}} 32 | {{- else if eq (index . "as") "environment" -}} 33 | {{- $_ := set $hasInjectionTypes "hasEnvVars" true -}} 34 | {{- else if eq (index . "as") "none" -}} 35 | {{- /* noop */ -}} 36 | {{- else -}} 37 | {{- fail printf "secrets config has unknown type: %s" (index . "as") -}} 38 | {{- end -}} 39 | {{- end -}} 40 | {{- $allConfigMaps := values .Values.configMaps -}} 41 | {{- range $allConfigMaps -}} 42 | {{- if eq (index . "as") "volume" -}} 43 | {{- $_ := set $hasInjectionTypes "hasVolume" true -}} 44 | {{- else if eq (index . "as") "environment" -}} 45 | {{- $_ := set $hasInjectionTypes "hasEnvVars" true -}} 46 | {{- else if eq (index . "as") "none" -}} 47 | {{- /* noop */ -}} 48 | {{- else -}} 49 | {{- fail printf "configMaps config has unknown type: %s" (index . "as") -}} 50 | {{- end -}} 51 | {{- end -}} 52 | {{- if gt (len .Values.persistentVolumes) 0 -}} 53 | {{- $_ := set $hasInjectionTypes "hasVolume" true -}} 54 | {{- end -}} 55 | --- 56 | apiVersion: apps/v1 57 | kind: Deployment 58 | metadata: 59 | name: {{ include ".fullname" . }} 60 | labels: 61 | # These labels are required by helm. You can read more about required labels in the chart best practices guide: 62 | # https://docs.helm.sh/chart_best_practices/#standard-labels 63 | helm.sh/chart: {{ include ".chart" . }} 64 | app.kubernetes.io/name: {{ include ".name" . }} 65 | app.kubernetes.io/instance: {{ .Release.Name }} 66 | app.kubernetes.io/managed-by: {{ .Release.Service }} 67 | {{- range $key, $value := .Values.additionalDeploymentLabels }} 68 | {{ $key }}: {{ $value }} 69 | {{- end}} 70 | {{- with .Values.deploymentAnnotations }} 71 | annotations: 72 | {{ toYaml . | indent 4 }} 73 | {{- end }} 74 | spec: 75 | replicas: {{ .Values.replicaCount }} 76 | selector: 77 | matchLabels: 78 | app.kubernetes.io/name: {{ include ".name" . }} 79 | app.kubernetes.io/instance: {{ .Release.Name }} 80 | gruntwork.io/deployment-type: main 81 | template: 82 | metadata: 83 | labels: 84 | app.kubernetes.io/name: {{ include ".name" . }} 85 | app.kubernetes.io/instance: {{ .Release.Name }} 86 | gruntwork.io/deployment-type: main 87 | {{- range $key, $value := .Values.additionalPodLabels }} 88 | {{ $key }}: {{ $value }} 89 | {{- end }} 90 | {{- with .Values.podAnnotations }} 91 | annotations: 92 | {{ toYaml . | indent 8 }} 93 | {{- end }} 94 | spec: 95 | {{- if gt (len .Values.serviceAccount.name) 0 }} 96 | serviceAccountName: "{{ .Values.serviceAccount.name }}" 97 | {{- end }} 98 | {{- if hasKey .Values.serviceAccount "automountServiceAccountToken" }} 99 | automountServiceAccountToken : {{ .Values.serviceAccount.automountServiceAccountToken }} 100 | {{- end }} 101 | {{- if .Values.podSecurityContext }} 102 | securityContext: 103 | {{ toYaml .Values.podSecurityContext | indent 8 }} 104 | {{- end}} 105 | containers: 106 | {{- if gt (int .Values.containerCount) 1 }} 107 | {{- with .Values.containers }} 108 | {{- toYaml . | nindent 8 }} 109 | {{- end}} 110 | {{- else }} 111 | - name: {{ .Values.applicationName }} 112 | {{- $repo := required "image.repository is required" .Values.image.repository }} 113 | {{- $tag := required "image.tag is required" .Values.image.tag }} 114 | image: "{{ $repo }}:{{ $tag }}" 115 | imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }} 116 | {{- if .Values.containerCommand }} 117 | command: 118 | {{ toYaml .Values.containerCommand | indent 12 }} 119 | {{- end }} 120 | 121 | {{- if index $hasInjectionTypes "exposePorts" }} 122 | ports: 123 | {{- range $key, $portSpec := .Values.containerPorts }} 124 | {{- if not $portSpec.disabled }} 125 | - name: {{ $key | quote }} 126 | containerPort: {{ int $portSpec.containerPort }} 127 | protocol: {{ $portSpec.protocol }} 128 | {{- end }} 129 | {{- end }} 130 | {{- end }} 131 | 132 | {{- if .Values.livenessProbe }} 133 | livenessProbe: 134 | {{ toYaml .Values.livenessProbe | indent 12 }} 135 | {{- end }} 136 | 137 | {{- if .Values.readinessProbe }} 138 | readinessProbe: 139 | {{ toYaml .Values.readinessProbe | indent 12 }} 140 | {{- end }} 141 | {{- if .Values.securityContext }} 142 | securityContext: 143 | {{ toYaml .Values.securityContext | indent 12 }} 144 | {{- end}} 145 | resources: 146 | {{ toYaml .Values.containerResources | indent 12 }} 147 | env: 148 | {{- if index $hasInjectionTypes "hasIRSA" }} 149 | - name: AWS_ROLE_ARN 150 | value: "{{ .Values.aws.irsa.role_arn }}" 151 | - name: AWS_WEB_IDENTITY_TOKEN_FILE 152 | value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token 153 | {{- end }} 154 | {{- range $key, $value := .Values.env }} 155 | - name: {{ $key }} 156 | value: {{ quote $value }} 157 | {{- end }} 158 | {{- if .Values.additionalContainerEnv }} 159 | {{ toYaml .Values.additionalContainerEnv | indent 12 }} 160 | {{- end }} 161 | {{- range $name, $value := .Values.configMaps }} 162 | {{- if eq $value.as "environment" }} 163 | {{- range $configKey, $keyEnvVarConfig := $value.items }} 164 | - name: {{ required "envVarName is required on configMaps items when using environment" $keyEnvVarConfig.envVarName | quote }} 165 | valueFrom: 166 | configMapKeyRef: 167 | name: {{ $name }} 168 | key: {{ $configKey }} 169 | {{- end }} 170 | {{- end }} 171 | {{- end }} 172 | {{- range $name, $value := .Values.secrets }} 173 | {{- if eq $value.as "environment" }} 174 | {{- range $secretKey, $keyEnvVarConfig := $value.items }} 175 | - name: {{ required "envVarName is required on secrets items when using environment" $keyEnvVarConfig.envVarName | quote }} 176 | valueFrom: 177 | secretKeyRef: 178 | name: {{ $name }} 179 | key: {{ $secretKey }} 180 | {{- end }} 181 | {{- end }} 182 | {{- end }} 183 | 184 | {{- /* START VOLUME MOUNT LOGIC */ -}} 185 | {{- if index $hasInjectionTypes "hasVolume" }} 186 | volumeMounts: 187 | {{- end }} 188 | {{- if index $hasInjectionTypes "hasIRSA" }} 189 | - name: aws-iam-token 190 | mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount 191 | readOnly: true 192 | {{- end }} 193 | {{- range $name, $value := .Values.configMaps }} 194 | {{- if eq $value.as "volume" }} 195 | - name: {{ $name }}-volume 196 | mountPath: {{ quote $value.mountPath }} 197 | {{- end }} 198 | {{- end }} 199 | {{- range $name, $value := .Values.secrets }} 200 | {{- if eq $value.as "volume" }} 201 | - name: {{ $name }}-volume 202 | mountPath: {{ quote $value.mountPath }} 203 | {{- end }} 204 | {{- end }} 205 | {{- range $name, $value := .Values.persistentVolumes }} 206 | - name: {{ $name }} 207 | mountPath: {{ quote $value.mountPath }} 208 | {{- end }} 209 | {{- /* END VOLUME MOUNT LOGIC */ -}} 210 | 211 | 212 | {{- if gt (int .Values.shutdownDelay) 0 }} 213 | lifecycle: 214 | {{ toYaml .Values.lifecycle | indent 12 }} 215 | {{- end }} 216 | 217 | {{- /* end containers */ -}} 218 | {{- end }} 219 | 220 | {{- range $key, $value := .Values.sideCarContainers }} 221 | - name: {{ $key }} 222 | {{ toYaml $value | indent 10 }} 223 | {{- end }} 224 | 225 | {{- /* START IMAGE PULL SECRETS LOGIC */ -}} 226 | {{- if gt (len .Values.imagePullSecrets) 0 }} 227 | imagePullSecrets: 228 | {{- range $secretName := .Values.imagePullSecrets }} 229 | - name: {{ $secretName }} 230 | {{- end }} 231 | {{- end }} 232 | {{- /* END IMAGE PULL SECRETS LOGIC */ -}} 233 | 234 | {{- /* START VOLUME LOGIC */ -}} 235 | {{- if index $hasInjectionTypes "hasVolume" }} 236 | volumes: 237 | {{- end }} 238 | {{- if index $hasInjectionTypes "hasIRSA" }} 239 | - name: aws-iam-token 240 | projected: 241 | defaultMode: 420 242 | sources: 243 | - serviceAccountToken: 244 | audience: sts.amazonaws.com 245 | expirationSeconds: 86400 246 | path: token 247 | {{- end }} 248 | {{- range $name, $value := .Values.configMaps }} 249 | {{- if eq $value.as "volume" }} 250 | - name: {{ $name }}-volume 251 | configMap: 252 | name: {{ $name }} 253 | {{- if $value.items }} 254 | items: 255 | {{- range $configKey, $keyMountConfig := $value.items }} 256 | - key: {{ $configKey }} 257 | path: {{ required "filePath is required for configMap items" $keyMountConfig.filePath | quote }} 258 | {{- if $keyMountConfig.fileMode }} 259 | mode: {{ include ".fileModeOctalToDecimal" $keyMountConfig.fileMode }} 260 | {{- end }} 261 | {{- end }} 262 | {{- end }} 263 | {{- end }} 264 | {{- end }} 265 | {{- range $name, $value := .Values.secrets }} 266 | {{- if eq $value.as "volume" }} 267 | - name: {{ $name }}-volume 268 | secret: 269 | secretName: {{ $name }} 270 | {{- if $value.items }} 271 | items: 272 | {{- range $secretKey, $keyMountConfig := $value.items }} 273 | - key: {{ $secretKey }} 274 | path: {{ required "filePath is required for secrets items" $keyMountConfig.filePath | quote }} 275 | {{- if $keyMountConfig.fileMode }} 276 | mode: {{ include ".fileModeOctalToDecimal" $keyMountConfig.fileMode }} 277 | {{- end }} 278 | {{- end }} 279 | {{- end }} 280 | {{- end }} 281 | {{- end }} 282 | {{- range $name, $value := .Values.persistentVolumes }} 283 | - name: {{ $name }} 284 | persistentVolumeClaim: 285 | claimName: {{ $value.claimName }} 286 | {{- end }} 287 | {{- /* END VOLUME LOGIC */ -}} 288 | 289 | {{- with .Values.nodeSelector }} 290 | nodeSelector: 291 | {{ toYaml . | indent 8 }} 292 | {{- end }} 293 | 294 | {{- with .Values.affinity }} 295 | affinity: 296 | {{ toYaml . | indent 8 }} 297 | {{- end }} 298 | 299 | {{- with .Values.tolerations }} 300 | tolerations: 301 | {{ toYaml . | indent 8 }} 302 | {{- end }} 303 | 304 | ... 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /templates/chart/values.yaml: -------------------------------------------------------------------------------- 1 | # container count 2 | containerCount: 1 3 | 4 | # container 5 | containers: {} 6 | 7 | # container command 8 | containerCommand: null 9 | 10 | # env 11 | env: {} 12 | 13 | # container ports 14 | containerPorts: {} 15 | 16 | # probe 17 | livenessProbe: {} 18 | readinessProbe: {} 19 | 20 | # securityContext is a map that specified the privillege and access control settings for a Pod of Container. Security Context 21 | # can be specified when the application requires additional access control permissions. More details on securityContext and supported 22 | # settings can be found at https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ 23 | # similar to the podSecurityContext {} however, this sets security attributes at the container level rather than at the pod level scope. 24 | 25 | # 26 | # EXAMPLE: 27 | # 1) To run a container in privilleged mode 28 | # securityContext: 29 | # privilleged: true 30 | # 31 | # 2) To run a container as a specific user 32 | # securityContext: 33 | # runAsUser: 2000 34 | securityContext: {} 35 | 36 | # podSecurityContext holds pod-level security access control settings. 37 | # similar to the securityContext {} however, this sets security attributes at the pod level rather than at the container level scope. 38 | # this allows certain attributes to be set that are not possible in the container level. For example 'fsGroup'. 39 | # more details can be found at https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#podsecuritycontext-v1-core 40 | 41 | # EXAMPLE: 42 | # podSecurityContext: 43 | # fsGroup: 2000 44 | podSecurityContext: {} 45 | 46 | 47 | # life cycle 48 | lifecycle: {} 49 | 50 | # shutdownDelay is the number of seconds to delay the shutdown sequence of the Pod by. This is implemented as a sleep 51 | # call in the preStop hook. By default, this chart includes a preStop hook with a shutdown delay for eventual 52 | # consistency reasons. You can read more about why you might want to do this in 53 | # https://blog.gruntwork.io/delaying-shutdown-to-wait-for-pod-deletion-propagation-445f779a8304 54 | # You can disable this behavior by setting this value to 0. 55 | shutdownDelay: 5 56 | 57 | # sideCarContainers specifies any additional containers that should be deployed as side cars to the main application 58 | # container. This will be included in the Deployment container spec so that it will be included in the application Pod. 59 | # This is a nested map, where the first map key is used to name the container, with the nested map being injected as the 60 | # container spec. 61 | # 62 | # The following example specifies a data dog agent container as a side car with some environment variables, binding the 63 | # name `datadog`: 64 | # 65 | # EXAMPLE: 66 | # 67 | # sideCarContainers: 68 | # datadog: 69 | # image: datadog/agent:latest 70 | # env: 71 | # - name: DD_API_KEY 72 | # value: ASDF-1234 73 | # - name: SD_BACKEND 74 | # value: docker 75 | sideCarContainers: {} 76 | 77 | # canary specifies test pod(s) that are deployed alongside your application's stable track pods. 78 | # It is useful for testing a new release candidate in a production environment with minimal disruption and 79 | # for allowing you to find any issues early. 80 | # The expected keys of the canary spec are: 81 | # - enabled (bool) (required) : Whether or not the canary deployment should be created. If false, no canary deployment will be created. 82 | # - containerImage (map) (required) : A map that specifies the application container and tag to be managed by the canary deployment. 83 | # This has the same structure as containerImage. 84 | # - replicaCount (int) : The number of pods that should be managed by the canary deployment. Defaults to 1 if unset. 85 | # 86 | # The following example specifies a simple canary deployment: 87 | # 88 | # EXAMPLE: 89 | # 90 | # canary: 91 | # enabled: true 92 | # replicaCount: 1 93 | # containerImage: 94 | # repository: nginx 95 | # tag: 1.16.0 96 | # pullPolicy: IfNotPresent 97 | canary: {} 98 | 99 | 100 | replicaCount: 1 101 | 102 | 103 | deploymentAnnotations: {} 104 | 105 | 106 | additionalDeploymentLabels: {} 107 | 108 | podAnnotations: {} 109 | 110 | # additionalDeploymentLabels will add the provided map to the labels for the Pods created by the deployment resource. 111 | # this is in addition to the helm template related labels created by the chart 112 | # The keys and values are free form, but subject to the limitations of Kubernetes labelling. 113 | # The match labels for the deployment aren't affected by these additional labels 114 | # NOTE: This variable is injected directly into the deployment spec. 115 | additionalPodLabels: {} 116 | 117 | # minPodsAvailable specifies the minimum number of pods that should be available at any given point in time. This is 118 | # used to configure a PodDisruptionBudget for the included pod. See 119 | # https://blog.gruntwork.io/avoiding-outages-in-your-kubernetes-cluster-using-poddisruptionbudgets-ef6a4baa5085 120 | # for an introduction to PodDisruptionBudgets. 121 | # NOTE: setting this to 0 will skip creating the PodDisruptionBudget resource. 122 | minPodsAvailable: 0 123 | 124 | 125 | # service: 126 | # enabled: true 127 | # ports: 128 | # app: 129 | # port: 80 130 | # targetPort: http 131 | # protocol: TCP 132 | 133 | service: 134 | enabled: true 135 | type: ClusterIP 136 | ports: {} 137 | 138 | # servicemonitor is a map that can be used to configure a Service monitor for the operator. By default, service monitor is off. 139 | # The expected keys are: 140 | # - enabled (bool) (required) : Whether or not the Service Monitor resource should be created. If false, no 141 | # Service Monitor resource will be created. 142 | # - namespace (string) (required) : Namespace of Endpoints object. 143 | # - endpoints (list[map]) (required) : An object used to discovers targets from listed endpoints of a service. 144 | # For each endpoint address one target is discovered per port. 145 | # If the endpoint is backed by a pod, all additional container ports of the pod, 146 | # not bound to an endpoint port, are discovered as targets as well. 147 | # 148 | # The following example specifies a ServiceMonitor rule that describes the set of targets to be monitored by Prometheus. 149 | # EXAMPLE: 150 | # 151 | # serviceMonitor: 152 | # enabled: true 153 | # namespace: monitoring 154 | # endpoints: 155 | # default: 156 | # interval: 10s 157 | # scrapeTimeout: 10s 158 | # honorLabels: true 159 | # path: /metrics 160 | # port: http 161 | # scheme: http 162 | serviceMonitor: 163 | enabled: false 164 | namespace: monitoring 165 | labels: {} 166 | endpoints: {} 167 | 168 | # ingress is a map that can be used to configure an Ingress resource for this service. By default, turn off ingress. 169 | # NOTE: if you enable Ingress, then Service must also be enabled. 170 | # The expected keys are: 171 | # - enabled (bool) (required) : Whether or not the Ingress resource should be created. If false, no 172 | # Ingress resource will be created. 173 | # - annotations (map) : Annotations that should be added to the Service resource. This is injected 174 | # directly in to the resource yaml. 175 | # - tls (list[map]) : Sets up TLS termination on the ingress rule. Each item is a separate TLS 176 | # rule that maps to one or more hosts specified in this ingress rule. This 177 | # is injected directly in to the resource yaml. 178 | # - hosts (list[string]) : Sets up the host routes for the ingress resource. There will be a routing 179 | # rule for each host defined in this list. If empty, will match all hosts. 180 | # - path (string) (required) : The url path to match to route to the Service. 181 | # - servicePort (int|string) (required) : The port (as a number) or the name of the port on the Service to route to. 182 | # - additionalPaths (list[map]) : Additional paths that should be added to the ingress which will be lower 183 | # priority than the application service path. Each item corresponds to 184 | # another path, and should define `path`, `serviceName`, and `servicePort`. 185 | # - additionalPathsHigherPriority (list[map]) 186 | # : Additional paths that should be added to the ingress which will be higher 187 | # priority than the application service path. Each item corresponds to 188 | # another path, and should define `path`, `serviceName`, and `servicePort`. 189 | # 190 | # The following example specifies an Ingress rule that routes chart-example.local/app to the Service port `app` with 191 | # TLS configured using the certificate key pair in the Secret `chart-example-tls`: 192 | # 193 | # EXAMPLE: 194 | # 195 | # ingress: 196 | # enabled: true 197 | # annotations: 198 | # kubernetes.io/ingress.class: nginx 199 | # kubernetes.io/tls-acme: "true" 200 | # path: /app 201 | # servicePort: app 202 | # hosts: 203 | # - chart-example.local 204 | # tls: 205 | # - secretName: chart-example-tls 206 | # hosts: 207 | # - chart-example.local 208 | ingress: 209 | enabled: false 210 | 211 | # additionalContainerEnv is a list of additional environment variables 212 | # definitions that will be inserted into the Container's environment YAML. 213 | # 214 | # Example: 215 | # additionalContainerEnv: 216 | # - name: DD_AGENT_HOST 217 | # valueFrom: 218 | # fieldRef: 219 | # fieldPath: status.hostIP 220 | # - name: DD_ENTITY_ID 221 | # valueFrom: 222 | # fieldRef: 223 | # fieldPath: metadata.uid 224 | additionalContainerEnv: {} 225 | 226 | # configMaps is a map that specifies the ConfigMap resources that should be exposed to the main application container. Each 227 | # entry in the map represents a ConfigMap resource. The key refers to the name of the ConfigMap that should be exposed, 228 | # with the value specifying how to expose the ConfigMap. The value is also a map and has the following attributes: 229 | # - as (enum[volume,environment,none]) (required) 230 | # : ConfigMaps can be exposed to Pods as a volume mount, or as environment variables. This attribute is a string 231 | # enum that is expected to be either "volume" or "environment", specifying that the ConfigMap should be exposed as a 232 | # mounted volume or via environment variables respectively. This attribute can also be set to "none", which 233 | # disables the `ConfigMap` on the container. 234 | # - mountPath (string) 235 | # : For ConfigMaps mounted as a volume, specify the mount path on the container file system where the config values 236 | # will be available. Required when the ConfigMap is exposed as a volume. Ignored when the ConfigMap is exposed as 237 | # environment variables. 238 | # - items (map[ConfigMapItem]) 239 | # : Specify how each ConfigMap value should be made available. The keys are the key of the ConfigMap that you wish 240 | # to configure, while the value is another map that controls how that key should be exposed. Required when the 241 | # ConfigMap is exposed as environment variables. When the ConfigMap is exposed as a volume, this field is optional. 242 | # If empty for volume ConfigMaps, all ConfigMpas will be mounted with the key as the file name relative to the 243 | # mountPath. See below for expected attributes. 244 | # The expected attributes of the `ConfigMapItem` map (the submap within `items`) are: 245 | # - filePath (string) : The file path relative to the ConfigMap mountPath where the value of the ConfigMap keyed at 246 | # the given key of the item should be mounted to in the container. Ignored when the ConfigMap 247 | # is exposed as environment variables. 248 | # - fileMode (string) : The permissions mode of the file when mounted in the container. Ignored when the ConfigMap is 249 | # exposed as environment variables. Expected to be the octal (e.g 777, 644). Defaults to 644. 250 | # - envVarName (string) : The name of the environment variable where the value of the ConfigMap keyed at the given key 251 | # of the item should be stored. Ignored when the ConfigMap is exposed as a volume mount. 252 | # 253 | # NOTE: These config values are only automatically injected to the main application container. To add them to the side 254 | # car containers, use the official Kubernetes Pod syntax: 255 | # https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ 256 | # 257 | # The following example exposes the ConfigMap `myconfig` as a volume mounted to `/etc/myconfig`, while it exposes the 258 | # ConfigMap `myotherconfig` as an environment variable. 259 | # 260 | # EXAMPLE: 261 | # 262 | # configMaps: 263 | # myconfig: 264 | # as: volume 265 | # mountPath: /etc/myconfig 266 | # myotherconfig: 267 | # as: environment 268 | # items: 269 | # foo: 270 | # envVarName: CONFIG_FOO 271 | configMaps: {} 272 | 273 | # resources 274 | resources: {} 275 | 276 | # persistentVolumes is a map that specifies PeristantVolumes that should be mounted on the pod. Each entry represents a 277 | # persistent volume which should already exist within your cluster. They Key is the name of the persistent volume. 278 | # The value is also a map and has the following attributes: 279 | # - mountPath (string) (required) 280 | # : The path within the container upon which this volume should be mounted. 281 | # - claimName (string) (required) 282 | # : The name of the Persistent Volume Claim on which this Persistent Volume in bound. 283 | # 284 | # EXAMPLE: 285 | # persistentVolumes: 286 | # example-pv: 287 | # mountPath: /mnt/myVol 288 | # claimName: example-pv-claim 289 | # example-pv-2: 290 | # mountPath: /mnt/myOtherVol 291 | # claimName: example-pv2-claim 292 | # 293 | # 294 | persistentVolumes: {} 295 | 296 | # secrets is a map that specifies the Secret resources that should be exposed to the main application container. Each entry in 297 | # the map represents a Secret resource. The key refers to the name of the Secret that should be exposed, with the value 298 | # specifying how to expose the Secret. The value is also a map and has the following attributes: 299 | # - as (enum[volume,environment,none]) (required) 300 | # : Secrets can be exposed to Pods as a volume mount, or as environment variables. This attribute is a string enum 301 | # that is expected to be either "volume" or "environment", specifying that the Secret should be exposed as a mounted 302 | # volume or via environment variables respectively. This attribute can also be set to "none", which disables the 303 | # `Secret` on the container. 304 | # - mountPath (string) 305 | # : For Secrets mounted as a volume, specify the mount path on the container file system where the secrets will be 306 | # available. Required when the Secret is exposed as a volume. Ignored when the Secret is exposed as environment 307 | # variables. 308 | # - items (map[SecretItem]) 309 | # : Specify how each Secret value should be made available. The keys are the key of the Secret that you wish to 310 | # configure, while the value is another map that controls how that key should be exposed. Required when the Secret 311 | # is exposed as environment variables. When the Secret is exposed as a volume, this field is optional. If empty for 312 | # volume Secrets, all Secrets will be mounted with the key as the file name relative to the mountPath. See below 313 | # for expected attributes. 314 | # The expected attributes of the `SecretItem` map (the submap within `items`) are: 315 | # - filePath (string) : The file path relative to the Secret mountPath where the value of the Secret keyed at the 316 | # given key of the item should be mounted to in the container. Ignored when the Secret is 317 | # exposed as environment variables. 318 | # - fileMode (string) : The permissions mode of the file when mounted in the container. Ignored when the Secret is 319 | # exposed as environment variables. Expected to be the octal (e.g 777, 644). Defaults to 644. 320 | # - envVarName (string) : The name of the environment variable where the value of the Secret keyed at the given key of 321 | # the item should be stored. Ignored when the Secret is exposed as a volume mount. 322 | # 323 | # NOTE: These secrets are only automatically injected to the main application container. To add them to the side car 324 | # containers, use the official Kubernetes Pod syntax: 325 | # https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets 326 | # 327 | # The following example exposes the Secret `mysecret` as a volume mounted to `/etc/mysecret`, while it exposes the 328 | # Secret `myothersecret` as an environment variable. 329 | # 330 | # EXAMPLE: 331 | # 332 | # secrets: 333 | # mysecret: 334 | # as: volume 335 | # mountPath: /etc/mysecret 336 | # myothersecret: 337 | # as: environment 338 | # items: 339 | # foo: 340 | # envVarName: SECRET_FOO 341 | secrets: {} 342 | 343 | 344 | # containerResources specifies the amount of resources the application container will require. Only specify if you have 345 | # specific resource needs. 346 | # NOTE: This variable is injected directly into the pod spec. See the official documentation for what this might look 347 | # like: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ 348 | containerResources: {} 349 | 350 | # nodeSelector and affinity specify restrictions on what node this pod should be scheduled on. 351 | # NOTE: These variables are injected directly into the pod spec. See the official documentation for what this might look 352 | # like: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ 353 | nodeSelector: {} 354 | affinity: {} 355 | 356 | # tolerations can be used to allow the pod to be scheduled on nodes with a specific taint. 357 | # NOTE: This variable is injected directly into the pod spec. See the official documentation for what this might look 358 | # like: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 359 | tolerations: [] 360 | 361 | applicationName: "" 362 | # image 363 | image: 364 | repository: "" 365 | pullPolicy: "" 366 | tag: "" 367 | 368 | # image pull secret 369 | imagePullSecrets: [] 370 | 371 | # serviceAccount is a map that configures the ServiceAccount information for the Pod. 372 | # The expected keys of serviceAccount are: 373 | # - name (string) : The name of the ServiceAccount in the Namespace where the Pod is deployed 374 | # that should be used. By default this is the default ServiceAccount of the 375 | # Namespace. 376 | # - automountServiceAccountToken (bool) : Whether or not to automatically mount the ServiceAccount token as a volume 377 | # into the Pod. Note that this can be used to override the equivalent config 378 | # on the ServiceAccount. 379 | # - create (bool) : Whether or not to create a service account with the desired name 380 | # - annotations (map) : Annotations will add the provided map to the annotations for the service 381 | # account created 382 | # - labels (map) : Labels will add the provided map to the annotations for the service 383 | # account created 384 | # 385 | # The default config uses empty string to indicate that the default service account should be used and one shouldn't 386 | # be created 387 | serviceAccount: 388 | name: "" 389 | create: false 390 | annotations: {} 391 | labels: {} 392 | 393 | # horizontalPodAutoscaler is a map that configures the Horizontal Pod Autoscaler information for this pod 394 | # The expected keys of hpa are: 395 | # - enabled (bool) : Whether or not Horizontal Pod Autoscaler should be created, if false the 396 | # Horizontal Pod Autoscaler will not be created 397 | # - minReplicas (int) : The minimum amount of replicas allowed 398 | # - maxReplicas (int) : The maximum amount of replicas allowed 399 | # - avgCpuUtilization (int) : The target average CPU utilization to be used with the metrics 400 | # - avgMemoryUtilization (int) : The target average Memory utilization to be used with the metrics 401 | # 402 | # The default config will not create the Horizontal Pod Autoscaler by setting enabled = false, the default values are 403 | # set so if enabled is true the horizontalPodAutoscaler has valid values. 404 | horizontalPodAutoscaler: 405 | enabled: false 406 | minReplicas: 1 407 | maxReplicas: 10 408 | 409 | #---------------------------------------------------------------------------------------------------------------------- 410 | # AWS SPECIFIC VALUES 411 | # These input values relate to AWS specific features, such as those relating to EKS and the AWS ALB Ingress Controller. 412 | #---------------------------------------------------------------------------------------------------------------------- 413 | aws: 414 | # irsa can be used to configure the projected tokens used in the IAM Roles for Service Accounts feature. This is 415 | # useful if you are manually annotating the projected tokens into your Pods, instead of relying on the mutating 416 | # admission hook. 417 | # 418 | # irsa is a map and expects the following keys: 419 | # - role_arn (string) (required) : The AWS ARN that the Service Account associated with the Pod should assume. 420 | # Note that the projected token will not be mounted and the environment 421 | # variables will not be set if this is an empty string (the default). 422 | # 423 | # Note that you can not use any role with the IRSA feature. It must have the proper assume role IAM policy to allow 424 | # the Service Account of the Pod to assume that role. See 425 | # https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html for more 426 | # information. 427 | # 428 | # EXAMPLE: 429 | # 430 | # aws: 431 | # irsa: 432 | # role_arn: "arn:aws:iam::123456789012:role/role-for-pod" 433 | # 434 | irsa: 435 | role_arn: "" 436 | 437 | 438 | #---------------------------------------------------------------------------------------------------------------------- 439 | # GOOGLE SPECIFIC VALUES 440 | # google specifies Google (GKE) specific configuration to be set via arguments/env. variables 441 | #---------------------------------------------------------------------------------------------------------------------- 442 | google: 443 | # managedCertificate can be used to provision a Google Managed Certificate. Associate the ManagedCertificate object 444 | # to an Ingress by adding an annotation 'networking.gke.io/managed-certificates' to the Ingress. 445 | # 446 | # The expected keys are: 447 | # - enabled (bool) (required) : Whether or not the ManagedCertificate resource should be created. 448 | # - domainName (string) : Specifies the domain that the SSL certificate will be created for 449 | # - name (string) : Specifies the name of the SSL certificate that you reference in Ingress with 450 | # networking.gke.io/managed-certificates: name 451 | # 452 | # The following example specifies a ManagedCertificate with a domain name 'api.acme.com' and name 'acme-cert': 453 | # 454 | # EXAMPLE: 455 | # 456 | # google: 457 | # managedCertificate: 458 | # enabled: true 459 | # name: acme-cert 460 | # domainName: api.acme.com 461 | # 462 | # NOTE: if you enable managedCertificate, then Ingress must also be enabled. 463 | # Use a Google Managed Certificate. By default, turn off. 464 | managedCertificate: 465 | enabled: false 466 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= 10 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 11 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 12 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 13 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 14 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 15 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 16 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 17 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 18 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 19 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 20 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 21 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 22 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 23 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 24 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 25 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 26 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 27 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 28 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 29 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 30 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 31 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 32 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 33 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 34 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 35 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 36 | github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= 37 | github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= 38 | github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= 39 | github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= 40 | github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= 41 | github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= 42 | github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= 43 | github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= 44 | github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= 45 | github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= 46 | github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= 47 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 48 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 49 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 50 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 51 | github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 52 | github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 53 | github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 h1:ZBbLwSJqkHBuFDA6DUhhse0IGJ7T5bemHyNILUjvOq4= 54 | github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2/go.mod h1:VSw57q4QFiWDbRnjdX8Cb3Ow0SFncRw+bA/ofY6Q83w= 55 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 56 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 57 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 58 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 59 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 60 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 61 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 62 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 63 | github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 64 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 65 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 66 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 67 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 68 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 69 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 70 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 71 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 72 | github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 73 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 74 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 75 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 76 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 77 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 78 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 79 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 80 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 81 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 82 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= 83 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= 84 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 85 | github.com/drone/envsubst v1.0.2 h1:dpYLMAspQHW0a8dZpLRKe9jCNvIGZPhCPrycZzIHdqo= 86 | github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0= 87 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 88 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 89 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 90 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 91 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 92 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 93 | github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 94 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 95 | github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= 96 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= 97 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 98 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 99 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= 100 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 101 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 102 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 103 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 104 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 105 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 106 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 107 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 108 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 109 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 110 | github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= 111 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 112 | github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= 113 | github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= 114 | github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= 115 | github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= 116 | github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= 117 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 118 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 119 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 120 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 121 | github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= 122 | github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 123 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 124 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 125 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 126 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 127 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 128 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 129 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 130 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 131 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 132 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 133 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 134 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 135 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 136 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 137 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 138 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 139 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 140 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 141 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 142 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 143 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 144 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 145 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 146 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 147 | github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= 148 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 149 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 150 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 151 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 152 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 153 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 154 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 155 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 156 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 157 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 158 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 159 | github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= 160 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 161 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 162 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 163 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 164 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 165 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 166 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 167 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 168 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 169 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 170 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 171 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 172 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 173 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 174 | github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 175 | github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM= 176 | github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= 177 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 178 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 179 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 180 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 181 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 182 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 183 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 184 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 185 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 186 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 187 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 188 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 189 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 190 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 191 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 192 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 193 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 194 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 195 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 196 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 197 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 198 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 199 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 200 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 201 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 202 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 203 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 204 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 205 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 206 | github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= 207 | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 208 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 209 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 210 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 211 | github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= 212 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 213 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 214 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 215 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 216 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 217 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 218 | github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 219 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 220 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 221 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 222 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 223 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 224 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 225 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 226 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 227 | github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 228 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 229 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 230 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 231 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 232 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 233 | github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= 234 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= 235 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 236 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 237 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 238 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 239 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 240 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 241 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 242 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 243 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 244 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 245 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 246 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 247 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 248 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 249 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 250 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 251 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 252 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 253 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= 254 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 255 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 256 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 257 | github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 258 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 259 | github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 260 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 261 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 262 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 263 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 264 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 265 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 266 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 267 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 268 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 269 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 270 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 271 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 272 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 273 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 274 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 275 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 276 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 277 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 278 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 279 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 280 | github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= 281 | github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= 282 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 283 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 284 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 285 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 286 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 287 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 288 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 289 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 290 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 291 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 292 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 293 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 294 | github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= 295 | github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= 296 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 297 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 298 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 299 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 300 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 301 | github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 302 | github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= 303 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 304 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 305 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 306 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 307 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 308 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 309 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 310 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 311 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 312 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 313 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 314 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 315 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 316 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 317 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 318 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 319 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 320 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 321 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 322 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 323 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 324 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 325 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 326 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 327 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 328 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 329 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 330 | golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 331 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 332 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= 333 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 334 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 335 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 336 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 337 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 338 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 339 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 340 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 341 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 342 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 343 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 344 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 345 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 346 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 347 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 348 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 349 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 350 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 351 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 352 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 353 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 354 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 355 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 356 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 357 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 358 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 359 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 360 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 361 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 362 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 363 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 364 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 365 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 366 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 367 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 368 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 369 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 370 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 371 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 372 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 373 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 374 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 375 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 376 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 377 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 378 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 379 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 380 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 381 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 382 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 383 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 384 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 385 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 386 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 387 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 388 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 389 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 390 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 391 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 392 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 393 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 394 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 395 | golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= 396 | golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 397 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 398 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 399 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 400 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 401 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 402 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= 403 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 404 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 405 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 406 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 407 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 408 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 409 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 410 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 411 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 412 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 413 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 414 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 415 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 416 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 417 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 418 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 419 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 420 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 421 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 422 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 423 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 424 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 425 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 426 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 427 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 428 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 429 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 430 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 431 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 432 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 433 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 434 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 435 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 436 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 437 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 438 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 439 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 440 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 441 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 442 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 443 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 444 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 445 | golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 446 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw= 447 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 448 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 449 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 450 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 451 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 452 | golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= 453 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 454 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 455 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 456 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 457 | golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= 458 | golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 459 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 460 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 461 | golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 462 | golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 463 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 464 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 465 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 466 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 467 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 468 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 469 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 470 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 471 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 472 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 473 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 474 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 475 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 476 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 477 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 478 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 479 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 480 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 481 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 482 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 483 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 484 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 485 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 486 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 487 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 488 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 489 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 490 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 491 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 492 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 493 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 494 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 495 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 496 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 497 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 498 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 499 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 500 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 501 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 502 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 503 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 504 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 505 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 506 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 507 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 508 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 509 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 510 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 511 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 512 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 513 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 514 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 515 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 516 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 517 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 518 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 519 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 520 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 521 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 522 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 523 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 524 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 525 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 526 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 527 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 528 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 529 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 530 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 531 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 532 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 533 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 534 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 535 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 536 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 537 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 538 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 539 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 540 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 541 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 542 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 543 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 544 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 545 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 546 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 547 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 548 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 549 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 550 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 551 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 552 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 553 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 554 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 555 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 556 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 557 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 558 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 559 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 560 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 561 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 562 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 563 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 564 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 565 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 566 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 567 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 568 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 569 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 570 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 571 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 572 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 573 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 574 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 575 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 576 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 577 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 578 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 579 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 580 | google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= 581 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 582 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 583 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 584 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 585 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 586 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 587 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 588 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 589 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 590 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 591 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 592 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 593 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 594 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 595 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 596 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 597 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 598 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 599 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 600 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= 601 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 602 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 603 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 604 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 605 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 606 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 607 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 608 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 609 | k8s.io/api v0.19.0 h1:XyrFIJqTYZJ2DU7FBE/bSPz7b1HvbVBuBf07oeo6eTc= 610 | k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= 611 | k8s.io/api v0.19.2 h1:q+/krnHWKsL7OBZg/rxnycsl9569Pud76UJ77MvKXms= 612 | k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= 613 | k8s.io/apimachinery v0.19.0 h1:gjKnAda/HZp5k4xQYjL0K/Yb66IvNqjthCb03QlKpaQ= 614 | k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= 615 | k8s.io/apimachinery v0.19.2 h1:5Gy9vQpAGTKHPVOh5c4plE274X8D/6cuEiTO2zve7tc= 616 | k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= 617 | k8s.io/client-go v0.19.0 h1:1+0E0zfWFIWeyRhQYWzimJOyAk2UT7TiARaLNwJCf7k= 618 | k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU= 619 | k8s.io/client-go v1.5.1 h1:XaX/lo2/u3/pmFau8HN+sB5C/b4dc4Dmm2eXjBH4p1E= 620 | k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= 621 | k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= 622 | k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= 623 | k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= 624 | k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= 625 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 626 | k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= 627 | k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= 628 | k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= 629 | k8s.io/kubernetes v1.19.3 h1:V6ohBHSxTkrPRyfVp8tbdEsgi9nfVN49xlUVkQseass= 630 | k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 631 | k8s.io/utils v0.0.0-20200912215256-4140de9c8800 h1:9ZNvfPvVIEsp/T1ez4GQuzCcCTEQWhovSofhqR73A6g= 632 | k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 633 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 634 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 635 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 636 | sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= 637 | sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 638 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 639 | sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= 640 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= 641 | --------------------------------------------------------------------------------