├── .circleci └── config.yml ├── .gitignore ├── .goreleaser.yml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── OWNERS ├── README.md ├── cmd ├── cleanup.go ├── convert.go ├── environment.go ├── move_config.go └── root.go ├── code-of-conduct.md ├── completion.yaml ├── go.mod ├── go.sum ├── helm-2to3.png ├── main.go ├── pkg ├── common │ └── common.go ├── utils │ └── utils.go ├── v2 │ ├── release.go │ └── utils.go └── v3 │ ├── connect.go │ ├── release.go │ └── utils.go ├── plugin.yaml └── scripts ├── install_plugin.sh └── tag.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | workflows: 3 | version: 2 4 | untagged-build: 5 | jobs: 6 | - lint 7 | - untagged-build 8 | tagged-build: 9 | jobs: 10 | - tagged-build: 11 | filters: 12 | tags: 13 | only: /^v.*/ 14 | branches: 15 | ignore: /.*/ 16 | jobs: 17 | lint: 18 | docker: 19 | - image: koalaman/shellcheck-alpine 20 | steps: 21 | - checkout 22 | - run: 23 | name: lint 24 | command: | 25 | shellcheck -x scripts/tag.sh 26 | shellcheck -x scripts/install_plugin.sh 27 | untagged-build: 28 | docker: 29 | - image: cimg/go:1.22 30 | auth: 31 | username: $DOCKER_USER 32 | password: $DOCKER_PASS 33 | steps: 34 | - checkout 35 | - run: 36 | command: make build 37 | no_output_timeout: 20m 38 | tagged-build: 39 | docker: 40 | - image: cimg/go:1.22 41 | auth: 42 | username: $DOCKER_USER 43 | password: $DOCKER_PASS 44 | steps: 45 | - checkout 46 | - run: 47 | command: curl -sfL https://goreleaser.com/static/run | bash 48 | no_output_timeout: 40m 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2to3 2 | bin/ 3 | tmp/ 4 | releases/ 5 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | builds: 2 | - main: main.go 3 | binary: 2to3 4 | env: 5 | - CGO_ENABLED=0 6 | goos: 7 | - darwin 8 | - linux 9 | - windows 10 | goarch: 11 | - amd64 12 | - arm64 13 | archives: 14 | - id: archive 15 | format: tar.gz 16 | files: 17 | - README.md 18 | - LICENSE 19 | - plugin.yaml 20 | - completion.yaml 21 | - scripts/install_plugin.sh 22 | checksum: 23 | name_template: 'checksums.txt' 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | The Helm 2to3 plugin project accepts contributions via GitHub pull requests. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | HELM_PLUGIN_NAME := 2to3 2 | LDFLAGS := "-X main.version=${VERSION}" 3 | MOD_PROXY_URL ?= https://goproxy.io 4 | 5 | .PHONY: build 6 | build: 7 | export CGO_ENABLED=0 && \ 8 | go build -o bin/${HELM_PLUGIN_NAME} -ldflags $(LDFLAGS) ./main.go 9 | 10 | .PHONY: bootstrap 11 | bootstrap: 12 | export GO111MODULE=on && \ 13 | export GOPROXY=$(MOD_PROXY_URL) && \ 14 | go mod download 15 | 16 | .PHONY: tag 17 | tag: 18 | @scripts/tag.sh 19 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | emeritus: 2 | - adamreese 3 | - bacongobbler 4 | - fibonacci1729 5 | - hickeyma 6 | - jdolitsky 7 | - mattfarina 8 | - michelleN 9 | - prydonius 10 | - rimusz 11 | - SlickNik 12 | - technosophos 13 | - thomastaylor312 14 | - viglesiasce 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | |![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Warning.svg/156px-Warning.svg.png) | This project is no longer supported. 2 | |---|---| 3 | 4 | # Helm 2to3 Plugin 5 | 6 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/helm/helm-2to3)](https://goreportcard.com/report/github.com/helm/helm-2to3) 8 | [![CircleCI](https://circleci.com/gh/helm/helm-2to3/tree/main.svg?style=svg)](https://circleci.com/gh/helm/helm-2to3/tree/main) 9 | [![Release](https://img.shields.io/github/release/helm/helm-2to3.svg?style=flat-square)](https://github.com/helm/helm-2to3/releases/latest) 10 | 11 | ![diagram](./helm-2to3.png) 12 | 13 | **Helm v3 plugin which migrates and cleans up Helm v2 configuration and releases in-place to Helm v3** 14 | 15 | ## ⚠️ Deprecation and Archive Notice 16 | 17 | The `2to3` plugin is deprecated and no longer supported. Helm 3 was released in November 2019 and Helm 2 became unsupported in November 2020. It would be expected that all users should be migrated to Helm 3 by this time. Therefore, the plugin has now been deprecated by the maintainers. 18 | 19 | ## Overview 20 | 21 | One of the most important aspects of upgrading to a new major release of Helm is the 22 | migration of data. This is especially true of Helm v2 to v3 considering the architectural 23 | changes between the releases. The `2to3` plugin helps with this migration by supporting: 24 | 25 | - Migration of [Helm v2 configuration](#migrate-helm-v2-configuration). 26 | - Migration of [Helm v2 releases](#migrate-helm-v2-releases). 27 | - [Clean up](#clean-up-helm-v2-data) Helm v2 configuration, release data and Tiller deployment. 28 | 29 | ## Readme before migration 30 | 31 | ***WARNING:*** All data migrations carry a level of risk. Helm v2 migration is no different. 32 | You should be aware of any risks specific to your environment and prepare a data migration 33 | strategy for your needs. 34 | 35 | Here are some suggestions to mitigate against potential risks during migration: 36 | 37 | - Perform a data backup of the following: 38 | - Helm v2 home folder. 39 | - Release data from the cluster. Refer to [How Helm Uses ConfigMaps to Store Data](http://technosophos.com/2017/03/23/how-helm-uses-configmaps-to-store-data.html) 40 | for details on how Helm v2 store release data in the cluster. This should apply 41 | similarly if Helm v2 is configured for secrets. 42 | - Avoid performing operations with Helm v3 until data migration is complete and you are 43 | satisfied that it is working as expected. Otherwise, Helm v3 data might be overwritten. 44 | The operations to avoid are chart install, adding repositories, plugin install etc. 45 | - The recommended data migration path is as follows: 46 | 1. Backup v2 data, as suggested above. 47 | 2. Migrate [Helm v2 configuration](#migrate-helm-v2-configuration). 48 | 3. Migrate [Helm v2 releases](#migrate-helm-v2-releases). 49 | 4. When happy that Helm v3 is managing Helm v2 data as expected, then [clean up](#clean-up-helm-v2-data) Helm v2 data. 50 | *Note:*: Only use the plugin to do clean up. Using `helm`, `kubectl` or other tools could lead to data loss and an indeterminate 51 | state for the release(s). 52 | 53 | **Note:** 54 | A Helm v2 client: 55 | 56 | - can manage 1 to many Kubernetes clusters. 57 | - can connect to 1 to many Tiller instances for a cluster. 58 | 59 | This means that you have to cognisant of this when migrating as releases are deployed into clusters by Tiller and 60 | its namespace. You have to therefore be aware of migrating for each cluster and each Tiller instance that is managed 61 | by the Helm v2 client instance. [Clean up](#clean-up-helm-v2-data) should only be run once all migration for a Helm v2 client is complete. 62 | 63 | ## Prerequisite 64 | 65 | - Helm v2 client installed on a system which manages releases on one to many clusters 66 | - Helm v3 client with `2to3` plugin installed on the same system 67 | - Access to the cluster(s) that Helm v2 client is managing and which Helm v3 will manage after migration. This access is similar to `kubectl` access using [kubeconfig files](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/). 68 | The `--kubeconfig` and `--kube-context` flags can be used with the `convert` and `cleanup` commands to set the kubeconfig path and context to override the environment configuration. 69 | - Access to the `tiller` namespace for required RBAC roles. If `Tillerless` setup, then a service account with the proper cluster wide RBAC roles will need to be used. If not used, `forbidden` errors will be thrown when trying to access restricted resources. 70 | - The plugin requires these RBAC resource permissions at the least. Additional resources might be needed depending on your environment setup 71 | ```yaml 72 | apiVersion: rbac.authorization.k8s.io/v1 73 | kind: ClusterRole 74 | metadata: 75 | name: 76 | rules: 77 | - apiGroups: 78 | - "" 79 | resources: 80 | - pods 81 | verbs: 82 | - list 83 | - get 84 | - apiGroups: 85 | - "" 86 | resources: 87 | - configmaps 88 | verbs: 89 | - list 90 | - get 91 | - delete 92 | ``` 93 | 94 | ## Recommended Prior to Migration 95 | 96 | This is a list of recommendations prior to migration: 97 | 98 | - [Latest](https://github.com/helm/helm/releases/tag/v2.17.0) Helm v2 version. 99 | - [Latest](https://github.com/helm/helm/releases) Helm v3 version. 100 | - Update Helm v2 releases to supported Kubernetes APIs prior to migrating. Check out [Deprecated Kubernetes APIs](https://v2.helm.sh/docs/using_helm/#deprecated-kubernetes-apis) docs and Helm [mapkubeapis plugin](https://github.com/hickeyma/helm-mapkubeapis) for more details. 101 | - Upgrade Kubernetes clusters to [supported versions](https://kubernetes.io/docs/setup/release/version-skew-policy/). 102 | 103 | ## Install 104 | 105 | Based on the version in `plugin.yaml`, release binary will be downloaded from GitHub: 106 | 107 | ```console 108 | $ helm plugin install https://github.com/helm/helm-2to3.git 109 | Downloading and installing helm-2to3 v0.1.3 ... 110 | https://github.com/helm/helm-2to3/releases/download/v0.1.3/helm-2to3_0.1.3_darwin_amd64.tar.gz 111 | Installed plugin: 2to3 112 | ``` 113 | 114 | ### For Windows (using WSL) 115 | 116 | Helm's plugin install hook system relies on `/bin/sh`, regardless of the operating system present. Windows users can work around this by using Helm under [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 117 | 118 | ```console 119 | $ wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz 120 | $ tar xzf helm-v3.0.0-linux-amd64.tar.gz 121 | $ ./linux-amd64/helm plugin install https://github.com/helm/helm-2to3 122 | ``` 123 | 124 | ## Usage 125 | 126 | ### Migrate Helm v2 configuration 127 | 128 | Migrate Helm v2 configuration in-place to Helm v3: 129 | 130 | ```console 131 | $ helm 2to3 move config [flags] 132 | 133 | Flags: 134 | 135 | --dry-run simulate a command 136 | --skip-confirmation if set, skips confirmation message before performing move 137 | -h, --help help for move 138 | ``` 139 | 140 | It will migrate: 141 | 142 | - Chart starters 143 | - Repositories 144 | - Plugins 145 | 146 | **Note:** 147 | 148 | - The `move config` command will create the Helm v3 config and data folders if they don't exist, and will override the `repositories.yaml` file if it does exist. 149 | - For migration it uses default Helm v2 home and v3 config and data folders. To override those folders you need to set environment variables 150 | `HELM_V2_HOME`, `HELM_V3_CONFIG` and `HELM_V3_DATA`: 151 | 152 | ```console 153 | $ export HELM_V2_HOME=$PWD/.helm2 154 | $ export HELM_V3_CONFIG=$PWD/.helm3 155 | $ export HELM_V3_DATA=$PWD/.helm3 156 | $ helm 2to3 move config 157 | ``` 158 | 159 | #### Readme after configuration migration 160 | 161 | - After running the command, check that all Helm v2 plugins work fine with the Helm v3. If any issue with a plugin, remove it (` plugin remove`) and 162 | re-add (` plugin install`) it as required. 163 | - The repository file `repositories.yaml` is copied to Helm v3 which contains references to repositories added in Helm v2. Local respoitories are not copied to Helm v3. 164 | You should remove all local repositories from Helm v3 using ` repo remove` and re-add where necessary using ` repo add`. This is a necessary refresh to align references 165 | for Helm v3. 166 | - When you are happy with your repository list, update the Helm v3 repo ` repo update`. This cleans up any Helm v2 cache references from Helm v3. 167 | 168 | ### Migrate Helm v2 releases 169 | 170 | Migrate Helm v2 releases in-place to Helm v3 171 | 172 | ```console 173 | $ helm 2to3 convert [flags] RELEASE 174 | 175 | Flags: 176 | 177 | --delete-v2-releases v2 release versions are deleted after migration. By default, the v2 release versions are retained 178 | --dry-run simulate a command 179 | -h, --help help for convert 180 | --ignore-already-migrated Ignore any already migrated release versions and continue migrating 181 | --kube-context string name of the kubeconfig context to use 182 | --kubeconfig string path to the kubeconfig file 183 | -l, --label string label to select Tiller resources by (default "OWNER=TILLER") 184 | -s, --release-storage string v2 release storage type/object. It can be 'secrets' or 'configmaps'. This is only used with the 'tiller-out-cluster' flag (default "secrets") 185 | --release-versions-max int limit the maximum number of versions converted per release. Use 0 for no limit (default 10) 186 | -t, --tiller-ns string namespace of Tiller (default "kube-system") 187 | --tiller-out-cluster when Tiller is not running in the cluster e.g. Tillerless 188 | ``` 189 | 190 | **Note:** There is a limit set on the number of versions/revisions of a release that are converted. It is defaulted to 10 but can be configured with the `--release-versions-max` flag. 191 | When the limit set is less that the actual number of versions then only the latest release versions up to the limit will be converted. Older release versions with not be converted. 192 | If `--delete-v2-releases` is set, these older versions will remain in Helm v2 storage but will no longer be visible to Helm v2 commands like `helm list`. [Clean up](#clean-up-helm-v2-data) 193 | will remove them from storage. 194 | 195 | ### Clean up Helm v2 data 196 | 197 | Clean up Helm v2 configuration, release data and Tiller deployment: 198 | 199 | ```console 200 | $ helm 2to3 cleanup [flags] 201 | 202 | Flags: 203 | 204 | --config-cleanup if set, configuration cleanup performed 205 | --dry-run simulate a command 206 | -h, --help help for cleanup 207 | --kube-context string name of the kubeconfig context to use 208 | --kubeconfig string path to the kubeconfig file 209 | -l, --label string label to select Tiller resources by (default "OWNER=TILLER") 210 | --name string the release name. When it is specified, the named release and its versions will be removed only. Should not be used with other cleanup operations 211 | --release-cleanup if set, release data cleanup performed 212 | -s, --release-storage string v2 release storage type/object. It can be 'secrets' or 'configmaps'. This is only used with the 'tiller-out-cluster' flag (default "secrets") 213 | --skip-confirmation if set, skips confirmation message before performing cleanup 214 | --tiller-cleanup if set, Tiller cleanup performed 215 | -t, --tiller-ns string namespace of Tiller (default "kube-system") 216 | --tiller-out-cluster when Tiller is not running in the cluster e.g. Tillerless 217 | ``` 218 | 219 | A full clean will remove the: 220 | 221 | - Configuration (Helm home directory) 222 | - v2 release data 223 | - Tiller deployment 224 | 225 | **Note:** Before performing a full or release data clean, remove any Helm v2 releases which have not been migrated to Helm v3 and are unwanted. They can be removed using the Helm v2 `delete` command. If they are not removed before clean up of the v2 release data then the Kubernetes resources deployed by the Helm release will remain in your cluster. In other words, the resources will be 'orphaned' without any Helm release associated. 226 | 227 | Cleanup of individual parts can be performed using the following flags: 228 | 229 | - `--config-cleanup` for configuration 230 | - `--release-cleanup` for v2 release data 231 | - `--tiller-cleanup` for Tiller deployment 232 | - `--name` for a release and its versions. This is a singular operation and is not to be used with the other cleanup operations. 233 | 234 | If none of these flags are set, then full cleanup is performed. 235 | 236 | The cleanup uses the default Helm v2 home folder. 237 | To override this folder you need to set the environment variable `HELM_V2_HOME`: 238 | 239 | ```console 240 | $ export HELM_V2_HOME=$PWD/.helm2 241 | $ helm 2to3 cleanup 242 | ``` 243 | 244 | **Warning:** The full `cleanup` command will remove the Helm v2 Configuration, Release Data and Tiller Deployment. 245 | It cleans up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases. 246 | Helm v2 will not be usable afterwards. Full cleanup should only be run once all migration (clusters and Tiller instances) for a Helm v2 client instance is complete. 247 | Helm v2 may also become unusable depending on cleanup of individual parts. 248 | 249 | ## Troubleshooting 250 | 251 | ***Q. I get an error when I try to do a chart dependency update in Helm v3 after configuration migration*** 252 | 253 | Error might be similar to the following: 254 | 255 | ```console 256 | $ helm dep update chrt-1/ 257 | Hang tight while we grab the latest from your chart repositories... 258 | ...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts): 259 | Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: connect: connection refused 260 | ...Successfully got an update from the "stable" chart repository 261 | Update Complete. ⎈Happy Helming!⎈ 262 | Error: open /home/usr1/.cache/helm/repository/local-index.yaml: no such file or directory 263 | ``` 264 | 265 | A. Local respoitories are not copied to Helm v3. You therefore need to remove all local repositories from Helm v3 using ` repo remove` and re-add where 266 | required using ` repo add`. This is a necessary refresh to align references for Helm v3 and remove the conflict. It is worthwhile to also refresh the 267 | repository list afterwards: ` repo update`. You should then be able to run the chart dependency update command successfully. 268 | 269 | ***Q. I get an error when I try to do a helm upgrade in Helm v3 after migration*** 270 | 271 | Error might be similar to the following: 272 | 273 | ```console 274 | $ helm upgrade nginx bitnami/nginx 275 | Error: failed to download "bitnami/nginx" (hint: running `helm repo update` may help) 276 | ``` 277 | 278 | A. This can happen when there are conflicts in the local repository list that Helm v3 cannot resolve. This can be fixed by running the `helm repo update` command. 279 | 280 | ## Frequently Asked Questions 281 | 282 | ***Q. How do you perform Helm v2 release migration as a batch operation?*** 283 | 284 | A. You can perform batch migration of releases using a command as follows: 285 | 286 | ```console 287 | $ kubectl get [configmap|secret] -n \ 288 | -l "OWNER=TILLER" | awk '{print $1}' | grep -v NAME | cut -d '.' -f1 | uniq | xargs -n1 helm 2to3 convert 289 | ``` 290 | 291 | An example of migrating releases which are stored as ConfigMaps in Tiller namespace `kube-system`: 292 | 293 | ```console 294 | $ kubectl get configmap -n kube-system -l "OWNER=TILLER" \ 295 | | awk '{print $1}' | grep -v NAME | cut -d '.' -f1 | uniq | xargs -n1 helm 2to3 convert 296 | ``` 297 | 298 | ## Developer (From Source) Install 299 | 300 | If you would like to handle the build yourself, this is the recommended way to do it. 301 | 302 | You must first have [Go v1.22](http://golang.org) installed, and then you run: 303 | 304 | ```console 305 | $ git clone git@github.com:helm/helm-2to3.git 306 | $ cd helm-2to3 307 | $ make build 308 | $ export HELM_LINTER_PLUGIN_NO_INSTALL_HOOK=true 309 | $ helm plugin install /helm-2to3 310 | ``` 311 | 312 | That last command will use the binary that you built. 313 | -------------------------------------------------------------------------------- /cmd/cleanup.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "io" 23 | "log" 24 | "strings" 25 | 26 | "github.com/spf13/cobra" 27 | 28 | "github.com/helm/helm-2to3/pkg/common" 29 | utils "github.com/helm/helm-2to3/pkg/utils" 30 | v2 "github.com/helm/helm-2to3/pkg/v2" 31 | ) 32 | 33 | var ( 34 | configCleanup bool 35 | releaseName string 36 | releaseCleanup bool 37 | skipConfirmation bool 38 | tillerCleanup bool 39 | ) 40 | 41 | type CleanupOptions struct { 42 | ConfigCleanup bool 43 | DryRun bool 44 | ReleaseName string 45 | ReleaseCleanup bool 46 | SkipConfirmation bool 47 | StorageType string 48 | TillerCleanup bool 49 | TillerLabel string 50 | TillerNamespace string 51 | TillerOutCluster bool 52 | } 53 | 54 | func newCleanupCmd(out io.Writer) *cobra.Command { 55 | cmd := &cobra.Command{ 56 | Use: "cleanup", 57 | Short: "cleanup Helm v2 configuration, release data and Tiller deployment", 58 | Args: func(cmd *cobra.Command, args []string) error { 59 | return nil 60 | }, 61 | RunE: runCleanup, 62 | } 63 | 64 | flags := cmd.Flags() 65 | settings.AddFlags(flags) 66 | 67 | flags.BoolVar(&configCleanup, "config-cleanup", false, "if set, configuration cleanup performed") 68 | flags.StringVar(&releaseName, "name", "", "the release name. When it is specified, the named release and its versions will be removed only. Should not be used with other cleanup operations") 69 | flags.BoolVar(&releaseCleanup, "release-cleanup", false, "if set, release data cleanup performed") 70 | flags.BoolVar(&skipConfirmation, "skip-confirmation", false, "if set, skips confirmation message before performing cleanup") 71 | flags.BoolVar(&tillerCleanup, "tiller-cleanup", false, "if set, Tiller cleanup performed") 72 | 73 | return cmd 74 | } 75 | 76 | func runCleanup(cmd *cobra.Command, args []string) error { 77 | cleanupOptions := CleanupOptions{ 78 | ConfigCleanup: configCleanup, 79 | DryRun: settings.DryRun, 80 | ReleaseCleanup: releaseCleanup, 81 | ReleaseName: releaseName, 82 | SkipConfirmation: skipConfirmation, 83 | StorageType: settings.ReleaseStorage, 84 | TillerCleanup: tillerCleanup, 85 | TillerLabel: settings.Label, 86 | TillerNamespace: settings.TillerNamespace, 87 | TillerOutCluster: settings.TillerOutCluster, 88 | } 89 | 90 | kubeConfig := common.KubeConfig{ 91 | Context: settings.KubeContext, 92 | File: settings.KubeConfigFile, 93 | } 94 | 95 | return Cleanup(cleanupOptions, kubeConfig) 96 | } 97 | 98 | // Cleanup will delete all release data for in specified namespace and owner label. It will remove 99 | // the Tiller server deployed as per namespace and owner label. It is also delete the Helm gv2 home directory 100 | // which contains the Helm configuration. Helm v2 will be unusable after this operation. 101 | func Cleanup(cleanupOptions CleanupOptions, kubeConfig common.KubeConfig) error { 102 | var message strings.Builder 103 | 104 | if cleanupOptions.ReleaseName != "" { 105 | if cleanupOptions.ConfigCleanup || cleanupOptions.TillerCleanup { 106 | return errors.New("cleanup of a specific release is a singular operation. Other operations like configuration cleanup or Tiller cleanup are not allowed in conjunction with the operation") 107 | } 108 | cleanupOptions.ReleaseCleanup = true 109 | } else { 110 | if !cleanupOptions.ConfigCleanup && !cleanupOptions.ReleaseCleanup && !cleanupOptions.TillerCleanup { 111 | cleanupOptions.ConfigCleanup = true 112 | cleanupOptions.ReleaseCleanup = true 113 | cleanupOptions.TillerCleanup = true 114 | } 115 | } 116 | 117 | if cleanupOptions.DryRun { 118 | log.Println("NOTE: This is in dry-run mode, the following actions will not be executed.") 119 | log.Println("Run without --dry-run to take the actions described below:") 120 | log.Println() 121 | } 122 | 123 | fmt.Fprint(&message, "WARNING: ") 124 | if cleanupOptions.ConfigCleanup { 125 | fmt.Fprint(&message, "\"Helm v2 Configuration\" ") 126 | } 127 | if cleanupOptions.ReleaseCleanup { 128 | if cleanupOptions.ReleaseName == "" { 129 | fmt.Fprint(&message, "\"Release Data\" ") 130 | } else { 131 | fmt.Fprint(&message, fmt.Sprintf("\"Release '%s' Data\" ", cleanupOptions.ReleaseName)) 132 | } 133 | } 134 | if cleanupOptions.TillerCleanup { 135 | fmt.Fprint(&message, "\"Tiller\" ") 136 | } 137 | fmt.Fprintln(&message, "will be removed. ") 138 | if cleanupOptions.ReleaseCleanup && cleanupOptions.ReleaseName == "" { 139 | fmt.Fprintln(&message, "This will clean up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases.") 140 | } 141 | if cleanupOptions.ReleaseName == "" { 142 | fmt.Fprintln(&message, "Helm v2 may not be usable afterwards.") 143 | } 144 | 145 | fmt.Println(message.String()) 146 | 147 | var doCleanup bool 148 | var err error 149 | if cleanupOptions.SkipConfirmation { 150 | log.Println("Skipping confirmation before performing cleanup.") 151 | doCleanup = true 152 | err = nil 153 | } else { 154 | doCleanup, err = utils.AskConfirmation("Cleanup", "cleanup Helm v2 data") 155 | } 156 | if err != nil { 157 | return err 158 | } 159 | if !doCleanup { 160 | log.Println("Cleanup will not proceed as the user didn't answer (Y|y) in order to continue.") 161 | return nil 162 | } 163 | 164 | log.Printf("\nHelm v2 data will be cleaned up.\n") 165 | 166 | if cleanupOptions.ReleaseCleanup { 167 | if cleanupOptions.ReleaseName == "" { 168 | log.Println("[Helm 2] Releases will be deleted.") 169 | } else { 170 | log.Printf("[Helm 2] Release '%s' will be deleted.\n", cleanupOptions.ReleaseName) 171 | } 172 | retrieveOptions := v2.RetrieveOptions{ 173 | ReleaseName: cleanupOptions.ReleaseName, 174 | TillerNamespace: cleanupOptions.TillerNamespace, 175 | TillerLabel: cleanupOptions.TillerLabel, 176 | TillerOutCluster: cleanupOptions.TillerOutCluster, 177 | StorageType: cleanupOptions.StorageType, 178 | } 179 | if cleanupOptions.ReleaseName == "" { 180 | err = v2.DeleteAllReleaseVersions(retrieveOptions, kubeConfig, cleanupOptions.DryRun) 181 | } else { 182 | // Get the releases versions as its the versions that are deleted 183 | v2Releases, err := v2.GetReleaseVersions(retrieveOptions, kubeConfig) 184 | if err != nil { 185 | return err 186 | } 187 | versions := []int32{} 188 | v2RelVerLen := len(v2Releases) 189 | for i := 0; i < v2RelVerLen; i++ { 190 | v2Release := v2Releases[i] 191 | versions = append(versions, v2Release.Version) 192 | } 193 | deleteOptions := v2.DeleteOptions{ 194 | DryRun: cleanupOptions.DryRun, 195 | Versions: versions, 196 | } 197 | err = v2.DeleteReleaseVersions(retrieveOptions, deleteOptions, kubeConfig) 198 | } 199 | if err != nil { 200 | return err 201 | } 202 | if !cleanupOptions.DryRun { 203 | if cleanupOptions.ReleaseName == "" { 204 | log.Println("[Helm 2] Releases deleted.") 205 | } else { 206 | log.Printf("[Helm 2] Release '%s' deleted.\n", cleanupOptions.ReleaseName) 207 | } 208 | } 209 | } 210 | 211 | if !cleanupOptions.TillerOutCluster && cleanupOptions.TillerCleanup { 212 | log.Printf("[Helm 2] Tiller in \"%s\" namespace will be removed.\n", cleanupOptions.TillerNamespace) 213 | err = v2.RemoveTiller(cleanupOptions.TillerNamespace, cleanupOptions.DryRun) 214 | if err != nil { 215 | return err 216 | } 217 | if !cleanupOptions.DryRun { 218 | log.Printf("[Helm 2] Tiller in \"%s\" namespace was removed.\n", cleanupOptions.TillerNamespace) 219 | } 220 | } 221 | 222 | if cleanupOptions.ConfigCleanup { 223 | err = v2.RemoveHomeFolder(cleanupOptions.DryRun) 224 | if err != nil { 225 | return err 226 | } 227 | } 228 | 229 | if !cleanupOptions.DryRun { 230 | log.Println("Helm v2 data was cleaned up successfully.") 231 | } 232 | return nil 233 | } 234 | -------------------------------------------------------------------------------- /cmd/convert.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "io" 22 | "log" 23 | 24 | "github.com/spf13/cobra" 25 | v2rel "k8s.io/helm/pkg/proto/hapi/release" 26 | 27 | common "github.com/helm/helm-2to3/pkg/common" 28 | v2 "github.com/helm/helm-2to3/pkg/v2" 29 | v3 "github.com/helm/helm-2to3/pkg/v3" 30 | 31 | "helm.sh/helm/v3/pkg/storage/driver" 32 | ) 33 | 34 | var ( 35 | deletev2Releases bool 36 | maxReleaseVersions int 37 | // new variable to ignore already migrated releases 38 | ignoreAlreadyMigrated bool 39 | ) 40 | 41 | type ConvertOptions struct { 42 | DeleteRelease bool 43 | DryRun bool 44 | MaxReleaseVersions int 45 | ReleaseName string 46 | StorageType string 47 | TillerLabel string 48 | TillerNamespace string 49 | TillerOutCluster bool 50 | IgnoreAlreadyMigrated bool 51 | } 52 | 53 | func newConvertCmd(out io.Writer) *cobra.Command { 54 | cmd := &cobra.Command{ 55 | Use: "convert [flags] RELEASE", 56 | Short: "migrate Helm v2 release in-place to Helm v3", 57 | Args: func(cmd *cobra.Command, args []string) error { 58 | if len(args) != 1 { 59 | return errors.New("name of release to be converted has to be defined") 60 | } 61 | return nil 62 | }, 63 | 64 | RunE: runConvert, 65 | } 66 | 67 | flags := cmd.Flags() 68 | settings.AddFlags(flags) 69 | 70 | flags.BoolVar(&deletev2Releases, "delete-v2-releases", false, "v2 release versions are deleted after migration. By default, the v2 release versions are retained") 71 | flags.IntVar(&maxReleaseVersions, "release-versions-max", 10, "limit the maximum number of versions converted per release. Use 0 for no limit") 72 | flags.BoolVar(&ignoreAlreadyMigrated, "ignore-already-migrated", false, "Ignore any already migrated release versions and continue migrating") 73 | 74 | return cmd 75 | 76 | } 77 | 78 | func runConvert(cmd *cobra.Command, args []string) error { 79 | releaseName := args[0] 80 | if settings.ReleaseStorage != "configmaps" && settings.ReleaseStorage != "secrets" { 81 | return errors.New("release-storage flag needs to be 'configmaps' or 'secrets'") 82 | } 83 | convertOptions := ConvertOptions{ 84 | DeleteRelease: deletev2Releases, 85 | DryRun: settings.DryRun, 86 | MaxReleaseVersions: maxReleaseVersions, 87 | ReleaseName: releaseName, 88 | StorageType: settings.ReleaseStorage, 89 | TillerLabel: settings.Label, 90 | TillerNamespace: settings.TillerNamespace, 91 | TillerOutCluster: settings.TillerOutCluster, 92 | IgnoreAlreadyMigrated: ignoreAlreadyMigrated, 93 | } 94 | kubeConfig := common.KubeConfig{ 95 | Context: settings.KubeContext, 96 | File: settings.KubeConfigFile, 97 | } 98 | 99 | return Convert(convertOptions, kubeConfig) 100 | } 101 | 102 | // Convert converts Helm 2 release into Helm 3 release. It maps the Helm v2 release versions 103 | // of the release into Helm v3 equivalent and stores the release versions. The underlying Kubernetes resources 104 | // are untouched. Note: The namespaces of each release version need to exist in the Kubernetes cluster. 105 | // The Helm 2 release is retained by default, unless the '--delete-v2-releases' flag is set. 106 | func Convert(convertOptions ConvertOptions, kubeConfig common.KubeConfig) error { 107 | if convertOptions.DryRun { 108 | log.Println("NOTE: This is in dry-run mode, the following actions will not be executed.") 109 | log.Println("Run without --dry-run to take the actions described below:") 110 | log.Println() 111 | } 112 | 113 | log.Printf("Release \"%s\" will be converted from Helm v2 to Helm v3.\n", convertOptions.ReleaseName) 114 | 115 | log.Printf("[Helm 3] Release \"%s\" will be created.\n", convertOptions.ReleaseName) 116 | 117 | retrieveOptions := v2.RetrieveOptions{ 118 | ReleaseName: convertOptions.ReleaseName, 119 | TillerNamespace: convertOptions.TillerNamespace, 120 | TillerLabel: convertOptions.TillerLabel, 121 | TillerOutCluster: convertOptions.TillerOutCluster, 122 | StorageType: convertOptions.StorageType, 123 | } 124 | v2Releases, err := v2.GetReleaseVersions(retrieveOptions, kubeConfig) 125 | if err != nil { 126 | return err 127 | } 128 | 129 | // Limit release versions to migrate. 130 | // Limit is based on newest versions. 131 | v2RelVerLen := len(v2Releases) 132 | startIndex := 0 133 | if convertOptions.MaxReleaseVersions > 0 && convertOptions.MaxReleaseVersions < v2RelVerLen { 134 | log.Println() 135 | log.Printf("NOTE: The max release versions \"%d\" is less than the actual release versions \"%d\".", convertOptions.MaxReleaseVersions, v2RelVerLen) 136 | log.Printf("This means only \"%d\" of the latest release versions will be converted.", convertOptions.MaxReleaseVersions) 137 | if convertOptions.DeleteRelease { 138 | log.Println("This also means some versions will remain in Helm v2 storage that will no longer be visible to Helm v2 commands like 'helm list'. Plugin 'cleanup' command will remove them from storage.") 139 | } 140 | log.Println() 141 | startIndex = v2RelVerLen - convertOptions.MaxReleaseVersions 142 | } 143 | 144 | versions := []int32{} 145 | for i := startIndex; i < v2RelVerLen; i++ { 146 | v2Release := v2Releases[i] 147 | relVerName := v2.GetReleaseVersionName(convertOptions.ReleaseName, v2Release.Version) 148 | log.Printf("[Helm 3] ReleaseVersion \"%s\" will be created.\n", relVerName) 149 | if !convertOptions.DryRun { 150 | if err := createV3ReleaseVersion(v2Release, kubeConfig); err != nil { 151 | 152 | if convertOptions.IgnoreAlreadyMigrated { 153 | if driver.ErrReleaseExists.Error() == err.Error() { 154 | log.Printf("[Helm 3] ReleaseVersion \"%s\" already exists.\n", relVerName) 155 | continue 156 | } 157 | } 158 | 159 | return err 160 | } 161 | log.Printf("[Helm 3] ReleaseVersion \"%s\" created.\n", relVerName) 162 | } 163 | versions = append(versions, v2Release.Version) 164 | } 165 | if !convertOptions.DryRun { 166 | log.Printf("[Helm 3] Release \"%s\" created.\n", convertOptions.ReleaseName) 167 | } 168 | 169 | if convertOptions.DeleteRelease { 170 | log.Printf("[Helm 2] Release \"%s\" will be deleted.\n", convertOptions.ReleaseName) 171 | deleteOptions := v2.DeleteOptions{ 172 | DryRun: convertOptions.DryRun, 173 | Versions: versions, 174 | } 175 | if err := v2.DeleteReleaseVersions(retrieveOptions, deleteOptions, kubeConfig); err != nil { 176 | return err 177 | } 178 | if !convertOptions.DryRun { 179 | log.Printf("[Helm 2] Release \"%s\" deleted.\n", convertOptions.ReleaseName) 180 | 181 | log.Printf("Release \"%s\" was converted successfully from Helm v2 to Helm v3.\n", convertOptions.ReleaseName) 182 | } 183 | } else { 184 | if !convertOptions.DryRun { 185 | log.Printf("Release \"%s\" was converted successfully from Helm v2 to Helm v3.\n", convertOptions.ReleaseName) 186 | log.Println("Note: The v2 release information still remains and should be removed to avoid conflicts with the migrated v3 release.") 187 | log.Println("v2 release information should only be removed using `helm 2to3` cleanup and when all releases have been migrated over.") 188 | } 189 | } 190 | 191 | return nil 192 | } 193 | 194 | func createV3ReleaseVersion(v2Release *v2rel.Release, kubeConfig common.KubeConfig) error { 195 | v3Release, err := v3.CreateRelease(v2Release) 196 | if err != nil { 197 | return err 198 | } 199 | return v3.StoreRelease(v3Release, kubeConfig) 200 | } 201 | -------------------------------------------------------------------------------- /cmd/environment.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package cmd 18 | 19 | import "github.com/spf13/pflag" 20 | 21 | type EnvSettings struct { 22 | DryRun bool 23 | KubeConfigFile string 24 | KubeContext string 25 | Label string 26 | ReleaseStorage string 27 | TillerNamespace string 28 | TillerOutCluster bool 29 | } 30 | 31 | func New() *EnvSettings { 32 | envSettings := EnvSettings{} 33 | return &envSettings 34 | } 35 | 36 | // AddBaseFlags binds base flags to the given flagset. 37 | func (s *EnvSettings) AddBaseFlags(fs *pflag.FlagSet) { 38 | fs.BoolVar(&s.DryRun, "dry-run", false, "simulate a command") 39 | } 40 | 41 | // AddFlags binds flags to the given flagset. 42 | func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) { 43 | s.AddBaseFlags(fs) 44 | fs.StringVar(&s.KubeConfigFile, "kubeconfig", "", "path to the kubeconfig file") 45 | fs.StringVar(&s.KubeContext, "kube-context", s.KubeContext, "name of the kubeconfig context to use") 46 | fs.StringVarP(&s.TillerNamespace, "tiller-ns", "t", "kube-system", "namespace of Tiller") 47 | fs.StringVarP(&s.Label, "label", "l", "OWNER=TILLER", "label to select Tiller resources by") 48 | fs.BoolVar(&s.TillerOutCluster, "tiller-out-cluster", false, "when Tiller is not running in the cluster e.g. Tillerless") 49 | fs.StringVarP(&s.ReleaseStorage, "release-storage", "s", "secrets", "v2 release storage type/object. It can be 'secrets' or 'configmaps'. This is only used with the 'tiller-out-cluster' flag") 50 | 51 | } 52 | -------------------------------------------------------------------------------- /cmd/move_config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "io" 22 | "log" 23 | 24 | "github.com/spf13/cobra" 25 | 26 | utils "github.com/helm/helm-2to3/pkg/utils" 27 | ) 28 | 29 | func newMoveConfigCmd(out io.Writer) *cobra.Command { 30 | cmd := &cobra.Command{ 31 | Use: "move config", 32 | Short: "migrate Helm v2 configuration in-place to Helm v3", 33 | Args: func(cmd *cobra.Command, args []string) error { 34 | if len(args) != 1 { 35 | return errors.New("config argument has to be specified") 36 | } 37 | return nil 38 | }, 39 | RunE: runMove, 40 | } 41 | 42 | flags := cmd.Flags() 43 | settings.AddBaseFlags(flags) 44 | flags.BoolVar(&skipConfirmation, "skip-confirmation", false, "if set, skips confirmation message before performing move") 45 | return cmd 46 | } 47 | 48 | func runMove(cmd *cobra.Command, args []string) error { 49 | moveArgName := args[0] 50 | 51 | if moveArgName != "config" { 52 | return errors.New("config argument has to be specified") 53 | } 54 | 55 | return Move(settings.DryRun) 56 | } 57 | 58 | // Moves/copies v2 configuration to v2 configuration. It copies repository config, 59 | // plugins and starters. It does not copy cache. 60 | func Move(dryRun bool) error { 61 | var err error 62 | var doConfig bool 63 | if dryRun { 64 | log.Println("NOTE: This is in dry-run mode, the following actions will not be executed.") 65 | log.Println("Run without --dry-run to take the actions described below:") 66 | log.Println() 67 | } 68 | 69 | log.Println("WARNING: Helm v3 configuration may be overwritten during this operation.") 70 | log.Println() 71 | if skipConfirmation { 72 | 73 | log.Println("Skipping confirmation before performing move configuration.") 74 | doConfig = true 75 | } else { 76 | doConfig, err = utils.AskConfirmation("Move config", "move the v2 configuration") 77 | if err != nil { 78 | return err 79 | } 80 | } 81 | if !doConfig { 82 | log.Println("Move will not proceed as the user didn't answer (Y|y) in order to continue.") 83 | return nil 84 | } 85 | 86 | log.Println("\nHelm v2 configuration will be moved to Helm v3 configuration.") 87 | err = utils.Copyv2HomeTov3(dryRun) 88 | if err != nil { 89 | return err 90 | } 91 | if !dryRun { 92 | log.Println("Helm v2 configuration was moved successfully to Helm v3 configuration.") 93 | } 94 | return nil 95 | } 96 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "io" 22 | "os" 23 | 24 | "github.com/spf13/cobra" 25 | ) 26 | 27 | var ( 28 | settings *EnvSettings 29 | ) 30 | 31 | func NewRootCmd(out io.Writer, args []string) *cobra.Command { 32 | cmd := &cobra.Command{ 33 | Use: "2to3", 34 | Short: "Migrate and Cleanup Helm v2 configuration and releases in-place to Helm v3", 35 | Long: "Migrate and Cleanup Helm v2 configuration and releases in-place to Helm v3", 36 | SilenceUsage: true, 37 | Args: func(cmd *cobra.Command, args []string) error { 38 | if len(args) > 0 { 39 | return errors.New("no arguments accepted") 40 | } 41 | return nil 42 | }, 43 | } 44 | 45 | flags := cmd.PersistentFlags() 46 | flags.Parse(args) 47 | settings = new(EnvSettings) 48 | 49 | // When run with the Helm plugin framework, Helm plugins are not passed the 50 | // plugin flags that correspond to Helm global flags e.g. helm 2to3 convert --kube-context ... 51 | // The flag values are set to corresponding environment variables instead. 52 | // The flags are passed as expected when run directly using the binary. 53 | // The below allows to use Helm's --kube-context global flag. 54 | if ctx := os.Getenv("HELM_KUBECONTEXT"); ctx != "" { 55 | settings.KubeContext = ctx 56 | } 57 | 58 | // Note that the plugin's --kubeconfig flag is set by the Helm plugin framework to 59 | // the KUBECONFIG environment variable instead of being passed into the plugin. 60 | // That variable is transparently handled by the helm-plugin-utils package so does not 61 | // need to be explicitely handled here. 62 | 63 | cmd.AddCommand( 64 | newCleanupCmd(out), 65 | newConvertCmd(out), 66 | newMoveConfigCmd(out), 67 | ) 68 | 69 | return cmd 70 | } 71 | -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Community Code of Conduct 2 | 3 | Helm follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 4 | -------------------------------------------------------------------------------- /completion.yaml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: cleanup 3 | flags: 4 | - config-cleanup 5 | - dry-run 6 | - l 7 | - label 8 | - name 9 | - release-cleanup 10 | - s 11 | - release-storage 12 | - skip-confirmation 13 | - tiller-cleanup 14 | - t 15 | - tiller-ns 16 | - tiller-out-cluster 17 | - name: convert 18 | flags: 19 | - delete-v2-releases 20 | - dry-run 21 | - ignore-already-migrated 22 | - l 23 | - label 24 | - s 25 | - release-storage 26 | - release-versions-max 27 | - t 28 | - tiller-ns 29 | - tiller-out-cluster 30 | - name: move 31 | commands: 32 | - name: config 33 | flags: 34 | - dry-run 35 | - skip-confirmation 36 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/helm/helm-2to3 2 | 3 | go 1.22.0 4 | 5 | toolchain go1.22.5 6 | 7 | require ( 8 | github.com/golang/protobuf v1.5.4 9 | github.com/maorfr/helm-plugin-utils v0.7.0 10 | github.com/mitchellh/go-homedir v1.1.0 11 | github.com/pkg/errors v0.9.1 12 | github.com/spf13/cobra v1.8.0 13 | github.com/spf13/pflag v1.0.5 14 | helm.sh/helm/v3 v3.15.3 15 | k8s.io/apimachinery v0.30.0 16 | k8s.io/helm v2.17.0+incompatible 17 | ) 18 | 19 | require ( 20 | github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect 21 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect 22 | github.com/BurntSushi/toml v1.3.2 // indirect 23 | github.com/MakeNowJust/heredoc v1.0.0 // indirect 24 | github.com/Masterminds/goutils v1.1.1 // indirect 25 | github.com/Masterminds/semver v1.5.0 // indirect 26 | github.com/Masterminds/semver/v3 v3.2.1 // indirect 27 | github.com/Masterminds/sprig/v3 v3.2.3 // indirect 28 | github.com/Masterminds/squirrel v1.5.4 // indirect 29 | github.com/Microsoft/hcsshim v0.11.4 // indirect 30 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect 31 | github.com/beorn7/perks v1.0.1 // indirect 32 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 33 | github.com/chai2010/gettext-go v1.0.2 // indirect 34 | github.com/containerd/containerd v1.7.12 // indirect 35 | github.com/containerd/log v0.1.0 // indirect 36 | github.com/cyphar/filepath-securejoin v0.2.4 // indirect 37 | github.com/davecgh/go-spew v1.1.1 // indirect 38 | github.com/distribution/reference v0.5.0 // indirect 39 | github.com/docker/cli v25.0.1+incompatible // indirect 40 | github.com/docker/distribution v2.8.3+incompatible // indirect 41 | github.com/docker/docker v25.0.5+incompatible // indirect 42 | github.com/docker/docker-credential-helpers v0.7.0 // indirect 43 | github.com/docker/go-connections v0.5.0 // indirect 44 | github.com/docker/go-metrics v0.0.1 // indirect 45 | github.com/emicklei/go-restful/v3 v3.11.0 // indirect 46 | github.com/evanphx/json-patch v5.7.0+incompatible // indirect 47 | github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect 48 | github.com/fatih/color v1.13.0 // indirect 49 | github.com/felixge/httpsnoop v1.0.3 // indirect 50 | github.com/ghodss/yaml v1.0.0 // indirect 51 | github.com/go-errors/errors v1.4.2 // indirect 52 | github.com/go-gorp/gorp/v3 v3.1.0 // indirect 53 | github.com/go-logr/logr v1.4.1 // indirect 54 | github.com/go-logr/stdr v1.2.2 // indirect 55 | github.com/go-openapi/jsonpointer v0.19.6 // indirect 56 | github.com/go-openapi/jsonreference v0.20.2 // indirect 57 | github.com/go-openapi/swag v0.22.3 // indirect 58 | github.com/gobwas/glob v0.2.3 // indirect 59 | github.com/gogo/protobuf v1.3.2 // indirect 60 | github.com/google/btree v1.0.1 // indirect 61 | github.com/google/gnostic-models v0.6.8 // indirect 62 | github.com/google/go-cmp v0.6.0 // indirect 63 | github.com/google/gofuzz v1.2.0 // indirect 64 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 65 | github.com/google/uuid v1.3.0 // indirect 66 | github.com/gorilla/mux v1.8.0 // indirect 67 | github.com/gorilla/websocket v1.5.0 // indirect 68 | github.com/gosuri/uitable v0.0.4 // indirect 69 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect 70 | github.com/hashicorp/errwrap v1.1.0 // indirect 71 | github.com/hashicorp/go-multierror v1.1.1 // indirect 72 | github.com/huandu/xstrings v1.4.0 // indirect 73 | github.com/imdario/mergo v0.3.13 // indirect 74 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 75 | github.com/jmoiron/sqlx v1.3.5 // indirect 76 | github.com/josharian/intern v1.0.0 // indirect 77 | github.com/json-iterator/go v1.1.12 // indirect 78 | github.com/klauspost/compress v1.16.0 // indirect 79 | github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect 80 | github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect 81 | github.com/lib/pq v1.10.9 // indirect 82 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect 83 | github.com/mailru/easyjson v0.7.7 // indirect 84 | github.com/mattn/go-colorable v0.1.13 // indirect 85 | github.com/mattn/go-isatty v0.0.17 // indirect 86 | github.com/mattn/go-runewidth v0.0.9 // indirect 87 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 88 | github.com/mitchellh/copystructure v1.2.0 // indirect 89 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 90 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 91 | github.com/moby/locker v1.0.1 // indirect 92 | github.com/moby/spdystream v0.2.0 // indirect 93 | github.com/moby/term v0.5.0 // indirect 94 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 95 | github.com/modern-go/reflect2 v1.0.2 // indirect 96 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 97 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 98 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect 99 | github.com/opencontainers/go-digest v1.0.0 // indirect 100 | github.com/opencontainers/image-spec v1.1.0-rc6 // indirect 101 | github.com/peterbourgon/diskv v2.0.1+incompatible // indirect 102 | github.com/prometheus/client_golang v1.16.0 // indirect 103 | github.com/prometheus/client_model v0.4.0 // indirect 104 | github.com/prometheus/common v0.44.0 // indirect 105 | github.com/prometheus/procfs v0.10.1 // indirect 106 | github.com/rubenv/sql-migrate v1.5.2 // indirect 107 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 108 | github.com/shopspring/decimal v1.3.1 // indirect 109 | github.com/sirupsen/logrus v1.9.3 // indirect 110 | github.com/spf13/cast v1.5.0 // indirect 111 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect 112 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 113 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect 114 | github.com/xlab/treeprint v1.2.0 // indirect 115 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect 116 | go.opentelemetry.io/otel v1.19.0 // indirect 117 | go.opentelemetry.io/otel/metric v1.19.0 // indirect 118 | go.opentelemetry.io/otel/trace v1.19.0 // indirect 119 | go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect 120 | golang.org/x/crypto v0.21.0 // indirect 121 | golang.org/x/net v0.23.0 // indirect 122 | golang.org/x/oauth2 v0.10.0 // indirect 123 | golang.org/x/sync v0.6.0 // indirect 124 | golang.org/x/sys v0.18.0 // indirect 125 | golang.org/x/term v0.18.0 // indirect 126 | golang.org/x/text v0.14.0 // indirect 127 | golang.org/x/time v0.3.0 // indirect 128 | google.golang.org/appengine v1.6.7 // indirect 129 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect 130 | google.golang.org/grpc v1.58.3 // indirect 131 | google.golang.org/protobuf v1.33.0 // indirect 132 | gopkg.in/inf.v0 v0.9.1 // indirect 133 | gopkg.in/yaml.v2 v2.4.0 // indirect 134 | gopkg.in/yaml.v3 v3.0.1 // indirect 135 | k8s.io/api v0.30.0 // indirect 136 | k8s.io/apiextensions-apiserver v0.30.0 // indirect 137 | k8s.io/apiserver v0.30.0 // indirect 138 | k8s.io/cli-runtime v0.30.0 // indirect 139 | k8s.io/client-go v0.30.0 // indirect 140 | k8s.io/component-base v0.30.0 // indirect 141 | k8s.io/klog/v2 v2.120.1 // indirect 142 | k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect 143 | k8s.io/kubectl v0.30.0 // indirect 144 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect 145 | oras.land/oras-go v1.2.5 // indirect 146 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 147 | sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect 148 | sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect 149 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 150 | sigs.k8s.io/yaml v1.4.0 // indirect 151 | ) 152 | -------------------------------------------------------------------------------- /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.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 17 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 18 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 19 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 20 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 21 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 22 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 23 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 24 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 25 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 26 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 27 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 28 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 29 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 30 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 31 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 32 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 33 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 34 | github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= 35 | github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= 36 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= 37 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 38 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 39 | github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= 40 | github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 41 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 42 | github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= 43 | github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= 44 | github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= 45 | github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= 46 | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= 47 | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= 48 | github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= 49 | github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= 50 | github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= 51 | github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= 52 | github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= 53 | github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= 54 | github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= 55 | github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= 56 | github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= 57 | github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= 58 | github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= 59 | github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= 60 | github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= 61 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 62 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 63 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 64 | github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= 65 | github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= 66 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 67 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 68 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 69 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 70 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 71 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= 72 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= 73 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 74 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 75 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 76 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 77 | github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= 78 | github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= 79 | github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= 80 | github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= 81 | github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= 82 | github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= 83 | github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= 84 | github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= 85 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 86 | github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= 87 | github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 88 | github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= 89 | github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= 90 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 91 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 92 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 93 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 94 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 95 | github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= 96 | github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= 97 | github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= 98 | github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= 99 | github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= 100 | github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 101 | github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= 102 | github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= 103 | github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 104 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 105 | github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= 106 | github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 107 | github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= 108 | github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 109 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 110 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 111 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 112 | github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= 113 | github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= 114 | github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= 115 | github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= 116 | github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU= 117 | github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= 118 | github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= 119 | github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= 120 | github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= 121 | github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 122 | github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= 123 | github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= 124 | github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= 125 | github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= 126 | github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= 127 | github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= 128 | github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= 129 | github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= 130 | github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= 131 | github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= 132 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 133 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 134 | github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 135 | github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 136 | github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= 137 | github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 138 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 139 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 140 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 141 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 142 | github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 143 | github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= 144 | github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 145 | github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= 146 | github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= 147 | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= 148 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 149 | github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= 150 | github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 151 | github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= 152 | github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= 153 | github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= 154 | github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= 155 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 156 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 157 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 158 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 159 | github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= 160 | github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= 161 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 162 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 163 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 164 | github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= 165 | github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= 166 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 167 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 168 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 169 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 170 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 171 | github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 172 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 173 | github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 174 | github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= 175 | github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 176 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 177 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 178 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 179 | github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 180 | github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= 181 | github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= 182 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= 183 | github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= 184 | github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= 185 | github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= 186 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 187 | github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 188 | github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= 189 | github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 190 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 191 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 192 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 193 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 194 | github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= 195 | github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= 196 | github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= 197 | github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= 198 | github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= 199 | github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= 200 | github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= 201 | github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= 202 | github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= 203 | github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= 204 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 205 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 206 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 207 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 208 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 209 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 210 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 211 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 212 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 213 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 214 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 215 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 216 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 217 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 218 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 219 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 220 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 221 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 222 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 223 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 224 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 225 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 226 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 227 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 228 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 229 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 230 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 231 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 232 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 233 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 234 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 235 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 236 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 237 | github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= 238 | github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 239 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 240 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 241 | github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= 242 | github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= 243 | github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= 244 | github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= 245 | github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= 246 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 247 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 248 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 249 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 250 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 251 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 252 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 253 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 254 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 255 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 256 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 257 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 258 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 259 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 260 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 261 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 262 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 263 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 264 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 265 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 266 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 267 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 268 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 269 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 270 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 271 | github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 272 | github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= 273 | github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 274 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 275 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= 276 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= 277 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 278 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 279 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 280 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 281 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 282 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 283 | github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= 284 | github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= 285 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 286 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 287 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 288 | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= 289 | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 290 | github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= 291 | github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= 292 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= 293 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 294 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 295 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= 296 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 297 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 298 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 299 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 300 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 301 | github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= 302 | github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 303 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 304 | github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 305 | github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= 306 | github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 307 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 308 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 309 | github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 310 | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 311 | github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= 312 | github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= 313 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 314 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 315 | github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= 316 | github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= 317 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 318 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 319 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 320 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 321 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 322 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 323 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 324 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 325 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 326 | github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= 327 | github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= 328 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 329 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 330 | github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= 331 | github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 332 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 333 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 334 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 335 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 336 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 337 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 338 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 339 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 340 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 341 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 342 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 343 | github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= 344 | github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= 345 | github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= 346 | github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= 347 | github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 348 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 349 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 350 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= 351 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= 352 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 353 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 354 | github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 355 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 356 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 357 | github.com/maorfr/helm-plugin-utils v0.7.0 h1:D/55ZPyNHZZ2tmwN/7uniAkN9O7xove45vgyq30t1yg= 358 | github.com/maorfr/helm-plugin-utils v0.7.0/go.mod h1:oUesLkYezgifrzhinBOStzlrtsJo//7WQOpJmZ4imZE= 359 | github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= 360 | github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= 361 | github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= 362 | github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= 363 | github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= 364 | github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= 365 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 366 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 367 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 368 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 369 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 370 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 371 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 372 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 373 | github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= 374 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 375 | github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= 376 | github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= 377 | github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= 378 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 379 | github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= 380 | github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= 381 | github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= 382 | github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= 383 | github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 384 | github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= 385 | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= 386 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 387 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 388 | github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= 389 | github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 390 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 391 | github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 392 | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= 393 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 394 | github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= 395 | github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= 396 | github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= 397 | github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= 398 | github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= 399 | github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= 400 | github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= 401 | github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= 402 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 403 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 404 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 405 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 406 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 407 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 408 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 409 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= 410 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= 411 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 412 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= 413 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 414 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 415 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= 416 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= 417 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 418 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 419 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 420 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 421 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 422 | github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= 423 | github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= 424 | github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= 425 | github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= 426 | github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= 427 | github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= 428 | github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= 429 | github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= 430 | github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= 431 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 432 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 433 | github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= 434 | github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= 435 | github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= 436 | github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= 437 | github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= 438 | github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= 439 | github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= 440 | github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= 441 | github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 442 | github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 443 | github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= 444 | github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= 445 | github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= 446 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 447 | github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= 448 | github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= 449 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 450 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 451 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 452 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 453 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 454 | github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= 455 | github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= 456 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 457 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 458 | github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= 459 | github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= 460 | github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= 461 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 462 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 463 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 464 | github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= 465 | github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= 466 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 467 | github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= 468 | github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= 469 | github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= 470 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 471 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 472 | github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= 473 | github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= 474 | github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= 475 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 476 | github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 477 | github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 478 | github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= 479 | github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= 480 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 481 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 482 | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= 483 | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 484 | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 485 | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= 486 | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 487 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 488 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 489 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 490 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 491 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 492 | github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= 493 | github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 494 | github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= 495 | github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 496 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 497 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 498 | github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= 499 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 500 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 501 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 502 | github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= 503 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 504 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 505 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 506 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 507 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 508 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 509 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 510 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 511 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 512 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 513 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 514 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 515 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 516 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= 517 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 518 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= 519 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 520 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= 521 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 522 | github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= 523 | github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= 524 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 525 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 526 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 527 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 528 | github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 529 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 530 | github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= 531 | github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= 532 | github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= 533 | github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= 534 | github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= 535 | github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= 536 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 537 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 538 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 539 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 540 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 541 | go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= 542 | go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= 543 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= 544 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= 545 | go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= 546 | go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= 547 | go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= 548 | go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= 549 | go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= 550 | go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= 551 | go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= 552 | go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= 553 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 554 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 555 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 556 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 557 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 558 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 559 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 560 | golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 561 | golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= 562 | golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= 563 | golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 564 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 565 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 566 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 567 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 568 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 569 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 570 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 571 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 572 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 573 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 574 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 575 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 576 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 577 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 578 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 579 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 580 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 581 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 582 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 583 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 584 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 585 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 586 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 587 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 588 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 589 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 590 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 591 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 592 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 593 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 594 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= 595 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 596 | golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= 597 | golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= 598 | golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 599 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 600 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 601 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 602 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 603 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 604 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 605 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 606 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 607 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 608 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 609 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 610 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 611 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 612 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 613 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 614 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 615 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 616 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 617 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 618 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 619 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 620 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 621 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 622 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 623 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 624 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 625 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 626 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 627 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 628 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 629 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 630 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 631 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 632 | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 633 | golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 634 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 635 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 636 | golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 637 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 638 | golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= 639 | golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= 640 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 641 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 642 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 643 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 644 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 645 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 646 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 647 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 648 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 649 | golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= 650 | golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= 651 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 652 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 653 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 654 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 655 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 656 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 657 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 658 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 659 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 660 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 661 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 662 | golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= 663 | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 664 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 665 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 666 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 667 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 668 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 669 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 670 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 671 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 672 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 673 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 674 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 675 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 676 | golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 677 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 678 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 679 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 680 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 681 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 682 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 683 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 684 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 685 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 686 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 687 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 688 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 689 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 690 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 691 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 692 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 693 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 694 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 695 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 696 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 697 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 698 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 699 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 700 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 701 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 702 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 703 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 704 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 705 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 706 | golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 707 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 708 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 709 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 710 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 711 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 712 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 713 | golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 714 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 715 | golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= 716 | golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 717 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 718 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 719 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 720 | golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 721 | golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 722 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 723 | golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= 724 | golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= 725 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 726 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 727 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 728 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 729 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 730 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 731 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 732 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 733 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 734 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 735 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 736 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 737 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 738 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 739 | golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 740 | golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= 741 | golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 742 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 743 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 744 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 745 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 746 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 747 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 748 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 749 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 750 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 751 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 752 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 753 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 754 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 755 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 756 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 757 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 758 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 759 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 760 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 761 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 762 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 763 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 764 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 765 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 766 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 767 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 768 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 769 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 770 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 771 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 772 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 773 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 774 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 775 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 776 | golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 777 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 778 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 779 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 780 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 781 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 782 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 783 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 784 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 785 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 786 | golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 787 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 788 | golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= 789 | golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= 790 | golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= 791 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 792 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 793 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 794 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 795 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 796 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 797 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 798 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 799 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 800 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 801 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 802 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 803 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 804 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 805 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 806 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 807 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 808 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 809 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 810 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 811 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 812 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 813 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 814 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 815 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 816 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 817 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 818 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 819 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 820 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 821 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 822 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 823 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 824 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 825 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 826 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 827 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 828 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 829 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 830 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 831 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 832 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 833 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 834 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 835 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 836 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 837 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 838 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 839 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 840 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 841 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 842 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 843 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 844 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 845 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 846 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 847 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 848 | google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 849 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= 850 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= 851 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 852 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 853 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 854 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 855 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 856 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 857 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 858 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 859 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 860 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 861 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 862 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 863 | google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= 864 | google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= 865 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 866 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 867 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 868 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 869 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 870 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 871 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 872 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 873 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 874 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 875 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 876 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 877 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 878 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 879 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 880 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 881 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 882 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 883 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 884 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 885 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 886 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 887 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 888 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 889 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 890 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 891 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 892 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 893 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 894 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 895 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 896 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 897 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 898 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 899 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 900 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 901 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 902 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 903 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 904 | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 905 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 906 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 907 | gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= 908 | gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= 909 | helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc= 910 | helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ= 911 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 912 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 913 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 914 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 915 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 916 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 917 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 918 | k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= 919 | k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= 920 | k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= 921 | k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= 922 | k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= 923 | k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= 924 | k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= 925 | k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= 926 | k8s.io/apiserver v0.30.0 h1:QCec+U72tMQ+9tR6A0sMBB5Vh6ImCEkoKkTDRABWq6M= 927 | k8s.io/apiserver v0.30.0/go.mod h1:smOIBq8t0MbKZi7O7SyIpjPsiKJ8qa+llcFCluKyqiY= 928 | k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= 929 | k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= 930 | k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= 931 | k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= 932 | k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= 933 | k8s.io/component-base v0.30.0 h1:cj6bp38g0ainlfYtaOQuRELh5KSYjhKxM+io7AUIk4o= 934 | k8s.io/component-base v0.30.0/go.mod h1:V9x/0ePFNaKeKYA3bOvIbrNoluTSG+fSJKjLdjOoeXQ= 935 | k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 936 | k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao= 937 | k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= 938 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 939 | k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= 940 | k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= 941 | k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= 942 | k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= 943 | k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= 944 | k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= 945 | k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= 946 | k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= 947 | k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= 948 | k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 949 | k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 950 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= 951 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 952 | oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= 953 | oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= 954 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 955 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 956 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 957 | sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= 958 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= 959 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= 960 | sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= 961 | sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= 962 | sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= 963 | sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= 964 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= 965 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= 966 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= 967 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= 968 | sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= 969 | sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= 970 | sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= 971 | -------------------------------------------------------------------------------- /helm-2to3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helm/helm-2to3/199182621ee65d5c2e464fb4cf17981986a61c8b/helm-2to3.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/helm/helm-2to3/cmd" 23 | ) 24 | 25 | func main() { 26 | migrateCmd := cmd.NewRootCmd(os.Stdout, os.Args[1:]) 27 | 28 | if err := migrateCmd.Execute(); err != nil { 29 | os.Exit(1) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/common/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package common 18 | 19 | type KubeConfig struct { 20 | Context string 21 | File string 22 | } 23 | -------------------------------------------------------------------------------- /pkg/utils/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v2v3 18 | 19 | import ( 20 | "bufio" 21 | "fmt" 22 | "io/ioutil" 23 | "log" 24 | "os" 25 | "path/filepath" 26 | "strings" 27 | 28 | "github.com/pkg/errors" 29 | 30 | v2 "github.com/helm/helm-2to3/pkg/v2" 31 | v3 "github.com/helm/helm-2to3/pkg/v3" 32 | ) 33 | 34 | // Copyv2HomeTov3 copies the v2 home directory to the v3 home directory . 35 | // Note that this is not a direct 1-1 copy 36 | func Copyv2HomeTov3(dryRun bool) error { 37 | v2HomeDir := v2.HomeDir() 38 | log.Printf("[Helm 2] Home directory: %s\n", v2HomeDir) 39 | v3ConfigDir := v3.ConfigDir() 40 | log.Printf("[Helm 3] Config directory: %s\n", v3ConfigDir) 41 | v3DataDir := v3.DataDir() 42 | log.Printf("[Helm 3] Data directory: %s\n", v3DataDir) 43 | v3CacheDir := v3.CacheDir() 44 | log.Printf("[Helm 3] Cache directory: %s\n", v3CacheDir) 45 | 46 | // Create Helm v3 config directory if needed 47 | log.Printf("[Helm 3] Create config folder \"%s\" .\n", v3ConfigDir) 48 | var err error 49 | if !dryRun { 50 | err = ensureDir(v3ConfigDir) 51 | if err != nil { 52 | return fmt.Errorf("[Helm 3] Failed to create config folder \"%s\" due to the following error: %s", v3ConfigDir, err) 53 | } 54 | log.Printf("[Helm 3] Config folder \"%s\" created.\n", v3ConfigDir) 55 | } 56 | 57 | // Move repo config 58 | v2RepoConfig := filepath.Join(v2HomeDir, "repository", "repositories.yaml") 59 | v3RepoConfig := filepath.Join(v3ConfigDir, "repositories.yaml") 60 | log.Printf("[Helm 2] repositories file \"%s\" will copy to [Helm 3] config folder \"%s\" .\n", v2RepoConfig, v3RepoConfig) 61 | if !dryRun { 62 | err = copyFile(v2RepoConfig, v3RepoConfig) 63 | if err != nil { 64 | return fmt.Errorf("Failed to copy [Helm 2] repository file \"%s\" due to the following error: %s", v2RepoConfig, err) 65 | } 66 | log.Printf("[Helm 2] repositories file \"%s\" copied successfully to [Helm 3] config folder \"%s\" .\n", v2RepoConfig, v3RepoConfig) 67 | } 68 | 69 | // Not moving local repo and its cache, as it is safer to recreate: e.g. v2HomeDir/repository/local v2HomeDir/repository/cache 70 | 71 | // Create Helm v3 cache directory if needed 72 | log.Printf("[Helm 3] Create cache folder \"%s\" .\n", v3CacheDir) 73 | if !dryRun { 74 | err = ensureDir(v3CacheDir) 75 | if err != nil { 76 | return fmt.Errorf("[Helm 3] Failed to create cache folder \"%s\" due to the following error: %s", v3CacheDir, err) 77 | } 78 | log.Printf("[Helm 3] cache folder \"%s\" created.\n", v3CacheDir) 79 | } 80 | 81 | // Create Helm v3 data directory if needed 82 | log.Printf("[Helm 3] Create data folder \"%s\" .\n", v3DataDir) 83 | if !dryRun { 84 | err = ensureDir(v3DataDir) 85 | if err != nil { 86 | return fmt.Errorf("[Helm 3] Failed to create data folder \"%s\" due to the following error: %s", v3DataDir, err) 87 | } 88 | log.Printf("[Helm 3] data folder \"%s\" created.\n", v3DataDir) 89 | } 90 | 91 | // Handle plugins 92 | v2Plugins := filepath.Join(v2HomeDir, "cache", "plugins") 93 | plugins, _ := pathExists(v2Plugins) 94 | if plugins { 95 | // Move plugins 96 | v2Plugins := filepath.Join(v2HomeDir, "cache", "plugins") 97 | v3Plugins := filepath.Join(v3CacheDir, "plugins") 98 | log.Printf("[Helm 2] plugins \"%s\" will copy to [Helm 3] cache folder \"%s\" .\n", v2Plugins, v3Plugins) 99 | if !dryRun { 100 | err = copyDir(v2Plugins, v3Plugins) 101 | if err != nil { 102 | return fmt.Errorf("Failed to copy [Helm 2] plugins directory \"%s\" due to the following error: %s", v2Plugins, err) 103 | } 104 | log.Printf("[Helm 2] plugins \"%s\" copied successfully to [Helm 3] cache folder \"%s\" .\n", v2Plugins, v3Plugins) 105 | } 106 | 107 | // Recreate the plugin symbolic links for v3 path 108 | v2Links := filepath.Join(v2HomeDir, "plugins") 109 | log.Printf("[Helm 2] plugin symbolic links \"%s\" will copy to [Helm 3] data folder \"%s\" .\n", v2Links, v3DataDir) 110 | if !dryRun { 111 | err = reCreatePluginSymLinks(v2Links, v3DataDir, v3CacheDir) 112 | if err != nil { 113 | return fmt.Errorf("Failed to copy [Helm 2] plugin links \"%s\" due to the following error: %s", v2Links, err) 114 | } 115 | log.Printf("[Helm 2] plugin links \"%s\" copied successfully to [Helm 3] data folder \"%s\" .\n", v2Links, v3DataDir) 116 | } 117 | } 118 | 119 | // Move starters 120 | v2Starters := filepath.Join(v2HomeDir, "starters") 121 | v3Starters := filepath.Join(v3DataDir, "starters") 122 | log.Printf("[Helm 2] starters \"%s\" will copy to [Helm 3] data folder \"%s\" .\n", v2Starters, v3Starters) 123 | if !dryRun { 124 | err = copyDir(v2Starters, v3Starters) 125 | if err != nil { 126 | return fmt.Errorf("Failed to copy [Helm 2] starters \"%s\" due to the following error: %s", v2Starters, err) 127 | } 128 | log.Printf("[Helm 2] starters \"%s\" copied successfully to [Helm 3] data folder \"%s\" .\n", v2Starters, v3Starters) 129 | } 130 | 131 | return nil 132 | } 133 | 134 | // AskConfirmation provides a prompt for user to confirm continuation with operation 135 | func AskConfirmation(operation, specificMsg string) (bool, error) { 136 | fmt.Printf("[%s/confirm] Are you sure you want to %s? [y/N]: ", operation, specificMsg) 137 | 138 | scanner := bufio.NewScanner(os.Stdin) 139 | scanner.Scan() 140 | if err := scanner.Err(); err != nil { 141 | return false, errors.Wrap(err, "couldn't read from standard input") 142 | } 143 | answer := scanner.Text() 144 | if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" { 145 | return true, nil 146 | } 147 | return false, nil 148 | } 149 | 150 | func copyFile(srcFileName, destFileName string) error { 151 | input, err := ioutil.ReadFile(srcFileName) 152 | if err != nil { 153 | return err 154 | } 155 | st, err := os.Stat(srcFileName) 156 | if err != nil { 157 | return err 158 | } 159 | err = ioutil.WriteFile(destFileName, input, st.Mode()) 160 | if err != nil { 161 | return err 162 | } 163 | 164 | return nil 165 | } 166 | 167 | func copyDir(srcDirName, destDirName string) error { 168 | err := ensureDir(destDirName) 169 | if err != nil { 170 | return fmt.Errorf("Failed to create folder \"%s\" due to the following error: %s", destDirName, err) 171 | } 172 | 173 | directory, _ := os.Open(srcDirName) 174 | objects, err := directory.Readdir(-1) 175 | if err != nil { 176 | return fmt.Errorf("Failed to copy directory due to the following error: %s", err) 177 | } 178 | for _, obj := range objects { 179 | srcFileName := filepath.Join(srcDirName, obj.Name()) 180 | destFileName := filepath.Join(destDirName, obj.Name()) 181 | if obj.IsDir() { 182 | // create sub-directories - recursively 183 | err = copyDir(srcFileName, destFileName) 184 | if err != nil { 185 | return fmt.Errorf("Failed to copy folder \"%s\" to folder \"%s\" due to the following error: %s", srcFileName, destFileName, err) 186 | } 187 | } else { 188 | fileInfo, err := os.Lstat(srcFileName) 189 | if err != nil { 190 | return fmt.Errorf("Failed to check file \"%s\" stats due to the following error: %s", srcFileName, err) 191 | } 192 | if fileInfo.Mode()&os.ModeSymlink != 0 { 193 | err = copySymLink(obj, srcDirName, destDirName) 194 | if err != nil { 195 | return fmt.Errorf("Failed to create symlink for \"%s\" due to the following error: %s", obj.Name(), err) 196 | } 197 | } else { 198 | err = copyFile(srcFileName, destFileName) 199 | if err != nil { 200 | return fmt.Errorf("Failed to copy file \"%s\" to \"%s\" due to the following error: %s", srcFileName, destFileName, err) 201 | } 202 | } 203 | } 204 | } 205 | 206 | return nil 207 | } 208 | 209 | func ensureDir(dirName string) error { 210 | err := os.MkdirAll(dirName, os.ModePerm) 211 | if err != nil && !os.IsExist(err) { 212 | return err 213 | } 214 | return nil 215 | } 216 | 217 | func pathExists(path string) (bool, error) { 218 | _, err := os.Stat(path) 219 | if err == nil { 220 | return true, nil 221 | } 222 | if os.IsNotExist(err) { 223 | return false, nil 224 | } 225 | return true, err 226 | } 227 | 228 | func copySymLink(fileInfo os.FileInfo, srcDirName, destDirName string) error { 229 | originFileName, err := os.Readlink(filepath.Join(srcDirName, fileInfo.Name())) 230 | if err != nil { 231 | return err 232 | } 233 | newSymLinkName := filepath.Join(destDirName, fileInfo.Name()) 234 | err = os.Symlink(originFileName, newSymLinkName) 235 | if err != nil && !os.IsExist(err) { 236 | return err 237 | } 238 | return nil 239 | } 240 | 241 | func reCreatePluginSymLinks(srcDirName, v3DataDir, v3CacheDir string) error { 242 | v3PluginDataDir := filepath.Join(v3DataDir, "plugins") 243 | err := ensureDir(v3PluginDataDir) 244 | if err != nil { 245 | return fmt.Errorf("Failed to create folder \"%s\" due to the following error: %s", v3PluginDataDir, err) 246 | } 247 | directory, _ := os.Open(srcDirName) 248 | objects, err := directory.Readdir(-1) 249 | if err != nil { 250 | return fmt.Errorf("Failed to re-create symlinks due to the following error: %s", err) 251 | } 252 | for _, obj := range objects { 253 | srcFileName := filepath.Join(srcDirName, obj.Name()) 254 | if !obj.IsDir() { 255 | fileInfo, err := os.Lstat(srcFileName) 256 | if err != nil { 257 | return fmt.Errorf("Failed to check file \"%s\" stats due to the following error: %s", srcFileName, err) 258 | } 259 | if fileInfo.Mode()&os.ModeSymlink != 0 { 260 | symLinkName := obj.Name() 261 | newFullSymLinkName := filepath.Join(v3PluginDataDir, symLinkName) 262 | origFullFileName, err := os.Readlink(filepath.Join(srcDirName, fileInfo.Name())) 263 | if err != nil { 264 | return fmt.Errorf("Failed to re-create symlink for \"%s\" due to the following error: %s", symLinkName, err) 265 | } 266 | newFullFileName := filepath.Join(v3CacheDir, "plugins", filepath.Base(origFullFileName)) 267 | err = os.Symlink(newFullFileName, newFullSymLinkName) 268 | if err != nil && !os.IsExist(err) { 269 | return fmt.Errorf("Failed to re-create symlink for \"%s\" due to the following error: %s", newFullSymLinkName, err) 270 | } 271 | } 272 | } 273 | } 274 | return nil 275 | } 276 | -------------------------------------------------------------------------------- /pkg/v2/release.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v2 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "log" 23 | "sort" 24 | 25 | utils "github.com/maorfr/helm-plugin-utils/pkg" 26 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 | 28 | rls "k8s.io/helm/pkg/proto/hapi/release" 29 | 30 | common "github.com/helm/helm-2to3/pkg/common" 31 | ) 32 | 33 | type RetrieveOptions struct { 34 | ReleaseName string 35 | StorageType string 36 | TillerLabel string 37 | TillerNamespace string 38 | TillerOutCluster bool 39 | } 40 | 41 | type DeleteOptions struct { 42 | DryRun bool 43 | Versions []int32 44 | } 45 | 46 | // ByReleaseVersion implements sort.Interface based on the rls.Release Version field 47 | type ByReleaseVersion []*rls.Release 48 | 49 | func (releases ByReleaseVersion) Len() int { return len(releases) } 50 | func (releases ByReleaseVersion) Less(i, j int) bool { 51 | return releases[i].Version < releases[j].Version 52 | } 53 | func (releases ByReleaseVersion) Swap(i, j int) { releases[i], releases[j] = releases[j], releases[i] } 54 | 55 | // GetReleaseVersions returns all release versions from Helm v2 storage for a specified release.. 56 | // It is based on Tiller namespace and labels like owner of storage. 57 | func GetReleaseVersions(retOpts RetrieveOptions, kubeConfig common.KubeConfig) ([]*rls.Release, error) { 58 | releases, err := getReleases(retOpts, kubeConfig) 59 | if err != nil { 60 | return nil, err 61 | } 62 | if len(releases) <= 0 { 63 | return nil, fmt.Errorf("%s has no deployed releases\n", retOpts.ReleaseName) 64 | } 65 | 66 | return releases, nil 67 | 68 | } 69 | 70 | // DeleteReleaseVersions deletes all release data from Helm v2 storage for a specified release. 71 | // It is based on Tiller namespace and labels like owner of storage. 72 | func DeleteReleaseVersions(retOpts RetrieveOptions, delOpts DeleteOptions, kubeConfig common.KubeConfig) error { 73 | for _, ver := range delOpts.Versions { 74 | relVerName := fmt.Sprintf("%s.v%d", retOpts.ReleaseName, ver) 75 | log.Printf("[Helm 2] ReleaseVersion \"%s\" will be deleted.\n", relVerName) 76 | if !delOpts.DryRun { 77 | if err := deleteRelease(retOpts, relVerName, kubeConfig); err != nil { 78 | return fmt.Errorf("[Helm 2] ReleaseVersion \"%s\" failed to delete with error: %s.\n", relVerName, err) 79 | } 80 | log.Printf("[Helm 2] ReleaseVersion \"%s\" deleted.\n", relVerName) 81 | } 82 | } 83 | 84 | return nil 85 | } 86 | 87 | // DeleteReleaseVersions deletes all release data from Helm v2 storage. 88 | // It is based on Tiller namespace and labels like owner of storage. 89 | func DeleteAllReleaseVersions(retOpts RetrieveOptions, kubeConfig common.KubeConfig, dryRun bool) error { 90 | if retOpts.TillerNamespace == "" { 91 | retOpts.TillerNamespace = "kube-system" 92 | } 93 | if retOpts.TillerLabel == "" { 94 | retOpts.TillerLabel = "OWNER=TILLER" 95 | } 96 | if retOpts.StorageType == "" { 97 | retOpts.StorageType = "configmaps" 98 | } 99 | 100 | // Get all release versions stored for that namespace and owner 101 | releases, err := getReleases(retOpts, kubeConfig) 102 | if err != nil { 103 | return err 104 | } 105 | releaseLen := len(releases) 106 | if releaseLen <= 0 { 107 | log.Printf("[Helm 2] no deployed releases for namespace: %s, owner: %s\n", retOpts.TillerNamespace, retOpts.TillerLabel) 108 | return nil 109 | } 110 | 111 | // Delete each release version from storage 112 | for i := 0; i < releaseLen; i++ { 113 | release := releases[i] 114 | relVerName := GetReleaseVersionName(release.Name, release.Version) 115 | log.Printf("[Helm 2] ReleaseVersion \"%s\" will be deleted.\n", relVerName) 116 | if !dryRun { 117 | if err := deleteRelease(retOpts, relVerName, kubeConfig); err != nil { 118 | return fmt.Errorf("[Helm 2] ReleaseVersion \"%s\" failed to delete with error: %s.\n", relVerName, err) 119 | } 120 | log.Printf("[Helm 2] ReleaseVersion \"%s\" deleted.\n", relVerName) 121 | } 122 | } 123 | return nil 124 | } 125 | 126 | func getReleases(retOpts RetrieveOptions, kubeConfig common.KubeConfig) ([]*rls.Release, error) { 127 | if retOpts.TillerNamespace == "" { 128 | retOpts.TillerNamespace = "kube-system" 129 | } 130 | if retOpts.TillerLabel == "" { 131 | retOpts.TillerLabel = "OWNER=TILLER" 132 | } 133 | if retOpts.ReleaseName != "" { 134 | retOpts.TillerLabel += fmt.Sprintf(",NAME=%s", retOpts.ReleaseName) 135 | } 136 | if retOpts.StorageType == "" { 137 | retOpts.StorageType = "configmaps" 138 | } 139 | storage := getStorageType(retOpts, kubeConfig) 140 | clientSet := utils.GetClientSetWithKubeConfig(kubeConfig.File, kubeConfig.Context) 141 | var releases []*rls.Release 142 | switch storage { 143 | case "secrets": 144 | secrets, err := clientSet.CoreV1().Secrets(retOpts.TillerNamespace).List(context.Background(), metav1.ListOptions{ 145 | LabelSelector: retOpts.TillerLabel, 146 | }) 147 | if err != nil { 148 | return nil, err 149 | } 150 | for _, item := range secrets.Items { 151 | release := getRelease((string)(item.Data["release"])) 152 | if release == nil { 153 | continue 154 | } 155 | releases = append(releases, release) 156 | } 157 | case "configmaps": 158 | configMaps, err := clientSet.CoreV1().ConfigMaps(retOpts.TillerNamespace).List(context.Background(), metav1.ListOptions{ 159 | LabelSelector: retOpts.TillerLabel, 160 | }) 161 | if err != nil { 162 | return nil, err 163 | } 164 | for _, item := range configMaps.Items { 165 | release := getRelease(item.Data["release"]) 166 | if release == nil { 167 | continue 168 | } 169 | releases = append(releases, release) 170 | } 171 | } 172 | 173 | sort.Sort(ByReleaseVersion(releases)) 174 | 175 | return releases, nil 176 | } 177 | 178 | func getStorageType(retOpts RetrieveOptions, kubeConfig common.KubeConfig) string { 179 | var storage string 180 | if !retOpts.TillerOutCluster { 181 | storage = utils.GetTillerStorageWithKubeConfig(retOpts.TillerNamespace, kubeConfig.File, kubeConfig.Context) 182 | } else { 183 | storage = retOpts.StorageType 184 | } 185 | return storage 186 | } 187 | 188 | func getRelease(itemReleaseData string) *rls.Release { 189 | data, _ := utils.DecodeRelease(itemReleaseData) 190 | return data 191 | } 192 | 193 | func deleteRelease(retOpts RetrieveOptions, releaseVersionName string, kubeConfig common.KubeConfig) error { 194 | if retOpts.TillerNamespace == "" { 195 | retOpts.TillerNamespace = "kube-system" 196 | } 197 | if retOpts.StorageType == "" { 198 | retOpts.StorageType = "configmaps" 199 | } 200 | storage := getStorageType(retOpts, kubeConfig) 201 | clientSet := utils.GetClientSetWithKubeConfig(kubeConfig.File, kubeConfig.Context) 202 | switch storage { 203 | case "secrets": 204 | return clientSet.CoreV1().Secrets(retOpts.TillerNamespace).Delete(context.Background(), releaseVersionName, metav1.DeleteOptions{}) 205 | case "configmaps": 206 | return clientSet.CoreV1().ConfigMaps(retOpts.TillerNamespace).Delete(context.Background(), releaseVersionName, metav1.DeleteOptions{}) 207 | } 208 | return nil 209 | } 210 | -------------------------------------------------------------------------------- /pkg/v2/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v2 18 | 19 | import ( 20 | "fmt" 21 | "log" 22 | "os" 23 | "path/filepath" 24 | "strings" 25 | 26 | utils "github.com/maorfr/helm-plugin-utils/pkg" 27 | "github.com/mitchellh/go-homedir" 28 | ) 29 | 30 | const sep = string(filepath.Separator) 31 | 32 | // RemoveHomeFolder removes the v2 Helm home folder 33 | func RemoveHomeFolder(dryRun bool) error { 34 | homeDir := HomeDir() 35 | log.Printf("[Helm 2] Home folder \"%s\" will be deleted.\n", homeDir) 36 | if !dryRun { 37 | if err := os.RemoveAll(homeDir); err != nil { 38 | return fmt.Errorf("[Helm 2] Failed to delete \"%s\" due to the following error: %s.\n", homeDir, err) 39 | } 40 | log.Printf("[Helm 2] Home folder \"%s\" deleted.\n", homeDir) 41 | } 42 | return nil 43 | 44 | } 45 | 46 | // RemoveTiller removes Tiller service in a particular namespace from the cluster 47 | func RemoveTiller(tillerNamespace string, dryRun bool) error { 48 | if tillerNamespace == "" { 49 | tillerNamespace = "kube-system" 50 | } 51 | if !dryRun { 52 | log.Printf("[Helm 2] Tiller \"%s\" in \"%s\" namespace will be removed.\n", "deploy", tillerNamespace) 53 | err := executeKubsDeleteTillerCmd(tillerNamespace, "deploy") 54 | if err != nil { 55 | return err 56 | } 57 | log.Printf("[Helm 2] Tiller \"%s\" in \"%s\" namespace was removed successfully.\n", "deploy", tillerNamespace) 58 | 59 | log.Printf("[Helm 2] Tiller \"%s\" in \"%s\" namespace will be removed.\n", "service", tillerNamespace) 60 | err = executeKubsDeleteTillerCmd(tillerNamespace, "service") 61 | if err != nil { 62 | return err 63 | } 64 | log.Printf("[Helm 2] Tiller \"%s\" in \"%s\" namespace was removed successfully.\n", "service", tillerNamespace) 65 | } 66 | return nil 67 | } 68 | 69 | // HomeDir return the Helm home folder 70 | func HomeDir() string { 71 | if homeDir, exists := os.LookupEnv("HELM_V2_HOME"); exists { 72 | return homeDir 73 | } 74 | 75 | homeDir, _ := homedir.Dir() 76 | defaultDir := homeDir + sep + ".helm" 77 | return defaultDir 78 | } 79 | 80 | // GetReleaseVersionName returns release version name 81 | func GetReleaseVersionName(releaseName string, releaseVersion int32) string { 82 | return fmt.Sprintf("%s.v%d", releaseName, releaseVersion) 83 | } 84 | 85 | func executeKubsDeleteTillerCmd(tillerNamespace, label string) error { 86 | delLabel := label + "/tiller-deploy" 87 | applyCmd := []string{"kubectl", "delete", "--namespace", tillerNamespace, delLabel} 88 | output := utils.Execute(applyCmd) 89 | if !strings.Contains(string(output), "\"tiller-deploy\" deleted") { 90 | return fmt.Errorf("[Helm 2] Failed to remove Tiller \"%s\" in \"%s\" namespace due to the following error: %s", label, tillerNamespace, string(output)) 91 | } 92 | return nil 93 | } 94 | -------------------------------------------------------------------------------- /pkg/v3/connect.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v3 18 | 19 | import ( 20 | "fmt" 21 | "log" 22 | "os" 23 | 24 | "helm.sh/helm/v3/pkg/action" 25 | "helm.sh/helm/v3/pkg/cli" 26 | 27 | common "github.com/helm/helm-2to3/pkg/common" 28 | ) 29 | 30 | var ( 31 | settings = cli.New() 32 | ) 33 | 34 | // GetActionConfig returns action configuration based on Helm env 35 | func GetActionConfig(namespace string, kubeConfig common.KubeConfig) (*action.Configuration, error) { 36 | actionConfig := new(action.Configuration) 37 | 38 | // Add kube config settings passed by user 39 | settings.KubeConfig = kubeConfig.File 40 | settings.KubeContext = kubeConfig.Context 41 | 42 | err := actionConfig.Init(settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), debug) 43 | if err != nil { 44 | return nil, err 45 | } 46 | 47 | return actionConfig, err 48 | } 49 | 50 | func debug(format string, v ...interface{}) { 51 | if settings.Debug { 52 | format = fmt.Sprintf("[debug] %s\n", format) 53 | log.Output(2, fmt.Sprintf(format, v...)) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pkg/v3/release.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v3 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | stdtime "time" 23 | 24 | "github.com/golang/protobuf/ptypes" 25 | "github.com/golang/protobuf/ptypes/any" 26 | timestamp "github.com/golang/protobuf/ptypes/timestamp" 27 | 28 | "helm.sh/helm/v3/pkg/chart" 29 | "helm.sh/helm/v3/pkg/release" 30 | "helm.sh/helm/v3/pkg/time" 31 | 32 | v2chrtutil "k8s.io/helm/pkg/chartutil" 33 | v2chart "k8s.io/helm/pkg/proto/hapi/chart" 34 | v2rls "k8s.io/helm/pkg/proto/hapi/release" 35 | 36 | common "github.com/helm/helm-2to3/pkg/common" 37 | ) 38 | 39 | // CreateRelease create a v3 release object from v2 release object 40 | func CreateRelease(v2Rel *v2rls.Release) (*release.Release, error) { 41 | if v2Rel.Chart == nil || v2Rel.Info == nil { 42 | return nil, fmt.Errorf("No v2 chart or info metadata") 43 | } 44 | chrt, err := mapv2ChartTov3Chart(v2Rel.Chart) 45 | if err != nil { 46 | return nil, err 47 | } 48 | config, err := mapConfig(v2Rel.Config) 49 | if err != nil { 50 | return nil, err 51 | } 52 | first, err := mapTimestampToTime(v2Rel.Info.FirstDeployed) 53 | if err != nil { 54 | return nil, err 55 | } 56 | last, err := mapTimestampToTime(v2Rel.Info.LastDeployed) 57 | if err != nil { 58 | return nil, err 59 | } 60 | deleted, err := mapTimestampToTime(v2Rel.Info.Deleted) 61 | if err != nil { 62 | return nil, err 63 | } 64 | v3StatusStr, err := mapStatus(v2Rel.Info) 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | hooks, err := mapHooks(v2Rel.Hooks, v2Rel.Info.Status.LastTestSuiteRun) 70 | if err != nil { 71 | return nil, err 72 | } 73 | 74 | return &release.Release{ 75 | Name: v2Rel.Name, 76 | Namespace: v2Rel.Namespace, 77 | Chart: chrt, 78 | Config: config, 79 | Info: &release.Info{ 80 | FirstDeployed: first, 81 | LastDeployed: last, 82 | Description: v2Rel.Info.Description, 83 | Deleted: deleted, 84 | Status: release.Status(v3StatusStr), 85 | Notes: v2Rel.Info.Status.Notes, 86 | }, 87 | Manifest: v2Rel.Manifest, 88 | Hooks: hooks, 89 | Version: int(v2Rel.Version), 90 | }, nil 91 | } 92 | 93 | // StoreRelease stores a release object in Helm v3 storage 94 | func StoreRelease(rel *release.Release, kubeConfig common.KubeConfig) error { 95 | cfg, err := GetActionConfig(rel.Namespace, kubeConfig) 96 | if err != nil { 97 | return err 98 | } 99 | 100 | return cfg.Releases.Create(rel) 101 | } 102 | 103 | func mapv2ChartTov3Chart(v2Chrt *v2chart.Chart) (*chart.Chart, error) { 104 | v3Chrt := new(chart.Chart) 105 | v3Chrt.Metadata = mapMetadata(v2Chrt) 106 | v3Chrt.Templates = mapTemplates(v2Chrt.Templates) 107 | err := mapDependencies(v2Chrt.Dependencies, v3Chrt) 108 | if err != nil { 109 | return nil, err 110 | } 111 | if v3Chrt.Values, err = mapConfig(v2Chrt.Values); err != nil { 112 | return nil, err 113 | } 114 | v3Chrt.Files = mapFiles(v2Chrt.Files) 115 | // Schema is set to nil as Schema wass introduced in Helm v3 116 | v3Chrt.Schema = nil 117 | // Lock is set to nil because v2 does not save the requirements lock file details 118 | // v3 should gather data as need be from the chart dependencies 119 | v3Chrt.Lock = nil 120 | return v3Chrt, nil 121 | } 122 | 123 | func mapMetadata(v2Chrt *v2chart.Chart) *chart.Metadata { 124 | if v2Chrt.Metadata == nil { 125 | return nil 126 | } 127 | metadata := new(chart.Metadata) 128 | metadata.Name = v2Chrt.Metadata.Name 129 | metadata.Home = v2Chrt.Metadata.Home 130 | metadata.Sources = v2Chrt.Metadata.Sources 131 | metadata.Version = v2Chrt.Metadata.Version 132 | metadata.Description = v2Chrt.Metadata.Description 133 | metadata.Keywords = v2Chrt.Metadata.Keywords 134 | metadata.Maintainers = mapMaintainers(v2Chrt.Metadata.Maintainers) 135 | metadata.Icon = v2Chrt.Metadata.Icon 136 | metadata.APIVersion = v2Chrt.Metadata.ApiVersion 137 | metadata.Condition = v2Chrt.Metadata.Condition 138 | metadata.Tags = v2Chrt.Metadata.Tags 139 | metadata.AppVersion = v2Chrt.Metadata.AppVersion 140 | metadata.Deprecated = v2Chrt.Metadata.Deprecated 141 | metadata.Annotations = v2Chrt.Metadata.Annotations 142 | metadata.KubeVersion = v2Chrt.Metadata.KubeVersion 143 | // v2 does not save the dependency metadata from requirements, so setting to nil 144 | // v3 should gather data as need be from the chart dependencies 145 | metadata.Dependencies = nil 146 | //Default to application 147 | metadata.Type = "application" 148 | return metadata 149 | } 150 | 151 | func mapMaintainers(v2Maintainers []*v2chart.Maintainer) []*chart.Maintainer { 152 | if v2Maintainers == nil { 153 | return nil 154 | } 155 | maintainers := []*chart.Maintainer{} 156 | for _, val := range v2Maintainers { 157 | maintainer := new(chart.Maintainer) 158 | maintainer.Name = val.Name 159 | maintainer.Email = val.Email 160 | maintainer.URL = val.Url 161 | maintainers = append(maintainers, maintainer) 162 | } 163 | return maintainers 164 | } 165 | 166 | func mapTemplates(v2Templates []*v2chart.Template) []*chart.File { 167 | if v2Templates == nil { 168 | return nil 169 | } 170 | files := []*chart.File{} 171 | for _, val := range v2Templates { 172 | file := new(chart.File) 173 | file.Name = val.Name 174 | file.Data = val.Data 175 | files = append(files, file) 176 | } 177 | return files 178 | } 179 | 180 | func mapDependencies(v2Dependencies []*v2chart.Chart, chart *chart.Chart) error { 181 | if v2Dependencies == nil { 182 | return nil 183 | } 184 | for _, val := range v2Dependencies { 185 | dependency, err := mapv2ChartTov3Chart(val) 186 | if err != nil { 187 | return err 188 | } 189 | chart.AddDependency(dependency) 190 | } 191 | return nil 192 | } 193 | 194 | func mapConfig(v2Config *v2chart.Config) (map[string]interface{}, error) { 195 | if v2Config == nil { 196 | return nil, nil 197 | } 198 | values, err := v2chrtutil.ReadValues([]byte(v2Config.Raw)) 199 | if err != nil { 200 | return nil, err 201 | } 202 | return values, nil 203 | } 204 | 205 | func mapFiles(v2Files []*any.Any) []*chart.File { 206 | if v2Files == nil { 207 | return nil 208 | } 209 | files := []*chart.File{} 210 | for _, f := range v2Files { 211 | file := new(chart.File) 212 | file.Name = f.TypeUrl 213 | file.Data = f.Value 214 | files = append(files, file) 215 | } 216 | return files 217 | } 218 | 219 | func mapStatus(v2Info *v2rls.Info) (string, error) { 220 | v2StatusStr, ok := v2rls.Status_Code_name[int32(v2Info.Status.Code)] 221 | if !ok { 222 | return "", fmt.Errorf("Failed to get v2 status") 223 | } 224 | // map to v3 status 225 | lowerCaseStr := strings.ToLower(v2StatusStr) 226 | v3StatusStr := strings.ReplaceAll(lowerCaseStr, "_", "-") 227 | if v3StatusStr == "deleted" { 228 | v3StatusStr = "uninstalled" 229 | } 230 | if v3StatusStr == "deleting" { 231 | v3StatusStr = "uninstalling" 232 | } 233 | return v3StatusStr, nil 234 | } 235 | 236 | func mapHooks(v2Hooks []*v2rls.Hook, v2LastTestSuiteRun *v2rls.TestSuite) ([]*release.Hook, error) { 237 | if v2Hooks == nil { 238 | return nil, nil 239 | } 240 | hooks := []*release.Hook{} 241 | for _, val := range v2Hooks { 242 | hook := new(release.Hook) 243 | hook.Name = val.Name 244 | hook.Kind = val.Kind 245 | hook.Path = val.Path 246 | hook.Manifest = val.Manifest 247 | events, err := mapHookEvents(val.Events) 248 | if err != nil { 249 | return nil, err 250 | } 251 | hook.Events = events 252 | hook.Weight = int(val.Weight) 253 | if err != nil { 254 | return nil, err 255 | } 256 | policies, err := mapHookDeletePolicies(val.DeletePolicies) 257 | if err != nil { 258 | return nil, err 259 | } 260 | hook.DeletePolicies = policies 261 | var lastRun *release.HookExecution 262 | lastRun, err = mapTestSuiteToHookExecution(hook.Name, v2LastTestSuiteRun) 263 | if err != nil { 264 | return nil, err 265 | } 266 | if lastRun != nil { 267 | hook.LastRun = *lastRun 268 | } 269 | hooks = append(hooks, hook) 270 | } 271 | return hooks, nil 272 | } 273 | 274 | func mapHookEvents(v2HookEvents []v2rls.Hook_Event) ([]release.HookEvent, error) { 275 | if v2HookEvents == nil { 276 | return nil, nil 277 | } 278 | hookEvents := []release.HookEvent{} 279 | for _, val := range v2HookEvents { 280 | v2EventStr, ok := v2rls.Hook_Event_name[int32(val)] 281 | if !ok { 282 | return nil, fmt.Errorf("Failed to get the v2 hook event string") 283 | } 284 | 285 | // map to v3 hook event 286 | lowerCaseStr := strings.ToLower(v2EventStr) 287 | v3EventStr := strings.ReplaceAll(lowerCaseStr, "_", "-") 288 | if strings.Contains(v3EventStr, "release-test") { 289 | v3EventStr = "test" 290 | } 291 | 292 | event := release.HookEvent(v3EventStr) 293 | hookEvents = append(hookEvents, event) 294 | } 295 | return hookEvents, nil 296 | } 297 | 298 | func mapHookDeletePolicies(v2HookDelPolicies []v2rls.Hook_DeletePolicy) ([]release.HookDeletePolicy, error) { 299 | if v2HookDelPolicies == nil { 300 | return nil, nil 301 | } 302 | hookDelPolicies := []release.HookDeletePolicy{} 303 | for _, val := range v2HookDelPolicies { 304 | v2PolicyStr, ok := v2rls.Hook_DeletePolicy_name[int32(val)] 305 | if !ok { 306 | return nil, fmt.Errorf("Failed to get the v2 hook delete policy") 307 | } 308 | 309 | // map to v3 hook delete policy 310 | lowerCaseStr := strings.ToLower(v2PolicyStr) 311 | v3PolicyStr := strings.ReplaceAll(lowerCaseStr, "_", "-") 312 | if !strings.Contains(v3PolicyStr, "before-hook-creation") { 313 | v3PolicyStr = "hook-" + v3PolicyStr 314 | } 315 | 316 | policy := release.HookDeletePolicy(strings.ToLower(v3PolicyStr)) 317 | hookDelPolicies = append(hookDelPolicies, policy) 318 | } 319 | return hookDelPolicies, nil 320 | } 321 | 322 | func mapTimestampToTime(ts *timestamp.Timestamp) (time.Time, error) { 323 | var mappedTime stdtime.Time 324 | var err error 325 | if ts != nil { 326 | mappedTime, err = ptypes.Timestamp(ts) 327 | if err != nil { 328 | return time.Time{Time: mappedTime}, err 329 | } 330 | } 331 | return time.Time{Time: mappedTime}, nil 332 | } 333 | 334 | func mapTestSuiteToHookExecution(hookName string, testSuite *v2rls.TestSuite) (*release.HookExecution, error) { 335 | if testSuite == nil { 336 | return nil, nil 337 | } 338 | 339 | testSuiteResLen := len(testSuite.Results) 340 | 341 | if testSuiteResLen <= 0 { 342 | return nil, nil 343 | } 344 | 345 | for i := 0; i < testSuiteResLen; i++ { 346 | testRun := testSuite.Results[i] 347 | if testRun.Name != hookName { 348 | continue 349 | } 350 | hookEx := new(release.HookExecution) 351 | var err error 352 | hookEx.StartedAt, err = mapTimestampToTime(testRun.StartedAt) 353 | if err != nil { 354 | return nil, err 355 | } 356 | hookEx.CompletedAt, err = mapTimestampToTime(testRun.CompletedAt) 357 | if err != nil { 358 | return nil, err 359 | } 360 | v2RunStatusStr, ok := v2rls.TestRun_Status_name[int32(testRun.Status)] 361 | if !ok { 362 | return nil, fmt.Errorf("Failed to get the v2 test run status") 363 | } 364 | 365 | // Map to v3 test run status 366 | v3RunStatusStr := strings.ToLower(v2RunStatusStr) 367 | if v3RunStatusStr == "success" { 368 | v3RunStatusStr = "Succeeded" 369 | } 370 | if v3RunStatusStr == "failure" { 371 | v3RunStatusStr = "Failed" 372 | } 373 | 374 | hookEx.Phase = release.HookPhase(strings.Title(v3RunStatusStr)) 375 | return hookEx, nil 376 | } 377 | 378 | return nil, nil 379 | } 380 | -------------------------------------------------------------------------------- /pkg/v3/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 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 | 17 | package v3 18 | 19 | import ( 20 | "os" 21 | 22 | "helm.sh/helm/v3/pkg/helmpath" 23 | ) 24 | 25 | // ConfigDir returns the v2 config directory 26 | func ConfigDir() string { 27 | if homeDir, exists := os.LookupEnv("HELM_V3_CONFIG"); exists { 28 | return homeDir 29 | } 30 | 31 | defaultDir := helmpath.ConfigPath() 32 | return defaultDir 33 | } 34 | 35 | // DataDir returns the v3 data directory 36 | func DataDir() string { 37 | if homeDir, exists := os.LookupEnv("HELM_V3_DATA"); exists { 38 | return homeDir 39 | } 40 | 41 | defaultDir := helmpath.DataPath() 42 | return defaultDir 43 | } 44 | 45 | // CacheDir returns the v3 data directory 46 | func CacheDir() string { 47 | if homeDir, exists := os.LookupEnv("HELM_V3_CACHE"); exists { 48 | return homeDir 49 | } 50 | 51 | defaultDir := helmpath.CachePath() 52 | return defaultDir 53 | } 54 | -------------------------------------------------------------------------------- /plugin.yaml: -------------------------------------------------------------------------------- 1 | name: "2to3" 2 | version: "0.11.0" 3 | usage: "migrate and cleanup Helm v2 configuration and releases in-place to Helm v3" 4 | description: "migrate and cleanup Helm v2 configuration and releases in-place to Helm v3" 5 | command: "$HELM_PLUGIN_DIR/bin/2to3" 6 | hooks: 7 | install: "cd $HELM_PLUGIN_DIR; scripts/install_plugin.sh" 8 | update: "cd $HELM_PLUGIN_DIR; scripts/install_plugin.sh" 9 | -------------------------------------------------------------------------------- /scripts/install_plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | if [ -n "${HELM_LINTER_PLUGIN_NO_INSTALL_HOOK}" ]; then 4 | echo "Development mode: not downloading versioned release." 5 | exit 0 6 | fi 7 | 8 | # shellcheck disable=SC2002 9 | version="$(cat plugin.yaml | grep "version" | cut -d '"' -f 2)" 10 | echo "Downloading and installing helm-2to3 v${version} ..." 11 | 12 | url="" 13 | if [ "$(uname)" = "Darwin" ]; then 14 | if [ "$(uname -m)" = "arm64" ]; then 15 | url="https://github.com/helm/helm-2to3/releases/download/v${version}/helm-2to3_${version}_darwin_arm64.tar.gz" 16 | else 17 | url="https://github.com/helm/helm-2to3/releases/download/v${version}/helm-2to3_${version}_darwin_amd64.tar.gz" 18 | fi 19 | elif [ "$(uname)" = "Linux" ] ; then 20 | if [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "arm64" ]; then 21 | url="https://github.com/helm/helm-2to3/releases/download/v${version}/helm-2to3_${version}_linux_arm64.tar.gz" 22 | else 23 | url="https://github.com/helm/helm-2to3/releases/download/v${version}/helm-2to3_${version}_linux_amd64.tar.gz" 24 | fi 25 | else 26 | url="https://github.com/helm/helm-2to3/releases/download/v${version}/helm-2to3_${version}_windows_amd64.tar.gz" 27 | fi 28 | 29 | echo "$url" 30 | 31 | mkdir -p "bin" 32 | mkdir -p "releases/v${version}" 33 | 34 | # Download with curl if possible. 35 | # shellcheck disable=SC2230 36 | if [ -x "$(which curl 2>/dev/null)" ]; then 37 | curl -sSL "${url}" -o "releases/v${version}.tar.gz" 38 | else 39 | wget -q "${url}" -O "releases/v${version}.tar.gz" 40 | fi 41 | tar xzf "releases/v${version}.tar.gz" -C "releases/v${version}" 42 | mv "releases/v${version}/2to3" "bin/2to3" || \ 43 | mv "releases/v${version}/2to3.exe" "bin/2to3" 44 | mv "releases/v${version}/completion.yaml" . 45 | mv "releases/v${version}/plugin.yaml" . 46 | mv "releases/v${version}/README.md" . 47 | mv "releases/v${version}/LICENSE" . 48 | -------------------------------------------------------------------------------- /scripts/tag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # shellcheck disable=SC2002 4 | tag="$(cat plugin.yaml | grep "version" | cut -d '"' -f 2)" 5 | echo "Tagging helm-2to3 with v${tag} ..." 6 | 7 | git checkout main 8 | git pull 9 | git tag -a -m "Release v$tag" "v$tag" 10 | git push origin refs/tags/v"$tag" 11 | --------------------------------------------------------------------------------