├── .vscode └── settings.json ├── .github ├── dependabot.yml └── workflows │ ├── auto-merge.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── .goreleaser.yaml ├── go.mod ├── README.md ├── main.go └── go.sum /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | dist 11 | .DS_Store 12 | 13 | # Test binary, built with `go test -c` 14 | *.test 15 | 16 | # Output of the go coverage tool, specifically when used with LiteIDE 17 | *.out 18 | 19 | # Dependency directories (remove the comment below to include it) 20 | # vendor/ 21 | 22 | # Go workspace file 23 | go.work 24 | 25 | dist/ 26 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/xt0rted/46475099dc0a70ba63e16e3177407872 2 | name: Dependabot auto-merge 3 | 4 | on: pull_request 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | jobs: 11 | dependabot: 12 | runs-on: ubuntu-latest 13 | 14 | if: github.event.pull_request.user.login == 'dependabot[bot]' 15 | 16 | steps: 17 | - name: Dependabot metadata 18 | id: dependabot_metadata 19 | uses: dependabot/fetch-metadata@v2 20 | with: 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | - name: Enable auto-merge for Dependabot PRs 24 | if: (steps.dependabot_metadata.outputs.update-type == 'version-update:semver-minor' || steps.dependabot_metadata.outputs.update-type == 'version-update:semver-patch') 25 | run: | 26 | gh pr merge --auto --merge "$PR_URL" 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | PR_URL: ${{ github.event.pull_request.html_url }} 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Sian Loong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/release.yml 2 | name: Release 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | # run only against tags 9 | tags: 10 | - "v*" 11 | 12 | permissions: 13 | contents: write 14 | # packages: write 15 | # issues: write 16 | 17 | jobs: 18 | goreleaser: 19 | runs-on: ubuntu-latest 20 | if: startsWith(github.ref, 'refs/tags/v') 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 26 | 27 | - name: Set up Go 28 | uses: actions/setup-go@v5 29 | with: 30 | go-version: stable 31 | 32 | - name: get version 33 | run: echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV 34 | 35 | # More assembly might be required: Docker logins, GPG, etc. 36 | # It all depends on your needs. 37 | - name: Run GoReleaser 38 | uses: goreleaser/goreleaser-action@v6 39 | with: 40 | # either 'goreleaser' (default) or 'goreleaser-pro' 41 | distribution: goreleaser 42 | version: latest 43 | args: release --clean 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GH_PAT }} 46 | # Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution 47 | # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} 48 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | 4 | # The lines below are called `modelines`. See `:help modeline` 5 | # Feel free to remove those if you don't want/need to use them. 6 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 7 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 8 | 9 | version: 1 10 | 11 | before: 12 | hooks: 13 | # You may remove this if you don't use go modules. 14 | - go mod tidy 15 | # you may remove this if you don't need go generate 16 | - go generate ./... 17 | 18 | builds: 19 | - env: 20 | - CGO_ENABLED=0 21 | goos: 22 | - linux 23 | - windows 24 | - darwin 25 | 26 | archives: 27 | - format: tar.gz 28 | # this name template makes the OS and Arch compatible with the results of `uname`. 29 | name_template: >- 30 | {{ .ProjectName }}_ 31 | {{- title .Os }}_ 32 | {{- if eq .Arch "amd64" }}x86_64 33 | {{- else if eq .Arch "386" }}i386 34 | {{- else }}{{ .Arch }}{{ end }} 35 | {{- if .Arm }}v{{ .Arm }}{{ end }} 36 | # use zip for windows archives 37 | format_overrides: 38 | - goos: windows 39 | format: zip 40 | 41 | brews: 42 | - name: helm-restore 43 | repository: 44 | owner: si3nloong 45 | name: homebrew-tools 46 | folder: Formula 47 | homepage: https://github.com/si3nloong/helm-restore 48 | description: A CLI to restore your helm charts 49 | 50 | changelog: 51 | sort: asc 52 | filters: 53 | exclude: 54 | - "^docs:" 55 | - "^test:" 56 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/si3nloong/helm-restore 2 | 3 | go 1.24.0 4 | 5 | toolchain go1.24.1 6 | 7 | require ( 8 | k8s.io/apimachinery v0.34.3 9 | k8s.io/client-go v0.34.3 10 | sigs.k8s.io/yaml v1.6.0 11 | ) 12 | 13 | require ( 14 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 15 | github.com/emicklei/go-restful/v3 v3.12.2 // indirect 16 | github.com/fxamacker/cbor/v2 v2.9.0 // indirect 17 | github.com/go-logr/logr v1.4.2 // indirect 18 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 19 | github.com/go-openapi/jsonreference v0.20.2 // indirect 20 | github.com/go-openapi/swag v0.23.0 // indirect 21 | github.com/gogo/protobuf v1.3.2 // indirect 22 | github.com/google/gnostic-models v0.7.0 // indirect 23 | github.com/google/uuid v1.6.0 // indirect 24 | github.com/josharian/intern v1.0.0 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/mailru/easyjson v0.7.7 // indirect 27 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 28 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect 29 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 30 | github.com/pkg/errors v0.9.1 // indirect 31 | github.com/spf13/pflag v1.0.6 // indirect 32 | github.com/x448/float16 v0.8.4 // indirect 33 | go.yaml.in/yaml/v2 v2.4.2 // indirect 34 | go.yaml.in/yaml/v3 v3.0.4 // indirect 35 | golang.org/x/net v0.38.0 // indirect 36 | golang.org/x/oauth2 v0.27.0 // indirect 37 | golang.org/x/sys v0.31.0 // indirect 38 | golang.org/x/term v0.30.0 // indirect 39 | golang.org/x/text v0.23.0 // indirect 40 | golang.org/x/time v0.9.0 // indirect 41 | google.golang.org/protobuf v1.36.5 // indirect 42 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 43 | gopkg.in/inf.v0 v0.9.1 // indirect 44 | gopkg.in/yaml.v3 v3.0.1 // indirect 45 | k8s.io/api v0.34.3 // indirect 46 | k8s.io/klog/v2 v2.130.1 // indirect 47 | k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect 48 | k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect 49 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect 50 | sigs.k8s.io/randfill v1.0.0 // indirect 51 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect 52 | ) 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # helm-restore 2 | 3 | > A CLI to restore your helm charts. As long as your kubernetes cluster is available, you can restore the helm chart using `helm-restore` CLI. 4 | 5 | ## ❓ Why `helm-restore`? 6 | 7 | Encountering the scenarios mentioned below? It's time to leverage the power of `helm-restore` CLI. 8 | 9 | - Your team has lost the original helm charts. 10 | - Previous developer has left the organization without providing the original Helm charts. 11 | - Third party has assisted in setting up components, leaving you without the original Helm charts. 12 | 13 | Having faced the same challenges, I developed this tool to simplify the process of recovering Helm charts. 14 | 15 | ## 🔨 Installation 16 | 17 | ### Brew 18 | 19 | ```console 20 | brew tap si3nloong/tools 21 | brew install helm-restore 22 | ``` 23 | 24 | ### Go 25 | 26 | ```console 27 | go install github.com/si3nloong/helm-restore@main 28 | ``` 29 | 30 | ### Distribution 31 | 32 | [Downloads](https://github.com/si3nloong/helm-restore/releases/tag/v1.0.0) 33 | 34 | ## 🥢 How to use? 35 | 36 | ```bash 37 | helm-restore --latest -o dist 38 | ``` 39 | 40 | This will take some time if you have many charts. After it complete, you will see your charts inside `dist` folder. 41 | 42 | ## ⚙️ Command line tool 43 | 44 | ### Syntax 45 | 46 | Use the following syntax to run `helm-restore` commands from your terminal window: 47 | 48 | ```bash 49 | helm-restore [command] [flags] 50 | ``` 51 | 52 | where `command`, and `flags` are: 53 | 54 | - `command`: Specifies the operation that you want to perform. 55 | - `flags`: Specifies optional flags. 56 | 57 | ### Cheat Sheet 58 | 59 | | Flags | Description | 60 | | -------------------- | ------------------------------------------------------------------------------------------------- | 61 | | --latest | Only download the latest chart | 62 | | -f | Load the cluster using the specific kubeconfig file instead of using default `$HOME/.kube/config` | 63 | | -o | Store the helm charts in the specific folder | 64 | | -context | Specify the kubernetes context | 65 | 66 | **Examples :** 67 | 68 | ```bash 69 | helm-restore --latest # download the latest charts only 70 | helm-restore -o dist # download the charts and store in `dist` folder 71 | ``` 72 | 73 | ## 📄 License 74 | 75 | [MIT](https://github.com/si3nloong/helm-restore/blob/main/LICENSE) 76 | 77 | Copyright (c) 2024-present, SianLoong Lee 78 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "context" 7 | "encoding/base64" 8 | "encoding/json" 9 | "flag" 10 | "fmt" 11 | "log" 12 | "os" 13 | "path/filepath" 14 | "strconv" 15 | "strings" 16 | 17 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 18 | "k8s.io/client-go/kubernetes" 19 | "k8s.io/client-go/rest" 20 | "k8s.io/client-go/tools/clientcmd" 21 | "k8s.io/client-go/util/homedir" 22 | "sigs.k8s.io/yaml" 23 | ) 24 | 25 | const ( 26 | defaultNS = "default" 27 | ) 28 | 29 | type HelmChartTemplate struct { 30 | Name string `json:"name"` 31 | // Info struct { 32 | // FirstDeployed time.Time `json:"first_deployed"` 33 | // LastDeployed time.Time `json:"last_deployed"` 34 | // Deleted string `json:"deleted"` 35 | // Description string `json:"description"` 36 | // Status string `json:"status"` 37 | // Notes string `json:"notes"` 38 | // } `json:"info"` 39 | Chart struct { 40 | Metadata json.RawMessage `json:"metadata"` 41 | Templates []struct { 42 | Name string `json:"name"` 43 | Data string `json:"data"` 44 | } `json:"templates"` 45 | Values json.RawMessage `json:"values"` 46 | // Schema any `json:"schema"` 47 | Files []struct { 48 | Name string `json:"name"` 49 | Data string `json:"data"` 50 | } `json:"files"` 51 | Dependencies []struct { 52 | Name string `json:"name"` 53 | Version string `json:"version"` 54 | Repository string `json:"repository"` 55 | } `json:"dependencies"` 56 | } `json:"chart"` 57 | Manifest string `json:"manifest"` 58 | // Version int `json:"version"` 59 | Namespace string `json:"namespace"` 60 | } 61 | 62 | type cmdOpts struct { 63 | kubeConfig string 64 | clusterContext string 65 | outDir string 66 | latest bool 67 | } 68 | 69 | // https://devops.stackexchange.com/questions/4344/original-helm-chart-gone-how-can-i-find-get-it-from-the-cluster/17642#17642?newreg=b1f82da562c445b086a171eb8397f33b 70 | func main() { 71 | var opts cmdOpts 72 | 73 | flag.StringVar(&opts.outDir, "o", ".", "Destination folder (output)") 74 | flag.StringVar(&opts.kubeConfig, "f", filepath.Join(homedir.HomeDir(), ".kube", "config"), "Kubernetes config file") 75 | flag.StringVar(&opts.clusterContext, "context", "", "Cluster context name") 76 | flag.BoolVar(&opts.latest, "latest", false, "Latest helm chart only") 77 | flag.Parse() 78 | 79 | os.MkdirAll(opts.outDir, os.ModePerm) 80 | 81 | if err := rootCommand(opts); err != nil { 82 | log.Fatal(err) 83 | } 84 | } 85 | 86 | func rootCommand(opts cmdOpts) error { 87 | ctx, cancel := context.WithCancel(context.Background()) 88 | defer cancel() 89 | 90 | var ( 91 | config *rest.Config 92 | err error 93 | ) 94 | 95 | if opts.clusterContext != "" { 96 | config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig( 97 | &clientcmd.ClientConfigLoadingRules{ExplicitPath: opts.kubeConfig}, 98 | &clientcmd.ConfigOverrides{ 99 | CurrentContext: opts.clusterContext, 100 | }).ClientConfig() 101 | if err != nil { 102 | return err 103 | } 104 | } else { 105 | config, err = clientcmd.BuildConfigFromFlags("", opts.kubeConfig) 106 | if err != nil { 107 | return err 108 | } 109 | } 110 | 111 | // Creates the clientset 112 | clientset, err := kubernetes.NewForConfig(config) 113 | if err != nil { 114 | return err 115 | } 116 | 117 | secrets, err := clientset.CoreV1().Secrets(defaultNS).List(ctx, v1.ListOptions{}) 118 | if err != nil { 119 | return err 120 | } 121 | 122 | for len(secrets.Items) > 0 { 123 | secret := secrets.Items[0] 124 | 125 | if !strings.HasPrefix(string(secret.Type), "helm.sh/release.") { 126 | secrets.Items = secrets.Items[1:] 127 | continue 128 | } 129 | 130 | b := secret.Data["release"] 131 | if len(b) == 0 { 132 | secrets.Items = secrets.Items[1:] 133 | continue 134 | } 135 | b, err = base64Decode(b) 136 | if err != nil { 137 | return err 138 | } 139 | 140 | r, err := gzip.NewReader(bytes.NewBuffer(b)) 141 | if err != nil { 142 | return err 143 | } 144 | defer r.Close() 145 | 146 | var chart HelmChartTemplate 147 | if err := json.NewDecoder(r).Decode(&chart); err != nil { 148 | return err 149 | } 150 | 151 | rootDir := filepath.Join(opts.outDir, secret.Name) 152 | os.MkdirAll(rootDir, os.ModePerm) 153 | 154 | if opts.latest { 155 | lastIdx := strings.LastIndex(secret.Name, ".") 156 | version, _ := strconv.Atoi(secret.Name[lastIdx+2:]) 157 | prevVersionDir := filepath.Join(opts.outDir, secret.Name[:lastIdx+2]+strconv.Itoa(version-1)) 158 | if _, err := os.Stat(prevVersionDir); !os.IsNotExist(err) { 159 | os.RemoveAll(prevVersionDir) 160 | } 161 | } 162 | 163 | // Creating `Chart.yaml` 164 | { 165 | mb, err := yaml.JSONToYAML(chart.Chart.Metadata) 166 | if err != nil { 167 | return err 168 | } 169 | 170 | f, err := os.OpenFile(filepath.Join(rootDir, "Chart.yaml"), os.O_WRONLY|os.O_CREATE, 0644) 171 | if err != nil { 172 | return err 173 | } 174 | defer f.Close() 175 | 176 | f.Write(mb) 177 | f.Close() 178 | } 179 | 180 | // Creating `values.yaml` 181 | { 182 | yb, err := yaml.JSONToYAML(chart.Chart.Values) 183 | if err != nil { 184 | fmt.Printf("err: %v\n", err) 185 | return err 186 | } 187 | 188 | f, err := os.OpenFile(filepath.Join(rootDir, "values.yaml"), os.O_WRONLY|os.O_CREATE, 0644) 189 | if err != nil { 190 | return err 191 | } 192 | defer f.Close() 193 | 194 | f.Write(yb) 195 | f.Close() 196 | } 197 | 198 | for _, tmpl := range chart.Chart.Templates { 199 | os.MkdirAll(filepath.Join(rootDir, filepath.Dir(tmpl.Name)), os.ModePerm) 200 | b, _ := base64.StdEncoding.DecodeString(tmpl.Data) 201 | fileName := filepath.Join(rootDir, tmpl.Name) 202 | f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0644) 203 | if err != nil { 204 | return err 205 | } 206 | defer f.Close() 207 | 208 | f.Write(b) 209 | f.Close() 210 | } 211 | 212 | for _, tmpl := range chart.Chart.Files { 213 | os.MkdirAll(filepath.Join(rootDir, filepath.Dir(tmpl.Name)), os.ModePerm) 214 | b, _ := base64.StdEncoding.DecodeString(tmpl.Data) 215 | fileName := filepath.Join(rootDir, tmpl.Name) 216 | f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0644) 217 | if err != nil { 218 | return err 219 | } 220 | defer f.Close() 221 | 222 | f.Write(b) 223 | f.Close() 224 | } 225 | 226 | secrets.Items = secrets.Items[1:] 227 | } 228 | return nil 229 | } 230 | 231 | func base64Decode(v []byte) ([]byte, error) { 232 | b64 := make([]byte, base64.StdEncoding.DecodedLen(len(v))) 233 | n, err := base64.StdEncoding.Decode(b64, v) 234 | if err != nil { 235 | return nil, err 236 | } 237 | return b64[:n], nil 238 | } 239 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 5 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= 7 | github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 8 | github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= 9 | github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= 10 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 11 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 12 | github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= 13 | github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= 14 | github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= 15 | github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= 16 | github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= 17 | github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 18 | github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= 19 | github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 20 | github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= 21 | github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= 22 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 23 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 24 | github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= 25 | github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= 26 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 27 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 28 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 29 | github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= 30 | github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= 31 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 32 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 33 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 34 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 35 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 36 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 37 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 38 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 39 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 40 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 41 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 42 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 43 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 44 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 45 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 46 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 47 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 48 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 49 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 50 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 51 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 52 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= 53 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 54 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= 55 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 56 | github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= 57 | github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= 58 | github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= 59 | github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= 60 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 61 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 62 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 63 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 64 | github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 65 | github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= 66 | github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= 67 | github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 68 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 69 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 70 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 71 | github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= 72 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 73 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 74 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 75 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 76 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 77 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 78 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 79 | github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 80 | github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= 81 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 82 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 83 | go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= 84 | go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= 85 | go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= 86 | go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= 87 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 88 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 89 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 90 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 91 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 92 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 93 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 94 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 95 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 96 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 97 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 98 | golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= 99 | golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= 100 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 101 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 102 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 103 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 104 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 105 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 106 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 107 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 108 | golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= 109 | golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 110 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 111 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 112 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 113 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 114 | golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= 115 | golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 116 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 117 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 118 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 119 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 120 | golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= 121 | golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 122 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 123 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 124 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 125 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 126 | google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= 127 | google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 128 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 129 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 130 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 131 | gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= 132 | gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= 133 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 134 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 135 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 136 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 137 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 138 | k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= 139 | k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= 140 | k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= 141 | k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= 142 | k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= 143 | k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= 144 | k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= 145 | k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= 146 | k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= 147 | k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= 148 | k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= 149 | k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 150 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= 151 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= 152 | sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= 153 | sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= 154 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= 155 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= 156 | sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= 157 | sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= 158 | --------------------------------------------------------------------------------