[
  {
    "path": ".github/workflows/build.yaml",
    "content": "# This workflow is triggered on push or pull request for the master branch.\n# It runs tests and various checks to validate that the proposed changes\n# will not introduce any regression after merging the code to the master branch.\nname: build\non:\n  push:\n    branches:\n      - master\n    paths-ignore:\n      - '*.md'\n  pull_request:\n    branches:\n      - master\n    paths-ignore:\n      - '*.md'\npermissions:\n  contents: read\nenv:\n  GO_VERSION: \"1.17\"\njobs:\n  lint:\n    name: Run linter\n    runs-on: ubuntu-18.04\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Run linter\n        run: make lint\n  test:\n    name: Run tests\n    runs-on: ubuntu-18.04\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Run tests\n        run: make test\n  release-snapshot:\n    name: Release unversioned snapshot\n    needs:\n      - lint\n      - test\n    runs-on: ubuntu-18.04\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Release\n        run: make release-snapshot\n"
  },
  {
    "path": ".github/workflows/release.yaml",
    "content": "# This workflow is triggered on new tags.\n# It runs tests to validate that the code is working before publishing a new\n# version for plugin \"lineage\" in krew-index.\nname: release\non:\n  push:\n    tags:\n    - 'v*.*.*'\nenv:\n  GO_VERSION: \"1.17\"\njobs:\n  lint:\n    name: Run linter\n    runs-on: ubuntu-18.04\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Run linter\n        run: make lint\n  test:\n    name: Run tests\n    runs-on: ubuntu-18.04\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Run tests\n        run: make test\n  release:\n    name: Release\n    runs-on: ubuntu-18.04\n    permissions:\n      contents: write\n    steps:\n      - name: Setup Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - name: Checkout code\n        uses: actions/checkout@v2\n      - uses: actions/cache@v2\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n      - name: Release\n        run: make release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          KREW_GITHUB_TOKEN: ${{ secrets.KREW_GITHUB_TOKEN }}\n      - name: Update new version for plugin \"lineage\" in krew-index\n        uses: rajatjindal/krew-release-bot@v0.0.40\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Output of the GoReleaser tool\ndist/\n\n# Binaries for make targets, downloaded via fetch.sh script\nbin/\n\n# GoLand IDEA\n/.idea/\n*.iml\n\n# VS Code\n.vscode\n\n# Emacs\n*~\n\\#*\\#\n\n# Miscellaneous files\n*.sw[op]\n*.DS_Store\n"
  },
  {
    "path": ".golangci.yaml",
    "content": "run:\n  deadline: 5m\nlinters:\n  enable-all: true\n  disable:\n    - golint           # deprecated\n    - interfacer       # deprecated\n    - maligned         # deprecated\n    - scopelint        # deprecated\n    - cyclop           # duplicate of gocyclo\n    - rowserrcheck     # exclude 'sql' preset\n    - sqlclosecheck    # exclude 'sql' preset\n    - exhaustivestruct\n    - gochecknoglobals\n    - goconst\n    - godox\n    - goerr113\n    - gomnd\n    - gomoddirectives\n    - lll\n    - nlreturn\n    - prealloc\n    - wrapcheck\n    - wsl\nlinters-settings:\n  depguard:\n    list-type: blacklist\n    include-go-root: true\n    packages:\n      - errors\n      - io/ioutil\n      - sync/atomic\n      - github.com/pkg/errors\n      - github.com/stretchr/testify/assert\n      - gotest.tools/v3\n    packages-with-error-message:\n      - errors: \"Use github.com/cockroachdb/errors instead.\"\n      - io/ioutil: \"The 'io/ioutil' package is deprecated. Use corresponding 'os' or 'io' functions instead.\"\n      - sync/atomic: \"Use go.uber.org/atomic instead.\"\n      - github.com/pkg/errors: \"Use github.com/cockroachdb/errors instead.\"\n      - github.com/stretchr/testify/assert: \"Use github.com/stretchr/testify/require instead.\"\n      - gotest.tools/v3: \"Use github.com/stretchr/testify instead.\"\n  gci:\n    local-prefixes: github.com/tohjustin/kube-lineage\n"
  },
  {
    "path": ".goreleaser.yaml",
    "content": "project_name: kube-lineage\nbefore:\n  hooks:\n    - go mod tidy\nbuilds:\n  - binary: kube-lineage\n    main: ./cmd/kube-lineage\n    goos:\n      - darwin\n      - linux\n      - windows\n    goarch:\n      - amd64\n      - arm64\n    ignore:\n      - goos: windows\n        goarch: arm64\n    env:\n      - CGO_ENABLED=0\n    ldflags:\n      - -s\n      - -w\n      - -X github.com/tohjustin/kube-lineage/internal/version.buildDate={{ .Env.BUILD_DATE }}\n      - -X github.com/tohjustin/kube-lineage/internal/version.gitCommit={{ .Env.GIT_COMMIT }}\n      - -X github.com/tohjustin/kube-lineage/internal/version.gitTreeState={{ .Env.GIT_TREE_STATE }}\n      - -X github.com/tohjustin/kube-lineage/internal/version.gitVersion={{ .Env.GIT_VERSION }}\n      - -X github.com/tohjustin/kube-lineage/internal/version.gitVersionMajor={{ .Env.GIT_VERSION_MAJOR }}\n      - -X github.com/tohjustin/kube-lineage/internal/version.gitVersionMinor={{ .Env.GIT_VERSION_MINOR }}\narchives:\n  - files:\n      - LICENSE.md\n      - README.md\n    format_overrides:\n      - goos: windows\n        format: zip\n    name_template: \"{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}\"\n    wrap_in_directory: false\nchecksum:\n  name_template: checksums.txt\nsnapshot:\n  name_template: \"{{ .Tag }}-next\"\nchangelog:\n  sort: asc\n  filters:\n    exclude:\n      - \"^build(\\\\(.+\\\\))?:\"\n      - \"^chore(\\\\(.+\\\\))?:\"\n      - \"^ci(\\\\(.+\\\\))?:\"\n      - \"^docs(\\\\(.+\\\\))?:\"\n      - \"^perf(\\\\(.+\\\\))?:\"\n      - \"^refactor(\\\\(.+\\\\))?:\"\n      - \"^style(\\\\(.+\\\\))?:\"\n      - \"^test(\\\\(.+\\\\))?:\"\nkrews:\n  - name: lineage\n    index:\n      owner: tohjustin\n      name: kubectl-plugins\n      branch: master\n      token: \"{{ .Env.KREW_GITHUB_TOKEN }}\"\n    url_template: \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .Tag }}/{{ .ArtifactName }}\"\n    commit_author:\n      name: Justin Toh\n      email: tohjustin@hotmail.com\n    commit_msg_template: \"Krew plugin update for {{ .ProjectName }} version {{ .Tag }}\"\n    homepage: https://github.com/tohjustin/kube-lineage\n    short_description: Display all dependent resources or resource dependencies\n    description: |\n      This plugin prints a table of dependencies or dependents of the specified\n      resource.\n    caveats: |\n      The tool only shows dependencies or dependents among the resources you have\n      access to. So for restricted users, the result may be incomplete.\n"
  },
  {
    "path": ".krew.yaml",
    "content": "apiVersion: krew.googlecontainertools.github.com/v1alpha2\nkind: Plugin\nmetadata:\n  name: lineage\nspec:\n  version: {{ .TagName }}\n  homepage: https://github.com/tohjustin/kube-lineage\n  shortDescription: Display all dependent resources or resource dependencies\n  description: |\n    This plugin prints a table of dependencies or dependents of the specified\n    resource.\n  caveats: |\n    The tool only shows dependencies or dependents among the resources you have\n    access to. So for restricted users, the result may be incomplete.\n  platforms:\n  - selector:\n      matchLabels:\n        os: darwin\n        arch: amd64\n    {{addURIAndSha \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .TagName }}/kube-lineage_darwin_amd64.tar.gz\" .TagName }}\n    bin: kube-lineage\n  - selector:\n      matchLabels:\n        os: darwin\n        arch: arm64\n    {{addURIAndSha \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .TagName }}/kube-lineage_darwin_arm64.tar.gz\" .TagName }}\n    bin: kube-lineage\n  - selector:\n      matchLabels:\n        os: linux\n        arch: amd64\n    {{addURIAndSha \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .TagName }}/kube-lineage_linux_amd64.tar.gz\" .TagName }}\n    bin: kube-lineage\n  - selector:\n      matchLabels:\n        os: linux\n        arch: arm64\n    {{addURIAndSha \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .TagName }}/kube-lineage_linux_arm64.tar.gz\" .TagName }}\n    bin: kube-lineage\n  - selector:\n      matchLabels:\n        os: windows\n        arch: amd64\n    {{addURIAndSha \"https://github.com/tohjustin/kube-lineage/releases/download/{{ .TagName }}/kube-lineage_windows_amd64.zip\" .TagName }}\n    bin: kube-lineage.exe\n"
  },
  {
    "path": "LICENSE.md",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Makefile",
    "content": "SHELL:=/bin/bash\n\nGO_VERSION = \"1.17\"\nGOLANGCI_LINT_VERSION = \"1.42.1\"\nGORELEASER_VERSION = \"1.0.0\"\n\nexport BUILD_DATE = $(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\")\nexport GIT_COMMIT = $(shell git rev-parse HEAD)\nexport GIT_TREE_STATE = $(shell if [ -z \"`git status --porcelain`\" ]; then echo \"clean\" ; else echo \"dirty\"; fi)\nexport GIT_VERSION = $(shell git describe --tags --always | grep -E '^v[0-9]+\\.[0-9]+\\.[0-9]+(-.*)?')\nexport GIT_VERSION_MAJOR = $(shell if [[ \"${GIT_VERSION}\" ]]; then echo ${GIT_VERSION} | cut -d 'v' -f 2 | cut -d \".\" -f 1 ; fi)\nexport GIT_VERSION_MINOR = $(shell if [[ \"${GIT_VERSION}\" ]]; then echo ${GIT_VERSION} | cut -d 'v' -f 2 | cut -d \".\" -f 2 ; fi)\nexport CGO_ENABLED = 1\n\nREPO = $(shell go list -m)\nGO_BUILD_ARGS = \\\n  -gcflags \"all=-trimpath=$(shell dirname $(shell pwd))\" \\\n  -asmflags \"all=-trimpath=$(shell dirname $(shell pwd))\" \\\n  -ldflags \" \\\n    -s \\\n    -w \\\n    -X '$(REPO)/internal/version.buildDate=$(BUILD_DATE)' \\\n    -X '$(REPO)/internal/version.gitCommit=$(GIT_COMMIT)' \\\n    -X '$(REPO)/internal/version.gitTreeState=$(GIT_TREE_STATE)' \\\n    -X '$(REPO)/internal/version.gitVersion=$(GIT_VERSION)' \\\n    -X '$(REPO)/internal/version.gitVersionMajor=$(GIT_VERSION_MAJOR)' \\\n    -X '$(REPO)/internal/version.gitVersionMinor=$(GIT_VERSION_MINOR)' \\\n  \" \\\n\n.PHONY: all\nall: install\n\n.PHONY: clean\nclean:\n\trm -rf bin dist\n\n.PHONY: lint\nlint:\n\tsource ./scripts/fetch.sh; fetch golangci-lint $(GOLANGCI_LINT_VERSION) && ./bin/golangci-lint run\n\n.PHONY: test\ntest:\n\tgo test ./...\n\n.PHONY: build\nbuild:\n\tgo build $(GO_BUILD_ARGS) -o bin/kube-lineage ./cmd/kube-lineage\n\n.PHONY: install\ninstall: build\n\tinstall bin/kube-lineage $(shell go env GOPATH)/bin\n\n.PHONY: release\nRELEASE_ARGS?=release --rm-dist\nrelease:\n\tsource ./scripts/fetch.sh; fetch goreleaser $(GORELEASER_VERSION) && ./bin/goreleaser $(RELEASE_ARGS)\n\n.PHONY: release-snapshot\nRELEASE_SNAPSHOT_ARGS?=release --rm-dist --skip-publish --snapshot\nrelease-snapshot:\n\tsource ./scripts/fetch.sh; fetch goreleaser $(GORELEASER_VERSION) && ./bin/goreleaser $(RELEASE_SNAPSHOT_ARGS)\n"
  },
  {
    "path": "README.md",
    "content": "# kube-lineage\n\n[![build](https://github.com/tohjustin/kube-lineage/actions/workflows/build.yaml/badge.svg)](https://github.com/tohjustin/kube-lineage/actions/workflows/build.yaml)\n[![release](https://aegisbadges.appspot.com/static?subject=release&status=v0.5.0&color=318FE0)](https://github.com/tohjustin/kube-lineage/releases)\n[![kubernetes compatibility](https://aegisbadges.appspot.com/static?subject=k8s%20compatibility&status=v1.21%2B&color=318FE0)](https://endoflife.date/kubernetes)\n[![helm compatibility](https://aegisbadges.appspot.com/static?subject=helm%20compatibility&status=v3&color=318FE0)](https://helm.sh/docs/topics/v2_v3_migration)\n[![license](https://aegisbadges.appspot.com/static?subject=license&status=Apache-2.0&color=318FE0)](./LICENSE.md)\n\nA CLI tool to display all dependencies or dependents of an object in a Kubernetes cluster.\n\n## Usage\n\n```shell\n$ kube-lineage clusterrole system:metrics-server --output=wide\nNAMESPACE     NAME                                                               READY   STATUS    AGE   RELATIONSHIPS\n              ClusterRole/system:metrics-server                                  -                 30m   []\n              └── ClusterRoleBinding/system:metrics-server                       -                 30m   [ClusterRoleBindingRole]\nkube-system       └── ServiceAccount/metrics-server                              -                 30m   [ClusterRoleBindingSubject]\nkube-system           ├── Pod/metrics-server-7b4f8b595-8m7rz                     1/1     Running   30m   [PodServiceAccount]\nkube-system           │   └── Service/metrics-server                             -                 30m   [Service]\n                      │       ├── APIService/v1beta1.metrics.k8s.io              True              30m   [APIService]\nkube-system           │       └── EndpointSlice.discovery/metrics-server-wb2cm   -                 30m   [ControllerReference OwnerReference]\nkube-system           └── Secret/metrics-server-token-nqw85                      -                 30m   [ServiceAccountSecret]\nkube-system               └── Pod/metrics-server-7b4f8b595-8m7rz                 1/1     Running   30m   [PodVolume]\n```\n\nUse either the `--dependencies` or `-D` flag to show dependencies instead of dependents\n\n```shell\n$ kube-lineage pod coredns-5cc79d4bf5-xgvkc --dependencies\nNAMESPACE     NAME                                                                   READY   STATUS         AGE\nkube-system   Pod/coredns-5cc79d4bf5-xgvkc                                           1/1     Running        30m\n              ├── Node/k3d-server                                                    True    KubeletReady   30m\n              ├── PodSecurityPolicy/system-unrestricted-psp                          -                      30m\nkube-system   ├── ConfigMap/coredns                                                  -                      30m\nkube-system   ├── ReplicaSet/coredns-5cc79d4bf5                                      1/1                    30m\nkube-system   │   └── Deployment/coredns                                             1/1                    30m\nkube-system   ├── Secret/coredns-token-6vsx4                                         -                      30m\nkube-system   │   └── ServiceAccount/coredns                                         -                      30m\n              │       ├── ClusterRoleBinding/system:basic-user                       -                      30m\n              │       │   └── ClusterRole/system:basic-user                          -                      30m\n              │       ├── ClusterRoleBinding/system:coredns                          -                      30m\n              │       │   └── ClusterRole/system:coredns                             -                      30m\n              │       ├── ClusterRoleBinding/system:discovery                        -                      30m\n              │       │   └── ClusterRole/system:discovery                           -                      30m\n              │       ├── ClusterRoleBinding/system:public-info-viewer               -                      30m\n              │       │   └── ClusterRole/system:public-info-viewer                  -                      30m\nkube-system   │       └── RoleBinding/system-unrestricted-svc-acct-psp-rolebinding   -                      30m\n              │           └── ClusterRole/system-unrestricted-psp-role               -                      30m\n              │               └── PodSecurityPolicy/system-unrestricted-psp          -                      30m\nkube-system   └── ServiceAccount/coredns                                             -                      30m\n```\n\nUse the `helm` subcommand to display Helm release resources & optionally their respective dependents in a Kubernetes cluster.\n\n```shell\n$ kube-lineage helm kube-state-metrics -n monitoring-system\nhelm kube-state-metrics -n monitoring-system\nNAMESPACE           NAME                                                             READY   STATUS     AGE\nmonitoring-system   kube-state-metrics                                               True    Deployed   25m\n                    ├── ClusterRole/kube-state-metrics                               -                  25m\n                    │   └── ClusterRoleBinding/kube-state-metrics                    -                  25m\nmonitoring-system   │       └── ServiceAccount/kube-state-metrics                    -                  25m\nmonitoring-system   │           ├── Pod/kube-state-metrics-7dff544777-jb2q2          1/1     Running    25m\nmonitoring-system   │           │   └── Service/kube-state-metrics                   -                  25m\nmonitoring-system   │           │       └── EndpointSlice/kube-state-metrics-rq8wk   -                  25m\nmonitoring-system   │           └── Secret/kube-state-metrics-token-bsr4q            -                  25m\nmonitoring-system   │               └── Pod/kube-state-metrics-7dff544777-jb2q2      1/1     Running    25m\n                    ├── ClusterRoleBinding/kube-state-metrics                        -                  25m\nmonitoring-system   ├── Deployment/kube-state-metrics                                1/1                25m\nmonitoring-system   │   └── ReplicaSet/kube-state-metrics-7dff544777                 1/1                25m\nmonitoring-system   │       └── Pod/kube-state-metrics-7dff544777-jb2q2              1/1     Running    25m\nmonitoring-system   ├── Secret/sh.helm.release.v1.kube-state-metrics.v1              -                  25m\nmonitoring-system   ├── Service/kube-state-metrics                                   -                  25m\nmonitoring-system   └── ServiceAccount/kube-state-metrics\n\n$ kube-lineage helm traefik --depth 1 --label-columns app.kubernetes.io/managed-by --label-columns owner\nNAMESPACE     NAME                                       READY   STATUS     AGE   MANAGED-BY   OWNER\nkube-system   traefik                                    True    Deployed   30m\n              ├── ClusterRole/traefik                    -                  30m   Helm\n              ├── ClusterRoleBinding/traefik             -                  30m   Helm\nkube-system   ├── ConfigMap/traefik                      -                  30m   Helm\nkube-system   ├── ConfigMap/traefik-test                 -                  30m   Helm\nkube-system   ├── Deployment/traefik                     1/1                30m   Helm\nkube-system   ├── Secret/sh.helm.release.v1.traefik.v1   -                  30m                helm\nkube-system   ├── Secret/traefik-default-cert            -                  30m   Helm\nkube-system   ├── Service/traefik                        -                  30m   Helm\nkube-system   ├── Service/traefik-prometheus             -                  30m   Helm\nkube-system   └── ServiceAccount/traefik                 -                  30m   Helm\n```\n\nUse either the `split` or `split-wide` output format to display resources grouped by their type.\n\n```shell\n$ kube-lineage deploy/coredns --output=split --show-group\nNAME                      READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/coredns   3/3     3            3           30m\n\nNAME                                            ADDRESSTYPE   PORTS        ENDPOINTS                          AGE\nendpointslice.discovery.k8s.io/kube-dns-mz9bw   IPv4          53,9153,53   10.42.0.24,10.42.0.26,10.42.0.27   30m\n\nNAME                           READY   STATUS    RESTARTS   AGE\npod/coredns-5cc79d4bf5-xgvkc   1/1     Running   0          30m\npod/coredns-5cc79d4bf5-rjc7d   1/1     Running   0          30m\npod/coredns-5cc79d4bf5-tt2zl   1/1     Running   0          30m\n\nNAME                                 DESIRED   CURRENT   READY   AGE\nreplicaset.apps/coredns-5cc79d4bf5   3         3         3       30m\n\nNAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE\nservice/kube-dns   ClusterIP   10.43.0.10   <none>        53/UDP,53/TCP,9153/TCP   30m\n```\n\n### Flags\n\nFlags for configuring relationship discovery parameters\n\n| Flag | Description |\n| ---- | ----------- |\n| `--all-namespaces`, `-A` | If present, list object relationships across all namespaces |\n| `--dependencies`, `-D`   | If present, list object dependencies instead of dependents. <br/> Not supported in `helm` subcommand |\n| `--depth`, `-d`          | Maximum depth to find relationships |\n| `--exclude-types`        | Accepts a comma separated list of resource types to exclude from relationship discovery. <br/> You can also use multiple flag options like --exclude-types type1 --exclude-types type2... |\n| `--include-types`        | Accepts a comma separated list of resource types to only include in relationship discovery. <br/> You can also use multiple flag options like --include-types type1 --include-types type2... |\n| `--scopes`, `-S`         | Accepts a comma separated list of additional namespaces to find relationships. <br/> You can also use multiple flag options like -S namespace1 -S namespace2... |\n\nFlags for configuring output format\n\n| Flag | Description |\n| ---- | ----------- |\n| `--output`, `-o`        | Output format. One of: wide \\| split \\| split-wide |\n| `--label-columns`, `-L` | Accepts a comma separated list of labels that are going to be presented as columns. <br/> You can also use multiple flag options like -L label1 -L label2... |\n| `--no-headers`          | When using the default output format, don't print headers |\n| `--show-group`          | If present, include the resource group for the requested object(s) |\n| `--show-label`          | When printing, show all labels as the last column |\n| `--show-namespace`      | When printing, show namespace as the first column |\n\nUse the following commands to view the full list of supported flags\n\n```shell\n$ kube-lineage --help\n$ kube-lineage helm --help\n```\n\n## Supported Relationships\n\nList of supported relationships used for discovering dependent objects:\n\n- Kubernetes\n  - [Controller](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/controller-ref.md) & [Owner](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/) References\n  - Core APIs: [Event](https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/event-v1/), [PersistentVolume](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/), [PersistentVolumeClaim](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/), [Pod](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/), [Service](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/), [ServiceAccount](https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/service-account-v1/)\n  - `policy` APIs: [PodDisruptionBudget](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1), [PodSecurityPolicy](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/)\n  - `admissionregistration.k8s.io` APIs: [MutatingWebhookConfiguration](https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/) & [ValidatingWebhookConfiguration](https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/)\n  - `apiregistration.k8s.io` APIs: [APIService](https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/api-service-v1/)\n  - `networking.k8s.io` APIs: [Ingress](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/), [IngressClass](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-class-v1/), [NetworkPolicy](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/network-policy-v1/)\n  - `node.k8s.io` APIs: [RuntimeClass](https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/runtime-class-v1/)\n  - `rbac.authorization.k8s.io` APIs: [ClusterRole](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/cluster-role-v1/), [ClusterRoleBinding](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/cluster-role-binding-v1/), [Role](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/role-v1/), [RoleBinding](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/role-binding-v1/)\n  - `storage.k8s.io` APIs: [CSINode](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/csi-node-v1/), [CSIStorageCapacity](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/csi-storage-capacity-v1beta1/), [StorageClass](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/storage-class-v1/), [VolumeAttachment](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/volume-attachment-v1/)\n- Helm\n  - [Helm Release](https://helm.sh/docs/intro/using_helm/#three-big-concepts)\n  - [Helm Storage](https://helm.sh/docs/topics/advanced/#storage-backends)\n\n## Installation\n\n### Install via [krew](https://krew.sigs.k8s.io/)\n\n```shell\n$ kubectl krew install lineage\n\n$ kubectl lineage --version\n```\n\n### Install from Source\n\n```shell\n$ git clone git@github.com:tohjustin/kube-lineage.git && cd kube-lineage\n$ make install\n\n$ kube-lineage --version\n```\n\n## Prior Art\n\nkube-lineage has been inspired by the following projects:\n\n- [ahmetb/kubectl-tree](https://github.com/ahmetb/kubectl-tree)\n- [feloy/kubectl-service-tree](https://github.com/feloy/kubectl-service-tree)\n- [nimakaviani/knative-inspect](https://github.com/nimakaviani/knative-inspect/)\n- [steveteuber/kubectl-graph](https://github.com/steveteuber/kubectl-graph)\n"
  },
  {
    "path": "cmd/kube-lineage/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/version\"\n\t\"github.com/tohjustin/kube-lineage/pkg/cmd/helm\"\n\t\"github.com/tohjustin/kube-lineage/pkg/cmd/lineage\"\n)\n\nvar rootCmdName = \"kube-lineage\"\n\n//nolint:gochecknoinits\nfunc init() {\n\t// If executed as a kubectl plugin\n\tif strings.HasPrefix(filepath.Base(os.Args[0]), \"kubectl-\") {\n\t\trootCmdName = \"kubectl lineage\"\n\t}\n}\n\nfunc NewCmd(streams genericclioptions.IOStreams) *cobra.Command {\n\tcmd := lineage.NewCmd(streams, rootCmdName, \"\")\n\tcmd.AddCommand(helm.NewCmd(streams, \"\", rootCmdName))\n\tcmd.SetVersionTemplate(\"{{printf \\\"%s\\\" .Version}}\\n\")\n\tcmd.Version = fmt.Sprintf(\"%#v\", version.Get())\n\treturn cmd\n}\n\nfunc main() {\n\tflags := pflag.NewFlagSet(\"kube-lineage\", pflag.ExitOnError)\n\tpflag.CommandLine = flags\n\n\tstreams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}\n\trootCmd := NewCmd(streams)\n\n\tif err := rootCmd.Execute(); err != nil {\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "cmd/kube-lineage/main_test.go",
    "content": "package main_test\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\n\tkubelineage \"github.com/tohjustin/kube-lineage/cmd/kube-lineage\"\n\t\"github.com/tohjustin/kube-lineage/internal/version\"\n)\n\nfunc runCmd(args ...string) (string, error) {\n\tbuf := bytes.NewBufferString(\"\")\n\tstreams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}\n\tcmd := kubelineage.NewCmd(streams)\n\tcmd.SetOut(buf)\n\n\tcmd.SetArgs(args)\n\tif err := cmd.Execute(); err != nil {\n\t\treturn \"\", err\n\t}\n\tout, err := io.ReadAll(buf)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(out), nil\n}\n\nfunc TestCommandWithVersionFlag(t *testing.T) {\n\tt.Parallel()\n\n\toutput, err := runCmd(\"--version\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to run command: %v\", err)\n\t}\n\n\texpected := fmt.Sprintf(\"%#v\\n\", version.Get())\n\tif output != expected {\n\t\tt.Fatalf(\"expected \\\"%s\\\" got \\\"%s\\\"\", expected, output)\n\t}\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/tohjustin/kube-lineage\n\ngo 1.17\n\nrequire (\n\tgithub.com/spf13/cobra v1.3.0\n\tgithub.com/spf13/pflag v1.0.5\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c\n\thelm.sh/helm/v3 v3.8.0\n\tk8s.io/api v0.23.4\n\tk8s.io/apimachinery v0.23.4\n\tk8s.io/apiserver v0.23.4\n\tk8s.io/cli-runtime v0.23.4\n\tk8s.io/client-go v0.23.4\n\tk8s.io/klog/v2 v2.30.0\n\tk8s.io/kube-aggregator v0.23.4\n\tk8s.io/kubectl v0.23.4\n)\n\nrequire (\n\tcloud.google.com/go v0.99.0 // indirect\n\tgithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect\n\tgithub.com/Azure/go-autorest v14.2.0+incompatible // indirect\n\tgithub.com/Azure/go-autorest/autorest v0.11.20 // indirect\n\tgithub.com/Azure/go-autorest/autorest/adal v0.9.15 // indirect\n\tgithub.com/Azure/go-autorest/autorest/date v0.3.0 // indirect\n\tgithub.com/Azure/go-autorest/logger v0.2.1 // indirect\n\tgithub.com/Azure/go-autorest/tracing v0.6.0 // indirect\n\tgithub.com/BurntSushi/toml v0.4.1 // indirect\n\tgithub.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect\n\tgithub.com/Masterminds/goutils v1.1.1 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.1.1 // indirect\n\tgithub.com/Masterminds/sprig/v3 v3.2.2 // indirect\n\tgithub.com/Masterminds/squirrel v1.5.2 // indirect\n\tgithub.com/PuerkitoBio/purell v1.1.1 // indirect\n\tgithub.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect\n\tgithub.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.1.2 // indirect\n\tgithub.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect\n\tgithub.com/containerd/containerd v1.5.9 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.2.3 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/docker/cli v20.10.11+incompatible // indirect\n\tgithub.com/docker/distribution v2.7.1+incompatible // indirect\n\tgithub.com/docker/docker v20.10.12+incompatible // indirect\n\tgithub.com/docker/docker-credential-helpers v0.6.4 // indirect\n\tgithub.com/docker/go-connections v0.4.0 // indirect\n\tgithub.com/docker/go-metrics v0.0.1 // indirect\n\tgithub.com/docker/go-units v0.4.0 // indirect\n\tgithub.com/evanphx/json-patch v4.12.0+incompatible // indirect\n\tgithub.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect\n\tgithub.com/fatih/color v1.13.0 // indirect\n\tgithub.com/fvbommel/sortorder v1.0.1 // indirect\n\tgithub.com/go-errors/errors v1.0.1 // indirect\n\tgithub.com/go-logr/logr v1.2.0 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.19.5 // indirect\n\tgithub.com/go-openapi/jsonreference v0.19.5 // indirect\n\tgithub.com/go-openapi/swag v0.19.14 // indirect\n\tgithub.com/gobwas/glob v0.2.3 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang-jwt/jwt/v4 v4.0.0 // indirect\n\tgithub.com/golang/protobuf v1.5.2 // indirect\n\tgithub.com/google/btree v1.0.1 // indirect\n\tgithub.com/google/go-cmp v0.5.6 // indirect\n\tgithub.com/google/gofuzz v1.1.0 // indirect\n\tgithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect\n\tgithub.com/google/uuid v1.2.0 // indirect\n\tgithub.com/googleapis/gnostic v0.5.5 // indirect\n\tgithub.com/gorilla/mux v1.8.0 // indirect\n\tgithub.com/gosuri/uitable v0.0.4 // indirect\n\tgithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect\n\tgithub.com/huandu/xstrings v1.3.2 // indirect\n\tgithub.com/imdario/mergo v0.3.12 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.0.0 // indirect\n\tgithub.com/jmoiron/sqlx v1.3.4 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/compress v1.13.6 // indirect\n\tgithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect\n\tgithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect\n\tgithub.com/lib/pq v1.10.4 // indirect\n\tgithub.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect\n\tgithub.com/mailru/easyjson v0.7.6 // indirect\n\tgithub.com/mattn/go-colorable v0.1.12 // indirect\n\tgithub.com/mattn/go-isatty v0.0.14 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.9 // indirect\n\tgithub.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect\n\tgithub.com/mitchellh/copystructure v1.2.0 // indirect\n\tgithub.com/mitchellh/go-wordwrap v1.0.0 // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.2 // indirect\n\tgithub.com/moby/locker v1.0.1 // indirect\n\tgithub.com/moby/spdystream v0.2.0 // indirect\n\tgithub.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.2 // indirect\n\tgithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect\n\tgithub.com/morikuni/aec v1.0.0 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.0.2 // indirect\n\tgithub.com/peterbourgon/diskv v2.0.1+incompatible // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_golang v1.11.0 // indirect\n\tgithub.com/prometheus/client_model v0.2.0 // indirect\n\tgithub.com/prometheus/common v0.28.0 // indirect\n\tgithub.com/prometheus/procfs v0.6.0 // indirect\n\tgithub.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc // indirect\n\tgithub.com/russross/blackfriday v1.5.2 // indirect\n\tgithub.com/shopspring/decimal v1.2.0 // indirect\n\tgithub.com/sirupsen/logrus v1.8.1 // indirect\n\tgithub.com/spf13/cast v1.4.1 // indirect\n\tgithub.com/stretchr/testify v1.7.0 // indirect\n\tgithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect\n\tgithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect\n\tgithub.com/xeipuuv/gojsonschema v1.2.0 // indirect\n\tgithub.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect\n\tgo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect\n\tgolang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect\n\tgolang.org/x/net v0.0.0-20220107192237-5cfca573fb4d // indirect\n\tgolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect\n\tgolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect\n\tgolang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgolang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 // indirect\n\tgoogle.golang.org/grpc v1.43.0 // indirect\n\tgoogle.golang.org/protobuf v1.27.1 // indirect\n\tgopkg.in/gorp.v1 v1.7.2 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect\n\tk8s.io/apiextensions-apiserver v0.23.4 // indirect\n\tk8s.io/component-base v0.23.4 // indirect\n\tk8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect\n\tk8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect\n\toras.land/oras-go v1.1.0 // indirect\n\tsigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect\n\tsigs.k8s.io/kustomize/api v0.10.1 // indirect\n\tsigs.k8s.io/kustomize/kyaml v0.13.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect\n\tsigs.k8s.io/yaml v1.3.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=\ncloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=\ncloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=\ngithub.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=\ngithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=\ngithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=\ngithub.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=\ngithub.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=\ngithub.com/Azure/go-autorest/autorest v0.11.20 h1:s8H1PbCZSqg/DH7JMlOz6YMig6htWLNPsjDdlLqCx3M=\ngithub.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.15 h1:X+p2GF0GWyOiSmqohIaEeuNFNDY4I4EOlVuUQvFdWMk=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=\ngithub.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=\ngithub.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=\ngithub.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=\ngithub.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=\ngithub.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=\ngithub.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=\ngithub.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=\ngithub.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=\ngithub.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=\ngithub.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=\ngithub.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=\ngithub.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=\ngithub.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=\ngithub.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=\ngithub.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=\ngithub.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=\ngithub.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=\ngithub.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=\ngithub.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE=\ngithub.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=\ngithub.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=\ngithub.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=\ngithub.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=\ngithub.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=\ngithub.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=\ngithub.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=\ngithub.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=\ngithub.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=\ngithub.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=\ngithub.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=\ngithub.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=\ngithub.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=\ngithub.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=\ngithub.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=\ngithub.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=\ngithub.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=\ngithub.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=\ngithub.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=\ngithub.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=\ngithub.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=\ngithub.com/Microsoft/hcsshim v0.9.1 h1:VfDCj+QnY19ktX5TsH22JHcjaZ05RWQiwDbOyEg5ziM=\ngithub.com/Microsoft/hcsshim v0.9.1/go.mod h1:Y/0uV2jUab5kBI7SQgl62at0AVX7uaruzADAVmxm3eM=\ngithub.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=\ngithub.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=\ngithub.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=\ngithub.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=\ngithub.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=\ngithub.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=\ngithub.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=\ngithub.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=\ngithub.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=\ngithub.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=\ngithub.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=\ngithub.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=\ngithub.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=\ngithub.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=\ngithub.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=\ngithub.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=\ngithub.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=\ngithub.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=\ngithub.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=\ngithub.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=\ngithub.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=\ngithub.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=\ngithub.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=\ngithub.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=\ngithub.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=\ngithub.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=\ngithub.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=\ngithub.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=\ngithub.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=\ngithub.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=\ngithub.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=\ngithub.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=\ngithub.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=\ngithub.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=\ngithub.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=\ngithub.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=\ngithub.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=\ngithub.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=\ngithub.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=\ngithub.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=\ngithub.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=\ngithub.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=\ngithub.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=\ngithub.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=\ngithub.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=\ngithub.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=\ngithub.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=\ngithub.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=\ngithub.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=\ngithub.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=\ngithub.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=\ngithub.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=\ngithub.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=\ngithub.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=\ngithub.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=\ngithub.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=\ngithub.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=\ngithub.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=\ngithub.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=\ngithub.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=\ngithub.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=\ngithub.com/containerd/cgroups v1.0.2 h1:mZBclaSgNDfPWtfhj2xJY28LZ9nYIgzB0pwSURPl6JM=\ngithub.com/containerd/cgroups v1.0.2/go.mod h1:qpbpJ1jmlqsR9f2IyaLPsdkCdnt0rbDVqIDlhuu5tRY=\ngithub.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=\ngithub.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=\ngithub.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=\ngithub.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=\ngithub.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=\ngithub.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=\ngithub.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=\ngithub.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=\ngithub.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=\ngithub.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=\ngithub.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=\ngithub.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=\ngithub.com/containerd/containerd v1.5.9 h1:rs6Xg1gtIxaeyG+Smsb/0xaSDu1VgFhOCKBXxMxbsF4=\ngithub.com/containerd/containerd v1.5.9/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ=\ngithub.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=\ngithub.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=\ngithub.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=\ngithub.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=\ngithub.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=\ngithub.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=\ngithub.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=\ngithub.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=\ngithub.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=\ngithub.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=\ngithub.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=\ngithub.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=\ngithub.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=\ngithub.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=\ngithub.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=\ngithub.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=\ngithub.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=\ngithub.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=\ngithub.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=\ngithub.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=\ngithub.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=\ngithub.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=\ngithub.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=\ngithub.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=\ngithub.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=\ngithub.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=\ngithub.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=\ngithub.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=\ngithub.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=\ngithub.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=\ngithub.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=\ngithub.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=\ngithub.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=\ngithub.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=\ngithub.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=\ngithub.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=\ngithub.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=\ngithub.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=\ngithub.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=\ngithub.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=\ngithub.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=\ngithub.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=\ngithub.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=\ngithub.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=\ngithub.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=\ngithub.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=\ngithub.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=\ngithub.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=\ngithub.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=\ngithub.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=\ngithub.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=\ngithub.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=\ngithub.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=\ngithub.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=\ngithub.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=\ngithub.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=\ngithub.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=\ngithub.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=\ngithub.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=\ngithub.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=\ngithub.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=\ngithub.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=\ngithub.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=\ngithub.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=\ngithub.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=\ngithub.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684 h1:DBZ2sN7CK6dgvHVpQsQj4sRMCbWTmd17l+5SUCjnQSY=\ngithub.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684/go.mod h1:UfCu3YXJJCI+IdnqGgYP82dk2+Joxmv+mUTVBES6wac=\ngithub.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=\ngithub.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc=\ngithub.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=\ngithub.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=\ngithub.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=\ngithub.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=\ngithub.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=\ngithub.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=\ngithub.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=\ngithub.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=\ngithub.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=\ngithub.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=\ngithub.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=\ngithub.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=\ngithub.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=\ngithub.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=\ngithub.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=\ngithub.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=\ngithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=\ngithub.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=\ngithub.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=\ngithub.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=\ngithub.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=\ngithub.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=\ngithub.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=\ngithub.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=\ngithub.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=\ngithub.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=\ngithub.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=\ngithub.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=\ngithub.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=\ngithub.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=\ngithub.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=\ngithub.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=\ngithub.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=\ngithub.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=\ngithub.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=\ngithub.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=\ngithub.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=\ngithub.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=\ngithub.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=\ngithub.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=\ngithub.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=\ngithub.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=\ngithub.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=\ngithub.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=\ngithub.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=\ngithub.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=\ngithub.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=\ngithub.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=\ngithub.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=\ngithub.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=\ngithub.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=\ngithub.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=\ngithub.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=\ngithub.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=\ngithub.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=\ngithub.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=\ngithub.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=\ngithub.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=\ngithub.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=\ngithub.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=\ngithub.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=\ngithub.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=\ngithub.com/gobuffalo/packr/v2 v2.8.1 h1:tkQpju6i3EtMXJ9uoF5GT6kB+LMTimDWD8Xvbz6zDVA=\ngithub.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=\ngithub.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=\ngithub.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=\ngithub.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=\ngithub.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=\ngithub.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=\ngithub.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=\ngithub.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o=\ngithub.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=\ngithub.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=\ngithub.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=\ngithub.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=\ngithub.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=\ngithub.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=\ngithub.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w=\ngithub.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=\ngithub.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=\ngithub.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=\ngithub.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=\ngithub.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=\ngithub.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=\ngithub.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=\ngithub.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=\ngithub.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=\ngithub.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=\ngithub.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=\ngithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=\ngithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=\ngithub.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=\ngithub.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=\ngithub.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=\ngithub.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=\ngithub.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=\ngithub.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=\ngithub.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=\ngithub.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=\ngithub.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=\ngithub.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=\ngithub.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=\ngithub.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=\ngithub.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=\ngithub.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=\ngithub.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=\ngithub.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=\ngithub.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=\ngithub.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=\ngithub.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=\ngithub.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=\ngithub.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=\ngithub.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=\ngithub.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/karrick/godirwalk v1.15.8 h1:7+rWAZPn9zuRxaIqqT8Ohs2Q2Ac0msBqwRdxNCr2VVs=\ngithub.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=\ngithub.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=\ngithub.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=\ngithub.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=\ngithub.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=\ngithub.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=\ngithub.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=\ngithub.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=\ngithub.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=\ngithub.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=\ngithub.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=\ngithub.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=\ngithub.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=\ngithub.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=\ngithub.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=\ngithub.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=\ngithub.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=\ngithub.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=\ngithub.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=\ngithub.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=\ngithub.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=\ngithub.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=\ngithub.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=\ngithub.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=\ngithub.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=\ngithub.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=\ngithub.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=\ngithub.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=\ngithub.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=\ngithub.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=\ngithub.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=\ngithub.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=\ngithub.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=\ngithub.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=\ngithub.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=\ngithub.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=\ngithub.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=\ngithub.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=\ngithub.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=\ngithub.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=\ngithub.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=\ngithub.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=\ngithub.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=\ngithub.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=\ngithub.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=\ngithub.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=\ngithub.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=\ngithub.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=\ngithub.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=\ngithub.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=\ngithub.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=\ngithub.com/moby/term v0.0.0-20210610120745-9d4ed1856297 h1:yH0SvLzcbZxcJXho2yh7CqdENGMQe73Cw3woZBpPli0=\ngithub.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=\ngithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=\ngithub.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=\ngithub.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=\ngithub.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=\ngithub.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=\ngithub.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=\ngithub.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=\ngithub.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=\ngithub.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=\ngithub.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=\ngithub.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=\ngithub.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=\ngithub.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=\ngithub.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=\ngithub.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=\ngithub.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=\ngithub.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=\ngithub.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=\ngithub.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=\ngithub.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=\ngithub.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=\ngithub.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=\ngithub.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=\ngithub.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=\ngithub.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=\ngithub.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=\ngithub.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=\ngithub.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=\ngithub.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=\ngithub.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=\ngithub.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=\ngithub.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=\ngithub.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=\ngithub.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=\ngithub.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=\ngithub.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3mEw=\ngithub.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=\ngithub.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=\ngithub.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\ngithub.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc h1:BD7uZqkN8CpjJtN/tScAKiccBikU4dlqe/gNrkRaPY4=\ngithub.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=\ngithub.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=\ngithub.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=\ngithub.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=\ngithub.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=\ngithub.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=\ngithub.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=\ngithub.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=\ngithub.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=\ngithub.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=\ngithub.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=\ngithub.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=\ngithub.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=\ngithub.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=\ngithub.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=\ngithub.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=\ngithub.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=\ngithub.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=\ngithub.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=\ngithub.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=\ngithub.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=\ngithub.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=\ngithub.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=\ngithub.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=\ngithub.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=\ngithub.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=\ngithub.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=\ngithub.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=\ngithub.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=\ngithub.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=\ngithub.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=\ngithub.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=\ngithub.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=\ngithub.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=\ngithub.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=\ngithub.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=\ngithub.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=\ngithub.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=\ngithub.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=\ngithub.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=\ngithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=\ngithub.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=\ngithub.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=\ngithub.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=\ngithub.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=\ngithub.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=\ngithub.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=\ngithub.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=\ngo.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=\ngo.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=\ngo.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=\ngo.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=\ngo.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=\ngo.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=\ngo.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=\ngo.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=\ngo.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=\ngo.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=\ngo.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=\ngo.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=\ngo.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=\ngo.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=\ngo.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=\ngo.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=\ngo.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=\ngo.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=\ngo.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=\ngo.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=\ngo.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=\ngo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=\ngo.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=\ngo.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=\ngo.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=\ngolang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=\ngolang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220107192237-5cfca573fb4d h1:62NvYBuaanGXR2ZOfwDFkhhl6X1DUgf8qg3GuQvxZsE=\ngolang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=\ngolang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=\ngolang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=\ngoogle.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=\ngoogle.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=\ngopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=\ngopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=\ngopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=\ngopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=\ngotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=\ngotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=\ngotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=\ngotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=\nhelm.sh/helm/v3 v3.8.0 h1:vlQQDDQkrH4NECOFbGcwjjKyHL5Sa3xNLjMxXm7fMVo=\nhelm.sh/helm/v3 v3.8.0/go.mod h1:0nYPSuvuj8TTJDLRSAfbzGGbazPZsayaDpP8s9FfZT8=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nk8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=\nk8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=\nk8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=\nk8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo=\nk8s.io/api v0.23.4 h1:85gnfXQOWbJa1SiWGpE9EEtHs0UVvDyIsSMpEtl2D4E=\nk8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI=\nk8s.io/apiextensions-apiserver v0.23.1/go.mod h1:0qz4fPaHHsVhRApbtk3MGXNn2Q9M/cVWWhfHdY2SxiM=\nk8s.io/apiextensions-apiserver v0.23.4 h1:AFDUEu/yEf0YnuZhqhIFhPLPhhcQQVuR1u3WCh0rveU=\nk8s.io/apiextensions-apiserver v0.23.4/go.mod h1:TWYAKymJx7nLMxWCgWm2RYGXHrGlVZnxIlGnvtfYu+g=\nk8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=\nk8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=\nk8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=\nk8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno=\nk8s.io/apimachinery v0.23.4 h1:fhnuMd/xUL3Cjfl64j5ULKZ1/J9n8NuQEgNL+WXWfdM=\nk8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=\nk8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=\nk8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=\nk8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=\nk8s.io/apiserver v0.23.1/go.mod h1:Bqt0gWbeM2NefS8CjWswwd2VNAKN6lUKR85Ft4gippY=\nk8s.io/apiserver v0.23.4 h1:zNvQlG+C/ERjuUz4p7eY/0IWHaMixRSBoxgmyIdwo9Y=\nk8s.io/apiserver v0.23.4/go.mod h1:A6l/ZcNtxGfPSqbFDoxxOjEjSKBaQmE+UTveOmMkpNc=\nk8s.io/cli-runtime v0.23.1/go.mod h1:r9r8H/qfXo9w+69vwUL7LokKlLRKW5D6A8vUKCx+YL0=\nk8s.io/cli-runtime v0.23.4 h1:C3AFQmo4TK4dlVPLOI62gtHEHu0OfA2Cp4UVRZ1JXns=\nk8s.io/cli-runtime v0.23.4/go.mod h1:7KywUNTUibmHPqmpDFuRO1kc9RhsufHv2lkjCm2YZyM=\nk8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=\nk8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=\nk8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=\nk8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0=\nk8s.io/client-go v0.23.4 h1:YVWvPeerA2gpUudLelvsolzH7c2sFoXXR5wM/sWqNFU=\nk8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0=\nk8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=\nk8s.io/code-generator v0.23.1/go.mod h1:V7yn6VNTCWW8GqodYCESVo95fuiEg713S8B7WacWZDA=\nk8s.io/code-generator v0.23.4/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=\nk8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=\nk8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=\nk8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=\nk8s.io/component-base v0.23.1/go.mod h1:6llmap8QtJIXGDd4uIWJhAq0Op8AtQo6bDW2RrNMTeo=\nk8s.io/component-base v0.23.4 h1:SziYh48+QKxK+ykJ3Ejqd98XdZIseVBG7sBaNLPqy6M=\nk8s.io/component-base v0.23.4/go.mod h1:8o3Gg8i2vnUXGPOwciiYlkSaZT+p+7gA9Scoz8y4W4E=\nk8s.io/component-helpers v0.23.1/go.mod h1:ZK24U+2oXnBPcas2KolLigVVN9g5zOzaHLkHiQMFGr0=\nk8s.io/component-helpers v0.23.4/go.mod h1:1Pl7L4zukZ054ElzRbvmZ1FJIU8roBXFOeRFu8zipa4=\nk8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=\nk8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=\nk8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=\nk8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=\nk8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=\nk8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=\nk8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=\nk8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=\nk8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=\nk8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=\nk8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=\nk8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=\nk8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=\nk8s.io/kube-aggregator v0.23.4 h1:gLk78rGLVfUXCdD14NrKg/JFBmNNCZ8FEs3tYt+W6Zk=\nk8s.io/kube-aggregator v0.23.4/go.mod h1:hpmPi4oaLBe014CkBCqzBYWok64H2C7Ka6FBLJvHgkg=\nk8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=\nk8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=\nk8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=\nk8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=\nk8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=\nk8s.io/kubectl v0.23.1/go.mod h1:Ui7dJKdUludF8yWAOSN7JZEkOuYixX5yF6E6NjoukKE=\nk8s.io/kubectl v0.23.4 h1:mAa+zEOlyZieecEy+xSrhjkpMcukYyHWzcNdX28dzMY=\nk8s.io/kubectl v0.23.4/go.mod h1:Dgb0Rvx/8JKS/C2EuvsNiQc6RZnX0SbHJVG3XUzH6ok=\nk8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=\nk8s.io/metrics v0.23.1/go.mod h1:qXvsM1KANrc+ZZeFwj6Phvf0NLiC+d3RwcsLcdGc+xs=\nk8s.io/metrics v0.23.4/go.mod h1:cl6sY9BdVT3DubbpqnkPIKi6mn/F2ltkU4yH1tEJ3Bo=\nk8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=\nk8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=\nk8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=\nk8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE=\nk8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=\noras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg=\noras.land/oras-go v1.1.0/go.mod h1:1A7vR/0KknT2UkJVWh+xMi95I/AhK8ZrxrnUSmXN0bQ=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27/go.mod h1:tq2nT0Kx7W+/f2JVE+zxYtUhdjuELJkVpNz+x/QN5R4=\nsigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=\nsigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=\nsigs.k8s.io/kustomize/api v0.10.1 h1:KgU7hfYoscuqag84kxtzKdEC3mKMb99DPI3a0eaV1d0=\nsigs.k8s.io/kustomize/api v0.10.1/go.mod h1:2FigT1QN6xKdcnGS2Ppp1uIWrtWN28Ms8A3OZUZhwr8=\nsigs.k8s.io/kustomize/cmd/config v0.10.2/go.mod h1:K2aW7nXJ0AaT+VA/eO0/dzFLxmpFcTzudmAgDwPY1HQ=\nsigs.k8s.io/kustomize/kustomize/v4 v4.4.1/go.mod h1:qOKJMMz2mBP+vcS7vK+mNz4HBLjaQSWRY22EF6Tb7Io=\nsigs.k8s.io/kustomize/kyaml v0.13.0 h1:9c+ETyNfSrVhxvphs+K2dzT3dh5oVPPEqPOE/cUpScY=\nsigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E=\nsigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=\nsigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=\nsigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=\nsigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=\nsigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=\nsigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=\nsigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=\nsigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=\nsigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=\nsigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=\n"
  },
  {
    "path": "internal/client/client.go",
    "content": "package client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"golang.org/x/sync/errgroup\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tunstructuredv1 \"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\tmetav1beta1 \"k8s.io/apimachinery/pkg/apis/meta/v1beta1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n\t\"k8s.io/client-go/discovery\"\n\t\"k8s.io/client-go/dynamic\"\n\t_ \"k8s.io/client-go/plugin/pkg/client/auth\" //nolint:gci\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\tclientQPS   = 300\n\tclientBurst = 400\n)\n\ntype GetOptions struct {\n\tAPIResource APIResource\n\tNamespace   string\n}\n\ntype GetTableOptions struct {\n\tAPIResource APIResource\n\tNamespace   string\n\tNames       []string\n}\n\ntype ListOptions struct {\n\tAPIResourcesToExclude []APIResource\n\tAPIResourcesToInclude []APIResource\n\tNamespaces            []string\n}\n\ntype Interface interface {\n\tGetMapper() meta.RESTMapper\n\tIsReachable() error\n\tResolveAPIResource(s string) (*APIResource, error)\n\n\tGet(ctx context.Context, name string, opts GetOptions) (*unstructuredv1.Unstructured, error)\n\tGetAPIResources(ctx context.Context) ([]APIResource, error)\n\tGetTable(ctx context.Context, opts GetTableOptions) (*metav1.Table, error)\n\tList(ctx context.Context, opts ListOptions) (*unstructuredv1.UnstructuredList, error)\n}\n\ntype client struct {\n\tconfigFlags *Flags\n\n\tdiscoveryClient discovery.DiscoveryInterface\n\tdynamicClient   dynamic.Interface\n\tmapper          meta.RESTMapper\n}\n\nfunc (c *client) GetMapper() meta.RESTMapper {\n\treturn c.mapper\n}\n\n// IsReachable tests connectivity to the cluster.\nfunc (c *client) IsReachable() error {\n\t_, err := c.discoveryClient.ServerVersion()\n\treturn err\n}\n\nfunc (c *client) ResolveAPIResource(s string) (*APIResource, error) {\n\tvar gvr schema.GroupVersionResource\n\tvar gvk schema.GroupVersionKind\n\tvar err error\n\n\t// Resolve type string into GVR\n\tfullySpecifiedGVR, gr := schema.ParseResourceArg(strings.ToLower(s))\n\tif fullySpecifiedGVR != nil {\n\t\tgvr, _ = c.mapper.ResourceFor(*fullySpecifiedGVR)\n\t}\n\tif gvr.Empty() {\n\t\tgvr, err = c.mapper.ResourceFor(gr.WithVersion(\"\"))\n\t\tif err != nil {\n\t\t\tif len(gr.Group) == 0 {\n\t\t\t\terr = fmt.Errorf(\"the server doesn't have a resource type \\\"%s\\\"\", gr.Resource)\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"the server doesn't have a resource type \\\"%s\\\" in group \\\"%s\\\"\", gr.Resource, gr.Group)\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t}\n\t// Obtain Kind from GVR\n\tgvk, err = c.mapper.KindFor(gvr)\n\tif gvk.Empty() {\n\t\tif err != nil {\n\t\t\tif len(gvr.Group) == 0 {\n\t\t\t\terr = fmt.Errorf(\"the server couldn't identify a kind for resource type \\\"%s\\\"\", gvr.Resource)\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"the server couldn't identify a kind for resource type \\\"%s\\\" in group \\\"%s\\\"\", gvr.Resource, gvr.Group)\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t}\n\t// Determine scope of resource\n\tmapping, err := c.mapper.RESTMapping(gvk.GroupKind())\n\tif err != nil {\n\t\tif len(gvk.Group) == 0 {\n\t\t\terr = fmt.Errorf(\"the server couldn't identify a group kind for resource type \\\"%s\\\"\", gvk.Kind)\n\t\t} else {\n\t\t\terr = fmt.Errorf(\"the server couldn't identify a group kind for resource type \\\"%s\\\" in group \\\"%s\\\"\", gvk.Kind, gvk.Group)\n\t\t}\n\t\treturn nil, err\n\t}\n\t// NOTE: This is a rather incomplete APIResource object, but it has enough\n\t//       information inside for our use case, which is to fetch API objects\n\tres := &APIResource{\n\t\tName:       gvr.Resource,\n\t\tNamespaced: mapping.Scope.Name() == meta.RESTScopeNameNamespace,\n\t\tGroup:      gvk.Group,\n\t\tVersion:    gvk.Version,\n\t\tKind:       gvk.Kind,\n\t}\n\n\treturn res, nil\n}\n\n// Get returns an object that matches the provided name & options on the server.\nfunc (c *client) Get(ctx context.Context, name string, opts GetOptions) (*unstructuredv1.Unstructured, error) {\n\tklog.V(4).Infof(\"Get \\\"%s\\\" with options: %+v\", name, opts)\n\tgvr := opts.APIResource.GroupVersionResource()\n\tvar ri dynamic.ResourceInterface\n\tif opts.APIResource.Namespaced {\n\t\tri = c.dynamicClient.Resource(gvr).Namespace(opts.Namespace)\n\t} else {\n\t\tri = c.dynamicClient.Resource(gvr)\n\t}\n\treturn ri.Get(ctx, name, metav1.GetOptions{})\n}\n\n// GetTable returns a table output from the server which contains data of the\n// list of objects that matches the provided options. This is similar to an API\n// request made by `kubectl get TYPE NAME... [-n NAMESPACE]`.\nfunc (c *client) GetTable(ctx context.Context, opts GetTableOptions) (*metav1.Table, error) {\n\tklog.V(4).Infof(\"GetTable with options: %+v\", opts)\n\tgk := opts.APIResource.GroupVersionKind().GroupKind()\n\tr := resource.NewBuilder(c.configFlags).\n\t\tUnstructured().\n\t\tNamespaceParam(opts.Namespace).\n\t\tResourceNames(gk.String(), opts.Names...).\n\t\tContinueOnError().\n\t\tLatest().\n\t\tTransformRequests(func(req *rest.Request) {\n\t\t\treq.SetHeader(\"Accept\", strings.Join([]string{\n\t\t\t\tfmt.Sprintf(\"application/json;as=Table;v=%s;g=%s\", metav1.SchemeGroupVersion.Version, metav1.GroupName),\n\t\t\t\tfmt.Sprintf(\"application/json;as=Table;v=%s;g=%s\", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName),\n\t\t\t\t\"application/json\",\n\t\t\t}, \",\"))\n\t\t\treq.Param(\"includeObject\", string(metav1.IncludeMetadata))\n\t\t}).\n\t\tDo()\n\tr.IgnoreErrors(apierrors.IsNotFound)\n\tif err := r.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfos, err := r.Infos()\n\tif err != nil || infos == nil {\n\t\treturn nil, err\n\t}\n\tvar table *metav1.Table\n\tfor ix := range infos {\n\t\tt, err := decodeIntoTable(infos[ix].Object)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif table == nil {\n\t\t\ttable = t\n\t\t\tcontinue\n\t\t}\n\t\ttable.Rows = append(table.Rows, t.Rows...)\n\t}\n\treturn table, nil\n}\n\nfunc decodeIntoTable(obj runtime.Object) (*metav1.Table, error) {\n\tu, ok := obj.(*unstructuredv1.Unstructured)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"attempt to decode non-Unstructured object\")\n\t}\n\ttable := &metav1.Table{}\n\tif err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, table); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor i := range table.Rows {\n\t\trow := &table.Rows[i]\n\t\tif row.Object.Raw == nil || row.Object.Object != nil {\n\t\t\tcontinue\n\t\t}\n\t\tconverted, err := runtime.Decode(unstructuredv1.UnstructuredJSONScheme, row.Object.Raw)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trow.Object.Object = converted\n\t}\n\n\treturn table, nil\n}\n\n// List returns a list of objects that matches the provided options on the\n// server.\n//\n//nolint:funlen,gocognit\nfunc (c *client) List(ctx context.Context, opts ListOptions) (*unstructuredv1.UnstructuredList, error) {\n\tklog.V(4).Infof(\"List with options: %+v\", opts)\n\tapis, err := c.GetAPIResources(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Filter APIs\n\tif len(opts.APIResourcesToInclude) > 0 {\n\t\tincludeGKSet := ResourcesToGroupKindSet(opts.APIResourcesToInclude)\n\t\tnewAPIs := []APIResource{}\n\t\tfor _, api := range apis {\n\t\t\tif _, ok := includeGKSet[api.GroupKind()]; ok {\n\t\t\t\tnewAPIs = append(newAPIs, api)\n\t\t\t}\n\t\t}\n\t\tapis = newAPIs\n\t}\n\tif len(opts.APIResourcesToExclude) > 0 {\n\t\texcludeGKSet := ResourcesToGroupKindSet(opts.APIResourcesToExclude)\n\t\tnewAPIs := []APIResource{}\n\t\tfor _, api := range apis {\n\t\t\tif _, ok := excludeGKSet[api.GroupKind()]; !ok {\n\t\t\t\tnewAPIs = append(newAPIs, api)\n\t\t\t}\n\t\t}\n\t\tapis = newAPIs\n\t}\n\n\t// Deduplicate list of namespaces & determine the scope for listing objects\n\tisClusterScopeRequest, nsSet := false, make(map[string]struct{})\n\tif len(opts.Namespaces) == 0 {\n\t\tisClusterScopeRequest = true\n\t}\n\tfor _, ns := range opts.Namespaces {\n\t\tif ns != \"\" {\n\t\t\tnsSet[ns] = struct{}{}\n\t\t} else {\n\t\t\tisClusterScopeRequest = true\n\t\t}\n\t}\n\n\tvar mu sync.Mutex\n\tvar items []unstructuredv1.Unstructured\n\tcreateListFn := func(ctx context.Context, api APIResource, ns string) func() error {\n\t\treturn func() error {\n\t\t\tobjs, err := c.listByAPI(ctx, api, ns)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tmu.Lock()\n\t\t\titems = append(items, objs.Items...)\n\t\t\tmu.Unlock()\n\t\t\treturn nil\n\t\t}\n\t}\n\teg, ctx := errgroup.WithContext(ctx)\n\tfor i := range apis {\n\t\tapi := apis[i]\n\t\tclusterScopeListFn := func() error {\n\t\t\treturn createListFn(ctx, api, \"\")()\n\t\t}\n\t\tnamespaceScopeListFn := func() error {\n\t\t\tegInner, ctxInner := errgroup.WithContext(ctx)\n\t\t\tfor ns := range nsSet {\n\t\t\t\tlistFn := createListFn(ctxInner, api, ns)\n\t\t\t\tegInner.Go(func() error {\n\t\t\t\t\terr = listFn()\n\t\t\t\t\t// If no permissions to list the resource at the namespace scope,\n\t\t\t\t\t// suppress the error to allow other goroutines to continue listing\n\t\t\t\t\tif apierrors.IsForbidden(err) {\n\t\t\t\t\t\terr = nil\n\t\t\t\t\t}\n\t\t\t\t\treturn err\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn egInner.Wait()\n\t\t}\n\t\teg.Go(func() error {\n\t\t\tvar err error\n\t\t\tif isClusterScopeRequest {\n\t\t\t\terr = clusterScopeListFn()\n\t\t\t\t// If no permissions to list the cluster-scoped resource,\n\t\t\t\t// suppress the error to allow other goroutines to continue listing\n\t\t\t\tif !api.Namespaced && apierrors.IsForbidden(err) {\n\t\t\t\t\terr = nil\n\t\t\t\t}\n\t\t\t\t// If no permissions to list the namespaced resource at the cluster\n\t\t\t\t// scope, don't return the error yet & reattempt to list the resource\n\t\t\t\t// in other namespace(s)\n\t\t\t\tif !api.Namespaced || !apierrors.IsForbidden(err) {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn namespaceScopeListFn()\n\t\t})\n\t}\n\tif err := eg.Wait(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tklog.V(4).Infof(\"Got %4d objects from %d API resources\", len(items), len(apis))\n\treturn &unstructuredv1.UnstructuredList{Items: items}, nil\n}\n\n// GetAPIResources returns all API resource registered on the server.\nfunc (c *client) GetAPIResources(_ context.Context) ([]APIResource, error) {\n\trls, err := c.discoveryClient.ServerPreferredResources()\n\tif err != nil {\n\t\tif discovery.IsGroupDiscoveryFailedError(err) {\n\t\t\tklog.V(3).Info(\"Ignoring invalid resources\")\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tapis := []APIResource{}\n\tfor _, rl := range rls {\n\t\tif len(rl.APIResources) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tgv, err := schema.ParseGroupVersion(rl.GroupVersion)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"Ignoring invalid discovered resource %q: %v\", rl.GroupVersion, err)\n\t\t\tcontinue\n\t\t}\n\t\tfor _, r := range rl.APIResources {\n\t\t\t// Filter resources that can be watched, listed & get\n\t\t\tif len(r.Verbs) == 0 || !sets.NewString(r.Verbs...).HasAll(\"watch\", \"list\", \"get\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tapi := APIResource{\n\t\t\t\tGroup:      gv.Group,\n\t\t\t\tVersion:    gv.Version,\n\t\t\t\tKind:       r.Kind,\n\t\t\t\tName:       r.Name,\n\t\t\t\tNamespaced: r.Namespaced,\n\t\t\t}\n\t\t\t// Exclude duplicated resources (for Kubernetes v1.18 & above)\n\t\t\tswitch {\n\t\t\t// migrated to \"events.v1.events.k8s.io\"\n\t\t\tcase api.Group == \"\" && api.Kind == \"Event\":\n\t\t\t\tklog.V(4).Infof(\"Exclude duplicated discovered resource: %s\", api)\n\t\t\t\tcontinue\n\t\t\t// migrated to \"ingresses.v1.networking.k8s.io\"\n\t\t\tcase api.Group == \"extensions\" && api.Kind == \"Ingress\":\n\t\t\t\tklog.V(4).Infof(\"Exclude duplicated discovered resource: %s\", api)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tapis = append(apis, api)\n\t\t}\n\t}\n\n\tklog.V(4).Infof(\"Discovered %d available API resources to list\", len(apis))\n\treturn apis, nil\n}\n\n// listByAPI list all objects of the provided API & namespace. If listing the\n// API at the cluster scope, set the namespace argument as an empty string.\nfunc (c *client) listByAPI(ctx context.Context, api APIResource, ns string) (*unstructuredv1.UnstructuredList, error) {\n\tvar ri dynamic.ResourceInterface\n\tvar items []unstructuredv1.Unstructured\n\tvar next string\n\n\tisClusterScopeRequest := !api.Namespaced || ns == \"\"\n\tif isClusterScopeRequest {\n\t\tri = c.dynamicClient.Resource(api.GroupVersionResource())\n\t} else {\n\t\tri = c.dynamicClient.Resource(api.GroupVersionResource()).Namespace(ns)\n\t}\n\tfor {\n\t\tobjectList, err := ri.List(ctx, metav1.ListOptions{\n\t\t\tLimit:    250,\n\t\t\tContinue: next,\n\t\t})\n\t\tif err != nil {\n\t\t\tswitch {\n\t\t\tcase apierrors.IsForbidden(err):\n\t\t\t\tif isClusterScopeRequest {\n\t\t\t\t\tklog.V(4).Infof(\"No access to list at cluster scope for resource: %s\", api)\n\t\t\t\t} else {\n\t\t\t\t\tklog.V(4).Infof(\"No access to list in the namespace \\\"%s\\\" for resource: %s\", ns, api)\n\t\t\t\t}\n\t\t\t\treturn nil, err\n\t\t\tcase apierrors.IsNotFound(err):\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tif isClusterScopeRequest {\n\t\t\t\t\terr = fmt.Errorf(\"failed to list resource type \\\"%s\\\" in API group \\\"%s\\\" at the cluster scope: %w\", api.Name, api.Group, err)\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"failed to list resource type \\\"%s\\\" in API group \\\"%s\\\" in the namespace \\\"%s\\\": %w\", api.Name, api.Group, ns, err)\n\t\t\t\t}\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tif objectList == nil {\n\t\t\tbreak\n\t\t}\n\t\titems = append(items, objectList.Items...)\n\t\tnext = objectList.GetContinue()\n\t\tif len(next) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif isClusterScopeRequest {\n\t\tklog.V(4).Infof(\"Got %4d objects from resource at the cluster scope: %s\", len(items), api)\n\t} else {\n\t\tklog.V(4).Infof(\"Got %4d objects from resource in the namespace \\\"%s\\\": %s\", len(items), ns, api)\n\t}\n\treturn &unstructuredv1.UnstructuredList{Items: items}, nil\n}\n"
  },
  {
    "path": "internal/client/flags.go",
    "content": "package client\n\nimport (\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\t\"k8s.io/client-go/dynamic\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/kubectl/pkg/cmd/get\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n\t\"k8s.io/kubectl/pkg/util\"\n)\n\n// Flags composes common client configuration flag structs used in the command.\ntype Flags struct {\n\t*genericclioptions.ConfigFlags\n}\n\n// Copy returns a copy of Flags for mutation.\nfunc (f *Flags) Copy() Flags {\n\tFlags := *f\n\treturn Flags\n}\n\n// AddFlags receives a pflag.FlagSet reference and binds flags related to client\n// configuration to it.\nfunc (f *Flags) AddFlags(flags *pflag.FlagSet) {\n\tf.ConfigFlags.AddFlags(flags)\n}\n\n// RegisterFlagCompletionFunc receives a *cobra.Command & register functions to\n// to provide completion for flags related to client configuration.\n//\n// Based off `registerCompletionFuncForGlobalFlags` from\n// https://github.com/kubernetes/kubectl/blob/v0.22.1/pkg/cmd/cmd.go#L439-L460\nfunc (*Flags) RegisterFlagCompletionFunc(cmd *cobra.Command, f cmdutil.Factory) {\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\t\"namespace\",\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn get.CompGetResource(f, cmd, \"namespace\", toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\t\"context\",\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn util.ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\t\"cluster\",\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn util.ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\t\"user\",\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn util.ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n}\n\n// ToClient returns a client based on the flag configuration.\nfunc (f *Flags) ToClient() (Interface, error) {\n\tconfig, err := f.ToRESTConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconfig.WarningHandler = rest.NoWarnings{}\n\tconfig.QPS = clientQPS\n\tconfig.Burst = clientBurst\n\tf.WithDiscoveryBurst(clientBurst)\n\n\tdyn, err := dynamic.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdis, err := f.ToDiscoveryClient()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmapper, err := f.ToRESTMapper()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc := &client{\n\t\tconfigFlags:     f,\n\t\tdiscoveryClient: dis,\n\t\tdynamicClient:   dyn,\n\t\tmapper:          mapper,\n\t}\n\n\treturn c, nil\n}\n\n// NewFlags returns flags associated with client configuration, with default\n// values set.\nfunc NewFlags() *Flags {\n\treturn &Flags{\n\t\tConfigFlags: genericclioptions.NewConfigFlags(true),\n\t}\n}\n"
  },
  {
    "path": "internal/client/resource.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\n// APIResource represents a Kubernetes API resource.\ntype APIResource metav1.APIResource\n\nfunc (r APIResource) GroupKind() schema.GroupKind {\n\treturn schema.GroupKind{\n\t\tGroup: r.Group,\n\t\tKind:  r.Kind,\n\t}\n}\n\nfunc (r APIResource) GroupVersionKind() schema.GroupVersionKind {\n\treturn schema.GroupVersionKind{\n\t\tGroup:   r.Group,\n\t\tVersion: r.Version,\n\t\tKind:    r.Kind,\n\t}\n}\n\nfunc (r APIResource) GroupVersionResource() schema.GroupVersionResource {\n\treturn schema.GroupVersionResource{\n\t\tGroup:    r.Group,\n\t\tVersion:  r.Version,\n\t\tResource: r.Name,\n\t}\n}\n\nfunc (r APIResource) String() string {\n\tif len(r.Group) == 0 {\n\t\treturn fmt.Sprintf(\"%s.%s\", r.Name, r.Version)\n\t}\n\treturn fmt.Sprintf(\"%s.%s.%s\", r.Name, r.Version, r.Group)\n}\n\nfunc (r APIResource) WithGroupString() string {\n\tif len(r.Group) == 0 {\n\t\treturn r.Name\n\t}\n\treturn r.Name + \".\" + r.Group\n}\n\nfunc ResourcesToGroupKindSet(apis []APIResource) map[schema.GroupKind]struct{} {\n\tgkSet := map[schema.GroupKind]struct{}{}\n\tfor _, api := range apis {\n\t\tgk := api.GroupKind()\n\t\t// Account for resources that migrated API groups (for Kubernetes v1.18 & above)\n\t\tswitch {\n\t\t// migrated from \"events.v1\" to \"events.v1.events.k8s.io\"\n\t\tcase gk.Kind == \"Event\" && (gk.Group == \"\" || gk.Group == \"events.k8s.io\"):\n\t\t\tgkSet[schema.GroupKind{Kind: gk.Kind, Group: \"\"}] = struct{}{}\n\t\t\tgkSet[schema.GroupKind{Kind: gk.Kind, Group: \"events.k8s.io\"}] = struct{}{}\n\t\t// migrated from \"ingresses.v1.extensions\" to \"ingresses.v1.networking.k8s.io\"\n\t\tcase gk.Kind == \"Ingress\" && (gk.Group == \"extensions\" || gk.Group == \"networking.k8s.io\"):\n\t\t\tgkSet[schema.GroupKind{Kind: gk.Kind, Group: \"extensions\"}] = struct{}{}\n\t\t\tgkSet[schema.GroupKind{Kind: gk.Kind, Group: \"networking.k8s.io\"}] = struct{}{}\n\t\tdefault:\n\t\t\tgkSet[gk] = struct{}{}\n\t\t}\n\t}\n\treturn gkSet\n}\n\n// ObjectMeta contains the metadata for identifying a Kubernetes object.\ntype ObjectMeta struct {\n\tAPIResource\n\tName      string\n\tNamespace string\n}\n\nfunc (o ObjectMeta) String() string {\n\treturn fmt.Sprintf(\"%s/%s\", o.APIResource, o.Name)\n}\n"
  },
  {
    "path": "internal/completion/completion.go",
    "content": "package completion\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n\t\"k8s.io/kubectl/pkg/cmd/get\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n)\n\n// filterString returns all strings from 's', except those with names matching\n// 'ignored'.\nfunc filterString(s []string, ignored []string) []string {\n\tif ignored == nil {\n\t\treturn s\n\t}\n\tvar filteredStrList []string\n\tfor _, str := range s {\n\t\tfound := false\n\t\tfor _, ignoredName := range ignored {\n\t\t\tif str == ignoredName {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tfilteredStrList = append(filteredStrList, str)\n\t\t}\n\t}\n\treturn filteredStrList\n}\n\n// GetScopeNamespaceList provides dynamic auto-completion for scope namespaces.\nfunc GetScopeNamespaceList(f cmdutil.Factory, cmd *cobra.Command, toComplete string) []string {\n\tvar comp []string\n\n\tallNS := get.CompGetResource(f, cmd, \"namespace\", \"\")\n\texistingNS := strings.Split(toComplete, \",\")\n\texistingNS = existingNS[:len(existingNS)-1]\n\tignoreNS := existingNS\n\tif ns, _, err := f.ToRawKubeConfigLoader().Namespace(); err == nil {\n\t\tignoreNS = append(ignoreNS, ns)\n\t}\n\tfilteredNS := filterString(allNS, ignoreNS)\n\n\tcompPrefix := strings.Join(existingNS, \",\")\n\tfor _, ns := range filteredNS {\n\t\tif len(compPrefix) > 0 {\n\t\t\tns = fmt.Sprintf(\"%s,%s\", compPrefix, ns)\n\t\t}\n\t\tcomp = append(comp, ns)\n\t}\n\n\treturn comp\n}\n"
  },
  {
    "path": "internal/graph/graph.go",
    "content": "package graph\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\teventsv1 \"k8s.io/api/events/v1\"\n\textensionsv1beta1 \"k8s.io/api/extensions/v1beta1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\tnodev1 \"k8s.io/api/node/v1\"\n\tpolicyv1 \"k8s.io/api/policy/v1\"\n\tpolicyv1beta1 \"k8s.io/api/policy/v1beta1\"\n\trbacv1 \"k8s.io/api/rbac/v1\"\n\tstoragev1 \"k8s.io/api/storage/v1\"\n\tstoragev1beta1 \"k8s.io/api/storage/v1beta1\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tunstructuredv1 \"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/klog/v2\"\n\tapiregistrationv1 \"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1\"\n)\n\n// ObjectLabelSelectorKey is a compact representation of an ObjectLabelSelector.\n// Typically used as key types for maps.\ntype ObjectLabelSelectorKey string\n\n// ObjectLabelSelector is a reference to a collection of Kubernetes objects.\ntype ObjectLabelSelector struct {\n\tGroup     string\n\tKind      string\n\tNamespace string\n\tSelector  labels.Selector\n}\n\n// Key converts the ObjectLabelSelector into a ObjectLabelSelectorKey.\nfunc (o *ObjectLabelSelector) Key() ObjectLabelSelectorKey {\n\tk := fmt.Sprintf(\"%s\\\\%s\\\\%s\\\\%s\", o.Group, o.Kind, o.Namespace, o.Selector)\n\treturn ObjectLabelSelectorKey(k)\n}\n\n// ObjectSelectorKey is a compact representation of an ObjectSelector.\n// Typically used as key types for maps.\ntype ObjectSelectorKey string\n\n// ObjectSelector is a reference to a collection of Kubernetes objects.\ntype ObjectSelector struct {\n\tGroup      string\n\tKind       string\n\tNamespaces sets.String\n}\n\n// Key converts the ObjectSelector into a ObjectSelectorKey.\nfunc (o *ObjectSelector) Key() ObjectSelectorKey {\n\tk := fmt.Sprintf(\"%s\\\\%s\\\\%s\", o.Group, o.Kind, o.Namespaces)\n\treturn ObjectSelectorKey(k)\n}\n\n// ObjectReferenceKey is a compact representation of an ObjectReference.\n// Typically used as key types for maps.\ntype ObjectReferenceKey string\n\n// ObjectReference is a reference to a Kubernetes object.\ntype ObjectReference struct {\n\tGroup     string\n\tKind      string\n\tNamespace string\n\tName      string\n}\n\n// Key converts the ObjectReference into a ObjectReferenceKey.\nfunc (o *ObjectReference) Key() ObjectReferenceKey {\n\tk := fmt.Sprintf(\"%s\\\\%s\\\\%s\\\\%s\", o.Group, o.Kind, o.Namespace, o.Name)\n\treturn ObjectReferenceKey(k)\n}\n\ntype sortableStringSlice []string\n\nfunc (s sortableStringSlice) Len() int           { return len(s) }\nfunc (s sortableStringSlice) Less(i, j int) bool { return s[i] < s[j] }\nfunc (s sortableStringSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\n\n// Relationship represents a relationship type between two Kubernetes objects.\ntype Relationship string\n\n// RelationshipSet contains a set of relationships.\ntype RelationshipSet map[Relationship]struct{}\n\n// List returns the contents as a sorted string slice.\nfunc (s RelationshipSet) List() []string {\n\tres := make(sortableStringSlice, 0, len(s))\n\tfor key := range s {\n\t\tres = append(res, string(key))\n\t}\n\tsort.Sort(res)\n\treturn []string(res)\n}\n\n// RelationshipMap contains a map of relationships a Kubernetes object has with\n// other objects in the cluster.\ntype RelationshipMap struct {\n\tDependenciesByLabelSelector map[ObjectLabelSelectorKey]RelationshipSet\n\tDependenciesByRef           map[ObjectReferenceKey]RelationshipSet\n\tDependenciesBySelector      map[ObjectSelectorKey]RelationshipSet\n\tDependenciesByUID           map[types.UID]RelationshipSet\n\tDependentsByLabelSelector   map[ObjectLabelSelectorKey]RelationshipSet\n\tDependentsByRef             map[ObjectReferenceKey]RelationshipSet\n\tDependentsBySelector        map[ObjectSelectorKey]RelationshipSet\n\tDependentsByUID             map[types.UID]RelationshipSet\n\tObjectLabelSelectors        map[ObjectLabelSelectorKey]ObjectLabelSelector\n\tObjectSelectors             map[ObjectSelectorKey]ObjectSelector\n}\n\nfunc newRelationshipMap() RelationshipMap {\n\treturn RelationshipMap{\n\t\tDependenciesByLabelSelector: map[ObjectLabelSelectorKey]RelationshipSet{},\n\t\tDependenciesByRef:           map[ObjectReferenceKey]RelationshipSet{},\n\t\tDependenciesBySelector:      map[ObjectSelectorKey]RelationshipSet{},\n\t\tDependenciesByUID:           map[types.UID]RelationshipSet{},\n\t\tDependentsByLabelSelector:   map[ObjectLabelSelectorKey]RelationshipSet{},\n\t\tDependentsByRef:             map[ObjectReferenceKey]RelationshipSet{},\n\t\tDependentsBySelector:        map[ObjectSelectorKey]RelationshipSet{},\n\t\tDependentsByUID:             map[types.UID]RelationshipSet{},\n\t\tObjectLabelSelectors:        map[ObjectLabelSelectorKey]ObjectLabelSelector{},\n\t\tObjectSelectors:             map[ObjectSelectorKey]ObjectSelector{},\n\t}\n}\n\nfunc (m *RelationshipMap) AddDependencyByKey(k ObjectReferenceKey, r Relationship) {\n\tif _, ok := m.DependenciesByRef[k]; !ok {\n\t\tm.DependenciesByRef[k] = RelationshipSet{}\n\t}\n\tm.DependenciesByRef[k][r] = struct{}{}\n}\n\nfunc (m *RelationshipMap) AddDependencyByLabelSelector(o ObjectLabelSelector, r Relationship) {\n\tk := o.Key()\n\tif _, ok := m.DependenciesByLabelSelector[k]; !ok {\n\t\tm.DependenciesByLabelSelector[k] = RelationshipSet{}\n\t}\n\tm.DependenciesByLabelSelector[k][r] = struct{}{}\n\tm.ObjectLabelSelectors[k] = o\n}\n\nfunc (m *RelationshipMap) AddDependencyBySelector(o ObjectSelector, r Relationship) {\n\tk := o.Key()\n\tif _, ok := m.DependenciesBySelector[k]; !ok {\n\t\tm.DependenciesBySelector[k] = RelationshipSet{}\n\t}\n\tm.DependenciesBySelector[k][r] = struct{}{}\n\tm.ObjectSelectors[k] = o\n}\n\nfunc (m *RelationshipMap) AddDependencyByUID(uid types.UID, r Relationship) {\n\tif _, ok := m.DependenciesByUID[uid]; !ok {\n\t\tm.DependenciesByUID[uid] = RelationshipSet{}\n\t}\n\tm.DependenciesByUID[uid][r] = struct{}{}\n}\n\nfunc (m *RelationshipMap) AddDependentByKey(k ObjectReferenceKey, r Relationship) {\n\tif _, ok := m.DependentsByRef[k]; !ok {\n\t\tm.DependentsByRef[k] = RelationshipSet{}\n\t}\n\tm.DependentsByRef[k][r] = struct{}{}\n}\n\nfunc (m *RelationshipMap) AddDependentByLabelSelector(o ObjectLabelSelector, r Relationship) {\n\tk := o.Key()\n\tif _, ok := m.DependentsByLabelSelector[k]; !ok {\n\t\tm.DependentsByLabelSelector[k] = RelationshipSet{}\n\t}\n\tm.DependentsByLabelSelector[k][r] = struct{}{}\n\tm.ObjectLabelSelectors[k] = o\n}\n\nfunc (m *RelationshipMap) AddDependentBySelector(o ObjectSelector, r Relationship) {\n\tk := o.Key()\n\tif _, ok := m.DependentsBySelector[k]; !ok {\n\t\tm.DependentsBySelector[k] = RelationshipSet{}\n\t}\n\tm.DependentsBySelector[k][r] = struct{}{}\n\tm.ObjectSelectors[k] = o\n}\n\nfunc (m *RelationshipMap) AddDependentByUID(uid types.UID, r Relationship) {\n\tif _, ok := m.DependentsByUID[uid]; !ok {\n\t\tm.DependentsByUID[uid] = RelationshipSet{}\n\t}\n\tm.DependentsByUID[uid][r] = struct{}{}\n}\n\n// Node represents a Kubernetes object in an relationship tree.\ntype Node struct {\n\t*unstructuredv1.Unstructured\n\tUID             types.UID\n\tGroup           string\n\tVersion         string\n\tKind            string\n\tResource        string\n\tNamespaced      bool\n\tNamespace       string\n\tName            string\n\tOwnerReferences []metav1.OwnerReference\n\tDependencies    map[types.UID]RelationshipSet\n\tDependents      map[types.UID]RelationshipSet\n\tDepth           uint\n}\n\nfunc (n *Node) AddDependency(uid types.UID, r Relationship) {\n\tif _, ok := n.Dependencies[uid]; !ok {\n\t\tn.Dependencies[uid] = RelationshipSet{}\n\t}\n\tn.Dependencies[uid][r] = struct{}{}\n}\n\nfunc (n *Node) AddDependent(uid types.UID, r Relationship) {\n\tif _, ok := n.Dependents[uid]; !ok {\n\t\tn.Dependents[uid] = RelationshipSet{}\n\t}\n\tn.Dependents[uid][r] = struct{}{}\n}\n\nfunc (n *Node) GetDeps(depsIsDependencies bool) map[types.UID]RelationshipSet {\n\tif depsIsDependencies {\n\t\treturn n.Dependencies\n\t}\n\treturn n.Dependents\n}\n\nfunc (n *Node) GetObjectReferenceKey() ObjectReferenceKey {\n\tref := ObjectReference{\n\t\tGroup:     n.Group,\n\t\tKind:      n.Kind,\n\t\tName:      n.Name,\n\t\tNamespace: n.Namespace,\n\t}\n\treturn ref.Key()\n}\n\nfunc (n *Node) GetNestedString(fields ...string) string {\n\tval, found, err := unstructuredv1.NestedString(n.UnstructuredContent(), fields...)\n\tif !found || err != nil {\n\t\treturn \"\"\n\t}\n\treturn val\n}\n\nfunc (n *Node) GetAPIResource() metav1.APIResource {\n\t// NOTE: This is a rather incomplete APIResource object, but it has enough\n\t//       information inside for our use case, which is to fetch API objects\n\treturn metav1.APIResource{\n\t\tGroup:      n.Group,\n\t\tVersion:    n.Version,\n\t\tKind:       n.Kind,\n\t\tName:       n.Resource,\n\t\tNamespaced: n.Namespaced,\n\t}\n}\n\n// NodeList contains a list of nodes.\ntype NodeList []*Node\n\nfunc (n NodeList) Len() int {\n\treturn len(n)\n}\n\nfunc (n NodeList) Less(i, j int) bool {\n\t// Sort nodes in following order: Namespace, Kind, Group, Name\n\ta, b := n[i], n[j]\n\tif a.Namespace != b.Namespace {\n\t\treturn a.Namespace < b.Namespace\n\t}\n\tif a.Kind != b.Kind {\n\t\treturn a.Kind < b.Kind\n\t}\n\tif a.Group != b.Group {\n\t\treturn a.Group < b.Group\n\t}\n\treturn a.Name < b.Name\n}\n\nfunc (n NodeList) Swap(i, j int) {\n\tn[i], n[j] = n[j], n[i]\n}\n\n// NodeMap contains a relationship tree stored as a map of nodes.\ntype NodeMap map[types.UID]*Node\n\n// ResolveDependencies resolves all dependencies of the provided objects and\n// returns a relationship tree.\nfunc ResolveDependencies(m meta.RESTMapper, objects []unstructuredv1.Unstructured, uids []types.UID) (NodeMap, error) {\n\treturn resolveDeps(m, objects, uids, true)\n}\n\n// ResolveDependents resolves all dependents of the provided objects and returns\n// a relationship tree.\nfunc ResolveDependents(m meta.RESTMapper, objects []unstructuredv1.Unstructured, uids []types.UID) (NodeMap, error) {\n\treturn resolveDeps(m, objects, uids, false)\n}\n\n// resolveDeps resolves all dependencies or dependents of the provided objects\n// and returns a relationship tree.\n//nolint:funlen,gocognit,gocyclo\nfunc resolveDeps(m meta.RESTMapper, objects []unstructuredv1.Unstructured, uids []types.UID, depsIsDependencies bool) (NodeMap, error) {\n\tif len(uids) == 0 {\n\t\treturn NodeMap{}, nil\n\t}\n\t// Create global node maps of all objects, one mapped by node UIDs & the other\n\t// mapped by node keys. This step also helps deduplicate the list of provided\n\t// objects\n\tglobalMapByUID := map[types.UID]*Node{}\n\tglobalMapByKey := map[ObjectReferenceKey]*Node{}\n\tfor ix, o := range objects {\n\t\tgvk := o.GroupVersionKind()\n\t\tm, err := m.RESTMapping(gvk.GroupKind(), gvk.Version)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"Failed to map resource \\\"%s\\\" to GVR\", gvk)\n\t\t\treturn nil, err\n\t\t}\n\t\tns := o.GetNamespace()\n\t\tnode := Node{\n\t\t\tUnstructured:    &objects[ix],\n\t\t\tUID:             o.GetUID(),\n\t\t\tName:            o.GetName(),\n\t\t\tNamespace:       ns,\n\t\t\tNamespaced:      ns != \"\",\n\t\t\tGroup:           m.Resource.Group,\n\t\t\tVersion:         m.Resource.Version,\n\t\t\tKind:            m.GroupVersionKind.Kind,\n\t\t\tResource:        m.Resource.Resource,\n\t\t\tOwnerReferences: o.GetOwnerReferences(),\n\t\t\tDependencies:    map[types.UID]RelationshipSet{},\n\t\t\tDependents:      map[types.UID]RelationshipSet{},\n\t\t}\n\t\tuid, key := node.UID, node.GetObjectReferenceKey()\n\t\tif n, ok := globalMapByUID[uid]; ok {\n\t\t\tklog.V(4).Infof(\"Duplicated %s.%s resource \\\"%s\\\" in namespace \\\"%s\\\"\", n.Kind, n.Group, n.Name, n.Namespace)\n\t\t}\n\t\tglobalMapByUID[uid] = &node\n\t\tglobalMapByKey[key] = &node\n\n\t\tif node.Group == corev1.GroupName && node.Kind == \"Node\" {\n\t\t\t// Node events sent by the Kubelet uses the node's name as the\n\t\t\t// ObjectReference UID, so we include them as keys in our global map to\n\t\t\t// support lookup by nodename\n\t\t\tglobalMapByUID[types.UID(node.Name)] = &node\n\t\t\t// Node events sent by the kube-proxy uses the node's hostname as the\n\t\t\t// ObjectReference UID, so we include them as keys in our global map to\n\t\t\t// support lookup by hostname\n\t\t\tif hostname, ok := o.GetLabels()[corev1.LabelHostname]; ok {\n\t\t\t\tglobalMapByUID[types.UID(hostname)] = &node\n\t\t\t}\n\t\t}\n\t}\n\n\tresolveLabelSelectorToNodes := func(o ObjectLabelSelector) []*Node {\n\t\tvar result []*Node\n\t\tfor _, n := range globalMapByUID {\n\t\t\tif n.Group == o.Group && n.Kind == o.Kind && n.Namespace == o.Namespace {\n\t\t\t\tif ok := o.Selector.Matches(labels.Set(n.GetLabels())); ok {\n\t\t\t\t\tresult = append(result, n)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\tresolveSelectorToNodes := func(o ObjectSelector) []*Node {\n\t\tvar result []*Node\n\t\tfor _, n := range globalMapByUID {\n\t\t\tif n.Group == o.Group && n.Kind == o.Kind {\n\t\t\t\tif len(o.Namespaces) == 0 || o.Namespaces.Has(n.Namespace) {\n\t\t\t\t\tresult = append(result, n)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\tupdateRelationships := func(node *Node, rmap *RelationshipMap) {\n\t\tfor k, rset := range rmap.DependenciesByRef {\n\t\t\tif n, ok := globalMapByKey[k]; ok {\n\t\t\t\tfor r := range rset {\n\t\t\t\t\tnode.AddDependency(n.UID, r)\n\t\t\t\t\tn.AddDependent(node.UID, r)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor k, rset := range rmap.DependentsByRef {\n\t\t\tif n, ok := globalMapByKey[k]; ok {\n\t\t\t\tfor r := range rset {\n\t\t\t\t\tn.AddDependency(node.UID, r)\n\t\t\t\t\tnode.AddDependent(n.UID, r)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor k, rset := range rmap.DependenciesByLabelSelector {\n\t\t\tif ols, ok := rmap.ObjectLabelSelectors[k]; ok {\n\t\t\t\tfor _, n := range resolveLabelSelectorToNodes(ols) {\n\t\t\t\t\tfor r := range rset {\n\t\t\t\t\t\tnode.AddDependency(n.UID, r)\n\t\t\t\t\t\tn.AddDependent(node.UID, r)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor k, rset := range rmap.DependentsByLabelSelector {\n\t\t\tif ols, ok := rmap.ObjectLabelSelectors[k]; ok {\n\t\t\t\tfor _, n := range resolveLabelSelectorToNodes(ols) {\n\t\t\t\t\tfor r := range rset {\n\t\t\t\t\t\tn.AddDependency(node.UID, r)\n\t\t\t\t\t\tnode.AddDependent(n.UID, r)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor k, rset := range rmap.DependenciesBySelector {\n\t\t\tif os, ok := rmap.ObjectSelectors[k]; ok {\n\t\t\t\tfor _, n := range resolveSelectorToNodes(os) {\n\t\t\t\t\tfor r := range rset {\n\t\t\t\t\t\tnode.AddDependency(n.UID, r)\n\t\t\t\t\t\tn.AddDependent(node.UID, r)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor k, rset := range rmap.DependentsBySelector {\n\t\t\tif os, ok := rmap.ObjectSelectors[k]; ok {\n\t\t\t\tfor _, n := range resolveSelectorToNodes(os) {\n\t\t\t\t\tfor r := range rset {\n\t\t\t\t\t\tn.AddDependency(node.UID, r)\n\t\t\t\t\t\tnode.AddDependent(n.UID, r)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor uid, rset := range rmap.DependenciesByUID {\n\t\t\tif n, ok := globalMapByUID[uid]; ok {\n\t\t\t\tfor r := range rset {\n\t\t\t\t\tnode.AddDependency(n.UID, r)\n\t\t\t\t\tn.AddDependent(node.UID, r)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor uid, rset := range rmap.DependentsByUID {\n\t\t\tif n, ok := globalMapByUID[uid]; ok {\n\t\t\t\tfor r := range rset {\n\t\t\t\t\tn.AddDependency(node.UID, r)\n\t\t\t\t\tnode.AddDependent(n.UID, r)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Populate dependencies & dependents based on Owner-Dependent relationships\n\tfor _, node := range globalMapByUID {\n\t\tfor _, ref := range node.OwnerReferences {\n\t\t\tif n, ok := globalMapByUID[ref.UID]; ok {\n\t\t\t\tif ref.Controller != nil && *ref.Controller {\n\t\t\t\t\tnode.AddDependency(n.UID, RelationshipControllerRef)\n\t\t\t\t\tn.AddDependent(node.UID, RelationshipControllerRef)\n\t\t\t\t}\n\t\t\t\tnode.AddDependency(n.UID, RelationshipOwnerRef)\n\t\t\t\tn.AddDependent(node.UID, RelationshipOwnerRef)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar rmap *RelationshipMap\n\tvar err error\n\tfor _, node := range globalMapByUID {\n\t\tswitch {\n\t\t// Populate dependencies & dependents based on PersistentVolume relationships\n\t\tcase node.Group == corev1.GroupName && node.Kind == \"PersistentVolume\":\n\t\t\trmap, err = getPersistentVolumeRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for persistentvolume named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on PersistentVolumeClaim relationships\n\t\tcase node.Group == corev1.GroupName && node.Kind == \"PersistentVolumeClaim\":\n\t\t\trmap, err = getPersistentVolumeClaimRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for persistentvolumeclaim named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on Pod relationships\n\t\tcase node.Group == corev1.GroupName && node.Kind == \"Pod\":\n\t\t\trmap, err = getPodRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for pod named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on Service relationships\n\t\tcase node.Group == corev1.GroupName && node.Kind == \"Service\":\n\t\t\trmap, err = getServiceRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for service named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on ServiceAccount relationships\n\t\tcase node.Group == corev1.GroupName && node.Kind == \"ServiceAccount\":\n\t\t\trmap, err = getServiceAccountRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for serviceaccount named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on PodSecurityPolicy relationships\n\t\tcase node.Group == policyv1beta1.GroupName && node.Kind == \"PodSecurityPolicy\":\n\t\t\trmap, err = getPodSecurityPolicyRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for podsecuritypolicy named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on PodDisruptionBudget relationships\n\t\tcase node.Group == policyv1.GroupName && node.Kind == \"PodDisruptionBudget\":\n\t\t\trmap, err = getPodDisruptionBudgetRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for poddisruptionbudget named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on MutatingWebhookConfiguration relationships\n\t\tcase node.Group == admissionregistrationv1.GroupName && node.Kind == \"MutatingWebhookConfiguration\":\n\t\t\trmap, err = getMutatingWebhookConfigurationRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for mutatingwebhookconfiguration named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on ValidatingWebhookConfiguration relationships\n\t\tcase node.Group == admissionregistrationv1.GroupName && node.Kind == \"ValidatingWebhookConfiguration\":\n\t\t\trmap, err = getValidatingWebhookConfigurationRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for validatingwebhookconfiguration named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on APIService relationships\n\t\tcase node.Group == apiregistrationv1.GroupName && node.Kind == \"APIService\":\n\t\t\trmap, err = getAPIServiceRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for apiservice named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on Event relationships\n\t\tcase (node.Group == eventsv1.GroupName || node.Group == corev1.GroupName) && node.Kind == \"Event\":\n\t\t\trmap, err = getEventRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for event named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on Ingress relationships\n\t\tcase (node.Group == networkingv1.GroupName || node.Group == extensionsv1beta1.GroupName) && node.Kind == \"Ingress\":\n\t\t\trmap, err = getIngressRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for ingress named \\\"%s\\\" in namespace \\\"%s\\\": %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on IngressClass relationships\n\t\tcase node.Group == networkingv1.GroupName && node.Kind == \"IngressClass\":\n\t\t\trmap, err = getIngressClassRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for ingressclass named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on NetworkPolicy relationships\n\t\tcase node.Group == networkingv1.GroupName && node.Kind == \"NetworkPolicy\":\n\t\t\trmap, err = getNetworkPolicyRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for networkpolicy named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on RuntimeClass relationships\n\t\tcase node.Group == nodev1.GroupName && node.Kind == \"RuntimeClass\":\n\t\t\trmap, err = getRuntimeClassRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for runtimeclass named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on ClusterRole relationships\n\t\tcase node.Group == rbacv1.GroupName && node.Kind == \"ClusterRole\":\n\t\t\trmap, err = getClusterRoleRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for clusterrole named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on ClusterRoleBinding relationships\n\t\tcase node.Group == rbacv1.GroupName && node.Kind == \"ClusterRoleBinding\":\n\t\t\trmap, err = getClusterRoleBindingRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for clusterrolebinding named \\\"%s\\\": %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on Role relationships\n\t\tcase node.Group == rbacv1.GroupName && node.Kind == \"Role\":\n\t\t\trmap, err = getRoleRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for role named \\\"%s\\\" in namespace \\\"%s\\\": %s: %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on RoleBinding relationships\n\t\tcase node.Group == rbacv1.GroupName && node.Kind == \"RoleBinding\":\n\t\t\trmap, err = getRoleBindingRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for rolebinding named \\\"%s\\\" in namespace \\\"%s\\\": %s: %s\", node.Name, node.Namespace, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on CSIStorageCapacity relationships\n\t\tcase node.Group == storagev1beta1.GroupName && node.Kind == \"CSIStorageCapacity\":\n\t\t\trmap, err = getCSIStorageCapacityRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for csistoragecapacity named \\\"%s\\\": %s: %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on CSINode relationships\n\t\tcase node.Group == storagev1.GroupName && node.Kind == \"CSINode\":\n\t\t\trmap, err = getCSINodeRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for csinode named \\\"%s\\\": %s: %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on StorageClass relationships\n\t\tcase node.Group == storagev1.GroupName && node.Kind == \"StorageClass\":\n\t\t\trmap, err = getStorageClassRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for storageclass named \\\"%s\\\": %s: %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t// Populate dependencies & dependents based on VolumeAttachment relationships\n\t\tcase node.Group == storagev1.GroupName && node.Kind == \"VolumeAttachment\":\n\t\t\trmap, err = getVolumeAttachmentRelationships(node)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to get relationships for volumeattachment named \\\"%s\\\": %s: %s\", node.Name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\t\tupdateRelationships(node, rmap)\n\t}\n\n\t// Create submap containing the provided objects & either their dependencies\n\t// or dependents from the global map\n\tvar depth uint\n\tnodeMap, uidQueue, uidSet := NodeMap{}, []types.UID{}, map[types.UID]struct{}{}\n\tfor _, uid := range uids {\n\t\tif node := globalMapByUID[uid]; node != nil {\n\t\t\tnodeMap[uid] = node\n\t\t\tuidQueue = append(uidQueue, uid)\n\t\t}\n\t}\n\tdepth, uidQueue = 0, append(uidQueue, \"\")\n\tfor {\n\t\tif len(uidQueue) <= 1 {\n\t\t\tbreak\n\t\t}\n\t\tuid := uidQueue[0]\n\t\tif uid == \"\" {\n\t\t\tdepth, uidQueue = depth+1, append(uidQueue[1:], \"\")\n\t\t\tcontinue\n\t\t}\n\n\t\t// Guard against possible cycles\n\t\tif _, ok := uidSet[uid]; ok {\n\t\t\tuidQueue = uidQueue[1:]\n\t\t\tcontinue\n\t\t} else {\n\t\t\tuidSet[uid] = struct{}{}\n\t\t}\n\n\t\tif node := nodeMap[uid]; node != nil {\n\t\t\t// Allow nodes to keep the smallest depth. For example, if a node has a\n\t\t\t// depth of 1 & 7 in the relationship tree, we keep 1 so that when\n\t\t\t// printing the tree with a depth of 2, the node will still be printed\n\t\t\tif node.Depth == 0 || depth < node.Depth {\n\t\t\t\tnode.Depth = depth\n\t\t\t}\n\t\t\tdeps := node.GetDeps(depsIsDependencies)\n\t\t\tdepUIDs, ix := make([]types.UID, len(deps)), 0\n\t\t\tfor depUID := range deps {\n\t\t\t\tnodeMap[depUID] = globalMapByUID[depUID]\n\t\t\t\tdepUIDs[ix] = depUID\n\t\t\t\tix++\n\t\t\t}\n\t\t\tuidQueue = append(uidQueue[1:], depUIDs...)\n\t\t}\n\t}\n\n\tklog.V(4).Infof(\"Resolved %d deps for %d objects\", len(nodeMap)-1, len(uids))\n\treturn nodeMap, nil\n}\n"
  },
  {
    "path": "internal/graph/helm.go",
    "content": "package graph\n\nconst (\n\t// Helm relationships.\n\tRelationshipHelmRelease Relationship = \"HelmRelease\"\n\tRelationshipHelmStorage Relationship = \"HelmStorage\"\n)\n"
  },
  {
    "path": "internal/graph/kubernetes.go",
    "content": "package graph\n\nimport (\n\t\"strings\"\n\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\teventsv1 \"k8s.io/api/events/v1\"\n\textensionsv1beta1 \"k8s.io/api/extensions/v1beta1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\tnodev1 \"k8s.io/api/node/v1\"\n\tpolicyv1 \"k8s.io/api/policy/v1\"\n\tpolicyv1beta1 \"k8s.io/api/policy/v1beta1\"\n\trbacv1 \"k8s.io/api/rbac/v1\"\n\tschedulingv1 \"k8s.io/api/scheduling/v1\"\n\tstoragev1 \"k8s.io/api/storage/v1\"\n\tstoragev1beta1 \"k8s.io/api/storage/v1beta1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/apiserver/pkg/authentication/serviceaccount\"\n\t\"k8s.io/apiserver/pkg/authentication/user\"\n\tapiregistrationv1 \"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1\"\n)\n\n// Well-known labels & annotations.\nconst (\n\t// Hardcode \"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util.ValidatedPSPAnnotation\"\n\t// as \"kubernetes.io/psp\" so we don't need import the entire k8s.io/kubernetes\n\t// package.\n\tValidatedPSPAnnotation = \"kubernetes.io/psp\"\n)\n\nconst (\n\t// Kubernetes APIService relationships.\n\tRelationshipAPIService Relationship = \"APIService\"\n\n\t// Kubernetes ClusterRole, ClusterRoleBinding, RoleBinding relationships.\n\tRelationshipClusterRoleAggregationRule Relationship = \"ClusterRoleAggregationRule\"\n\tRelationshipClusterRolePolicyRule      Relationship = \"ClusterRolePolicyRule\"\n\tRelationshipClusterRoleBindingSubject  Relationship = \"ClusterRoleBindingSubject\"\n\tRelationshipClusterRoleBindingRole     Relationship = \"ClusterRoleBindingRole\"\n\tRelationshipRoleBindingSubject         Relationship = \"RoleBindingSubject\"\n\tRelationshipRoleBindingRole            Relationship = \"RoleBindingRole\"\n\tRelationshipRolePolicyRule             Relationship = \"RolePolicyRule\"\n\n\t// Kubernetes CSINode relationships.\n\tRelationshipCSINodeDriver Relationship = \"CSINodeDriver\"\n\n\t// Kubernetes CSIStorageCapacity relationships.\n\tRelationshipCSIStorageCapacityStorageClass Relationship = \"CSIStorageCapacityStorageClass\"\n\n\t// Kubernetes Event relationships.\n\tRelationshipEventRegarding Relationship = \"EventRegarding\"\n\tRelationshipEventRelated   Relationship = \"EventRelated\"\n\n\t// Kubernetes Ingress & IngressClass relationships.\n\tRelationshipIngressClass           Relationship = \"IngressClass\"\n\tRelationshipIngressClassParameters Relationship = \"IngressClassParameters\"\n\tRelationshipIngressResource        Relationship = \"IngressResource\"\n\tRelationshipIngressService         Relationship = \"IngressService\"\n\tRelationshipIngressTLSSecret       Relationship = \"IngressTLSSecret\"\n\n\t// Kubernetes MutatingWebhookConfiguration & ValidatingWebhookConfiguration relationships.\n\tRelationshipWebhookConfigurationService Relationship = \"WebhookConfigurationService\"\n\n\t// Kubernetes RelationshipNetworkPolicy relationships.\n\tRelationshipNetworkPolicy Relationship = \"NetworkPolicy\"\n\n\t// Kubernetes Owner-Dependent relationships.\n\tRelationshipControllerRef Relationship = \"ControllerReference\"\n\tRelationshipOwnerRef      Relationship = \"OwnerReference\"\n\n\t// Kubernetes PersistentVolume & PersistentVolumeClaim relationships.\n\tRelationshipPersistentVolumeClaim           Relationship = \"PersistentVolumeClaim\"\n\tRelationshipPersistentVolumeCSIDriver       Relationship = \"PersistentVolumeCSIDriver\"\n\tRelationshipPersistentVolumeCSIDriverSecret Relationship = \"PersistentVolumeCSIDriverSecret\"\n\tRelationshipPersistentVolumeStorageClass    Relationship = \"PersistentVolumeStorageClass\"\n\n\t// Kubernetes Pod relationships.\n\tRelationshipPodContainerEnv          Relationship = \"PodContainerEnvironment\"\n\tRelationshipPodImagePullSecret       Relationship = \"PodImagePullSecret\" //nolint:gosec\n\tRelationshipPodNode                  Relationship = \"PodNode\"\n\tRelationshipPodPriorityClass         Relationship = \"PodPriorityClass\"\n\tRelationshipPodRuntimeClass          Relationship = \"PodRuntimeClass\"\n\tRelationshipPodSecurityPolicy        Relationship = \"PodSecurityPolicy\"\n\tRelationshipPodServiceAccount        Relationship = \"PodServiceAccount\"\n\tRelationshipPodVolume                Relationship = \"PodVolume\"\n\tRelationshipPodVolumeCSIDriver       Relationship = \"PodVolumeCSIDriver\"\n\tRelationshipPodVolumeCSIDriverSecret Relationship = \"PodVolumeCSIDriverSecret\" //nolint:gosec\n\n\t// Kubernetes PodDisruptionBudget relationships.\n\tRelationshipPodDisruptionBudget Relationship = \"PodDisruptionBudget\"\n\n\t// Kubernetes PodSecurityPolicy relationships.\n\tRelationshipPodSecurityPolicyAllowedCSIDriver    Relationship = \"PodSecurityPolicyAllowedCSIDriver\"\n\tRelationshipPodSecurityPolicyAllowedRuntimeClass Relationship = \"PodSecurityPolicyAllowedRuntimeClass\"\n\tRelationshipPodSecurityPolicyDefaultRuntimeClass Relationship = \"PodSecurityPolicyDefaultRuntimeClass\"\n\n\t// Kubernetes RuntimeClass relationships.\n\tRelationshipRuntimeClass Relationship = \"RuntimeClass\"\n\n\t// Kubernetes Service relationships.\n\tRelationshipService Relationship = \"Service\"\n\n\t// Kubernetes ServiceAccount relationships.\n\tRelationshipServiceAccountImagePullSecret Relationship = \"ServiceAccountImagePullSecret\"\n\tRelationshipServiceAccountSecret          Relationship = \"ServiceAccountSecret\"\n\n\t// Kubernetes StorageClass relationships.\n\tRelationshipStorageClassProvisioner Relationship = \"StorageClassProvisioner\"\n\n\t// Kubernetes VolumeAttachment relationships.\n\tRelationshipVolumeAttachmentAttacher                    Relationship = \"VolumeAttachmentAttacher\"\n\tRelationshipVolumeAttachmentNode                        Relationship = \"VolumeAttachmentNode\"\n\tRelationshipVolumeAttachmentSourceVolume                Relationship = \"VolumeAttachmentSourceVolume\"\n\tRelationshipVolumeAttachmentSourceVolumeClaim           Relationship = \"VolumeAttachmentSourceVolumeClaim\"\n\tRelationshipVolumeAttachmentSourceVolumeCSIDriver       Relationship = \"VolumeAttachmentSourceVolumeCSIDriver\"\n\tRelationshipVolumeAttachmentSourceVolumeCSIDriverSecret Relationship = \"VolumeAttachmentSourceVolumeCSIDriverSecret\"\n\tRelationshipVolumeAttachmentSourceVolumeStorageClass    Relationship = \"VolumeAttachmentSourceVolumeStorageClass\"\n)\n\n// getAPIServiceRelationships returns a map of relationships that this\n// APIService has with other objects, based on what was referenced in its\n// manifest.\nfunc getAPIServiceRelationships(n *Node) (*RelationshipMap, error) {\n\tvar apisvc apiregistrationv1.APIService\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &apisvc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipAPIService\n\tif svc := apisvc.Spec.Service; svc != nil {\n\t\tref = ObjectReference{Kind: \"Service\", Namespace: svc.Namespace, Name: svc.Name}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipAPIService)\n\t}\n\n\treturn &result, nil\n}\n\n// getClusterRoleRelationships returns a map of relationships that this\n// ClusterRole has with other objects, based on what was referenced in\n// its manifest.\nfunc getClusterRoleRelationships(n *Node) (*RelationshipMap, error) {\n\tvar cr rbacv1.ClusterRole\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &cr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar os ObjectSelector\n\tvar ols ObjectLabelSelector\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipClusterRoleAggregationRule\n\tif ar := cr.AggregationRule; ar != nil {\n\t\tfor ix := range ar.ClusterRoleSelectors {\n\t\t\tselector, err := metav1.LabelSelectorAsSelector(&ar.ClusterRoleSelectors[ix])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tols = ObjectLabelSelector{Group: rbacv1.GroupName, Kind: \"ClusterRole\", Selector: selector}\n\t\t\tresult.AddDependencyByLabelSelector(ols, RelationshipClusterRoleAggregationRule)\n\t\t}\n\t}\n\n\t// RelationshipClusterRolePolicyRule\n\tfor _, r := range cr.Rules {\n\t\tif podSecurityPolicyMatches(r) {\n\t\t\tswitch len(r.ResourceNames) {\n\t\t\tcase 0:\n\t\t\t\tos = ObjectSelector{Group: policyv1beta1.GroupName, Kind: \"PodSecurityPolicy\"}\n\t\t\t\tresult.AddDependencyBySelector(os, RelationshipClusterRolePolicyRule)\n\t\t\tdefault:\n\t\t\t\tfor _, n := range r.ResourceNames {\n\t\t\t\t\tref = ObjectReference{Group: policyv1beta1.GroupName, Kind: \"PodSecurityPolicy\", Name: n}\n\t\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipClusterRolePolicyRule)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getClusterRoleBindingRelationships returns a map of relationships that this\n// ClusterRoleBinding has with other objects, based on what was referenced in\n// its manifest.\n//nolint:gocognit\nfunc getClusterRoleBindingRelationships(n *Node) (*RelationshipMap, error) {\n\tvar crb rbacv1.ClusterRoleBinding\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &crb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar os ObjectSelector\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipClusterRoleBindingSubject\n\tfor _, s := range crb.Subjects {\n\t\tswitch s.Kind {\n\t\tcase rbacv1.ServiceAccountKind:\n\t\t\tif s.APIGroup == corev1.GroupName && s.Namespace != \"\" {\n\t\t\t\tref = ObjectReference{Kind: \"ServiceAccount\", Namespace: s.Namespace, Name: s.Name}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipClusterRoleBindingSubject)\n\t\t\t}\n\t\tcase rbacv1.GroupKind:\n\t\t\tif s.APIGroup == rbacv1.GroupName && s.Namespace == \"\" {\n\t\t\t\tswitch {\n\t\t\t\t// All ServiceAccounts in any namespace (authenticated users)\n\t\t\t\tcase s.Name == user.AllAuthenticated:\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\"}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipClusterRoleBindingSubject)\n\t\t\t\t// All ServiceAccounts in any namespace\n\t\t\t\tcase s.Name == serviceaccount.AllServiceAccountsGroup:\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\"}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipClusterRoleBindingSubject)\n\t\t\t\t// All ServiceAccounts in the namespace (extracted from the SA group)\n\t\t\t\tcase strings.HasPrefix(s.Name, serviceaccount.ServiceAccountGroupPrefix):\n\t\t\t\t\tsns := s.Name[len(serviceaccount.ServiceAccountGroupPrefix):]\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\", Namespaces: sets.NewString(sns)}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipClusterRoleBindingSubject)\n\t\t\t\t}\n\t\t\t}\n\t\tcase rbacv1.UserKind:\n\t\t\tif s.APIGroup == rbacv1.GroupName && s.Namespace == \"\" {\n\t\t\t\tns, sa, err := serviceaccount.SplitUsername(s.Name)\n\t\t\t\tif err == nil {\n\t\t\t\t\tref = ObjectReference{Kind: \"ServiceAccount\", Namespace: ns, Name: sa}\n\t\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipClusterRoleBindingSubject)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// RelationshipClusterRoleBindingRole\n\tr := crb.RoleRef\n\tif r.APIGroup == rbacv1.GroupName && r.Kind == \"ClusterRole\" {\n\t\tref = ObjectReference{Group: rbacv1.GroupName, Kind: \"ClusterRole\", Name: r.Name}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipRoleBindingRole)\n\t}\n\n\treturn &result, nil\n}\n\n// getCSINodeRelationships returns a map of relationships that this CSINode has\n// with other objects, based on what was referenced in its manifest.\nfunc getCSINodeRelationships(n *Node) (*RelationshipMap, error) {\n\tvar csin storagev1.CSINode\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &csin)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipCSINodeDriver\n\tfor _, d := range csin.Spec.Drivers {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: d.Name}\n\t\tresult.AddDependentByKey(ref.Key(), RelationshipCSINodeDriver)\n\t}\n\n\treturn &result, nil\n}\n\n// getCSIStorageCapacityRelationships returns a map of relationships that this\n// CSIStorageCapacity has with other objects, based on what was referenced in\n// its manifest.\nfunc getCSIStorageCapacityRelationships(n *Node) (*RelationshipMap, error) {\n\tvar csisc storagev1beta1.CSIStorageCapacity\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &csisc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipCSIStorageCapacityStorageClass\n\tif sc := csisc.StorageClassName; len(sc) > 0 {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"StorageClass\", Name: sc}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipCSIStorageCapacityStorageClass)\n\t}\n\n\treturn &result, nil\n}\n\n// getEventRelationships returns a map of relationships that this Event has with\n// other objects, based on what was referenced in its manifest.\n//nolint:unparam\nfunc getEventRelationships(n *Node) (*RelationshipMap, error) {\n\tresult := newRelationshipMap()\n\tswitch n.Group {\n\tcase corev1.GroupName:\n\t\t// RelationshipEventRegarding\n\t\tregUID := types.UID(n.GetNestedString(\"involvedobject\", \"uid\"))\n\t\tresult.AddDependencyByUID(regUID, RelationshipEventRegarding)\n\tcase eventsv1.GroupName:\n\t\t// RelationshipEventRegarding\n\t\tregUID := types.UID(n.GetNestedString(\"regarding\", \"uid\"))\n\t\tresult.AddDependencyByUID(regUID, RelationshipEventRegarding)\n\t\t// RelationshipEventRelated\n\t\trelUID := types.UID(n.GetNestedString(\"related\", \"uid\"))\n\t\tresult.AddDependencyByUID(relUID, RelationshipEventRelated)\n\t}\n\n\treturn &result, nil\n}\n\n// getIngressRelationships returns a map of relationships that this Ingress has\n// with other objects, based on what was referenced in its manifest.\n//nolint:funlen,gocognit\nfunc getIngressRelationships(n *Node) (*RelationshipMap, error) {\n\tvar ref ObjectReference\n\tns := n.Namespace\n\tresult := newRelationshipMap()\n\tswitch n.Group {\n\tcase extensionsv1beta1.GroupName:\n\t\tvar ing extensionsv1beta1.Ingress\n\t\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &ing)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// RelationshipIngressClass\n\t\tif ingc := ing.Spec.IngressClassName; ingc != nil && len(*ingc) > 0 {\n\t\t\tref = ObjectReference{Group: networkingv1.GroupName, Kind: \"IngressClass\", Name: *ingc}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressClass)\n\t\t}\n\n\t\t// RelationshipIngressResource\n\t\t// RelationshipIngressService\n\t\tvar backends []extensionsv1beta1.IngressBackend\n\t\tif ing.Spec.Backend != nil {\n\t\t\tbackends = append(backends, *ing.Spec.Backend)\n\t\t}\n\t\tfor _, rule := range ing.Spec.Rules {\n\t\t\tif rule.HTTP != nil {\n\t\t\t\tfor _, path := range rule.HTTP.Paths {\n\t\t\t\t\tbackends = append(backends, path.Backend)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, b := range backends {\n\t\t\tswitch {\n\t\t\tcase b.Resource != nil:\n\t\t\t\tgroup := \"\"\n\t\t\t\tif b.Resource.APIGroup != nil {\n\t\t\t\t\tgroup = *b.Resource.APIGroup\n\t\t\t\t}\n\t\t\t\tref = ObjectReference{Group: group, Kind: b.Resource.Kind, Name: b.Resource.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressResource)\n\t\t\tcase b.ServiceName != \"\":\n\t\t\t\tref = ObjectReference{Kind: \"Service\", Name: b.ServiceName, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressService)\n\t\t\t}\n\t\t}\n\n\t\t// RelationshipIngressTLSSecret\n\t\tfor _, tls := range ing.Spec.TLS {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: tls.SecretName, Namespace: ns}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressClass)\n\t\t}\n\tcase networkingv1.GroupName:\n\t\tvar ing networkingv1.Ingress\n\t\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &ing)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// RelationshipIngressClass\n\t\tif ingc := ing.Spec.IngressClassName; ingc != nil && len(*ingc) > 0 {\n\t\t\tref = ObjectReference{Group: networkingv1.GroupName, Kind: \"IngressClass\", Name: *ingc}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressClass)\n\t\t}\n\n\t\t// RelationshipIngressResource\n\t\t// RelationshipIngressService\n\t\tvar backends []networkingv1.IngressBackend\n\t\tif ing.Spec.DefaultBackend != nil {\n\t\t\tbackends = append(backends, *ing.Spec.DefaultBackend)\n\t\t}\n\t\tfor _, rule := range ing.Spec.Rules {\n\t\t\tif rule.HTTP != nil {\n\t\t\t\tfor _, path := range rule.HTTP.Paths {\n\t\t\t\t\tbackends = append(backends, path.Backend)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, b := range backends {\n\t\t\tswitch {\n\t\t\tcase b.Resource != nil:\n\t\t\t\tgroup := \"\"\n\t\t\t\tif b.Resource.APIGroup != nil {\n\t\t\t\t\tgroup = *b.Resource.APIGroup\n\t\t\t\t}\n\t\t\t\tref = ObjectReference{Group: group, Kind: b.Resource.Kind, Name: b.Resource.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressResource)\n\t\t\tcase b.Service != nil:\n\t\t\t\tref = ObjectReference{Kind: \"Service\", Name: b.Service.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressService)\n\t\t\t}\n\t\t}\n\n\t\t// RelationshipIngressTLSSecret\n\t\tfor _, tls := range ing.Spec.TLS {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: tls.SecretName, Namespace: ns}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressClass)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getIngressClassRelationships returns a map of relationships that this\n// IngressClass has with other objects, based on what was referenced in its\n// manifest.\nfunc getIngressClassRelationships(n *Node) (*RelationshipMap, error) {\n\tvar ingc networkingv1.IngressClass\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &ingc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipIngressClassParameters\n\tif p := ingc.Spec.Parameters; p != nil {\n\t\tgroup := \"\"\n\t\tif p.APIGroup != nil {\n\t\t\tgroup = *p.APIGroup\n\t\t}\n\t\tns := \"\"\n\t\tif p.Namespace != nil {\n\t\t\tns = *p.Namespace\n\t\t}\n\t\tref = ObjectReference{Group: group, Kind: p.Kind, Namespace: ns, Name: p.Name}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipIngressClassParameters)\n\t}\n\n\treturn &result, nil\n}\n\n// getMutatingWebhookConfigurationRelationships returns a map of relationships\n// that this MutatingWebhookConfiguration has with other objects, based on what\n// was referenced in its manifest.\nfunc getMutatingWebhookConfigurationRelationships(n *Node) (*RelationshipMap, error) {\n\tvar mwc admissionregistrationv1.MutatingWebhookConfiguration\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &mwc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipWebhookConfigurationService\n\tfor _, wh := range mwc.Webhooks {\n\t\tif svc := wh.ClientConfig.Service; svc != nil {\n\t\t\tref = ObjectReference{Kind: \"Service\", Namespace: svc.Namespace, Name: svc.Name}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipWebhookConfigurationService)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getNetworkPolicyRelationships returns a map of relationships that this\n// NetworkPolicy has with other objects, based on what was referenced in its\n// manifest.\nfunc getNetworkPolicyRelationships(n *Node) (*RelationshipMap, error) {\n\tvar netpol networkingv1.NetworkPolicy\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &netpol)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ols ObjectLabelSelector\n\tns := netpol.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipNetworkPolicy\n\tselector, err := metav1.LabelSelectorAsSelector(&netpol.Spec.PodSelector)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tols = ObjectLabelSelector{Kind: \"Pod\", Namespace: ns, Selector: selector}\n\tresult.AddDependencyByLabelSelector(ols, RelationshipNetworkPolicy)\n\n\treturn &result, nil\n}\n\n// getPersistentVolumeRelationships returns a map of relationships that this\n// PersistentVolume has with other objects, based on what was referenced in its\n// manifest.\nfunc getPersistentVolumeRelationships(n *Node) (*RelationshipMap, error) {\n\tvar pv corev1.PersistentVolume\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &pv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tns := pv.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipPersistentVolumeClaim\n\tif pvcRef := pv.Spec.ClaimRef; pvcRef != nil {\n\t\tref = ObjectReference{Kind: \"PersistentVolumeClaim\", Name: pvcRef.Name, Namespace: ns}\n\t\tresult.AddDependentByKey(ref.Key(), RelationshipPersistentVolumeClaim)\n\t}\n\n\t// RelationshipPersistentVolumeCSIDriver\n\t// RelationshipPersistentVolumeCSIDriverSecret\n\t//nolint:gocritic\n\tswitch {\n\tcase pv.Spec.PersistentVolumeSource.CSI != nil:\n\t\tcsi := pv.Spec.PersistentVolumeSource.CSI\n\t\tif d := csi.Driver; len(d) > 0 {\n\t\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: d}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPersistentVolumeCSIDriver)\n\t\t}\n\t\tif ces := csi.ControllerExpandSecretRef; ces != nil {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: ces.Name, Namespace: ces.Namespace}\n\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipPersistentVolumeCSIDriverSecret)\n\t\t}\n\t\tif cps := csi.ControllerPublishSecretRef; cps != nil {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: cps.Name, Namespace: cps.Namespace}\n\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipPersistentVolumeCSIDriverSecret)\n\t\t}\n\t\tif nps := csi.NodePublishSecretRef; nps != nil {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: nps.Name, Namespace: nps.Namespace}\n\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipPersistentVolumeCSIDriverSecret)\n\t\t}\n\t\tif nss := csi.NodeStageSecretRef; nss != nil {\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: nss.Name, Namespace: nss.Namespace}\n\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipPersistentVolumeCSIDriverSecret)\n\t\t}\n\t}\n\n\t// RelationshipPersistentVolumeStorageClass\n\tif sc := pv.Spec.StorageClassName; len(sc) > 0 {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"StorageClass\", Name: sc}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPersistentVolumeStorageClass)\n\t}\n\n\treturn &result, nil\n}\n\n// getPersistentVolumeClaimRelationships returns a map of relationships that\n// this PersistentVolumeClaim has with other objects, based on what was\n// referenced in its manifest.\nfunc getPersistentVolumeClaimRelationships(n *Node) (*RelationshipMap, error) {\n\tvar pvc corev1.PersistentVolumeClaim\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &pvc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipPersistentVolumeClaim\n\tif pv := pvc.Spec.VolumeName; len(pv) > 0 {\n\t\tref = ObjectReference{Kind: \"PersistentVolume\", Name: pv}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPersistentVolumeClaim)\n\t}\n\n\treturn &result, nil\n}\n\n// getPodRelationships returns a map of relationships that this Pod has with\n// other objects, based on what was referenced in its manifest.\n//nolint:funlen,gocognit\nfunc getPodRelationships(n *Node) (*RelationshipMap, error) {\n\tvar pod corev1.Pod\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &pod)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tns := pod.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipPodContainerEnv\n\tvar cList []corev1.Container\n\tcList = append(cList, pod.Spec.InitContainers...)\n\tcList = append(cList, pod.Spec.Containers...)\n\tfor _, c := range cList {\n\t\tfor _, env := range c.EnvFrom {\n\t\t\tswitch {\n\t\t\tcase env.ConfigMapRef != nil:\n\t\t\t\tref = ObjectReference{Kind: \"ConfigMap\", Name: env.ConfigMapRef.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodContainerEnv)\n\t\t\tcase env.SecretRef != nil:\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: env.SecretRef.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodContainerEnv)\n\t\t\t}\n\t\t}\n\t\tfor _, env := range c.Env {\n\t\t\tif env.ValueFrom == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tswitch {\n\t\t\tcase env.ValueFrom.ConfigMapKeyRef != nil:\n\t\t\t\tref = ObjectReference{Kind: \"ConfigMap\", Name: env.ValueFrom.ConfigMapKeyRef.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodContainerEnv)\n\t\t\tcase env.ValueFrom.SecretKeyRef != nil:\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: env.ValueFrom.SecretKeyRef.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodContainerEnv)\n\t\t\t}\n\t\t}\n\t}\n\n\t// RelationshipPodImagePullSecret\n\tfor _, ips := range pod.Spec.ImagePullSecrets {\n\t\tref = ObjectReference{Kind: \"Secret\", Name: ips.Name, Namespace: ns}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodImagePullSecret)\n\t}\n\n\t// RelationshipPodNode\n\tref = ObjectReference{Kind: \"Node\", Name: pod.Spec.NodeName}\n\tresult.AddDependencyByKey(ref.Key(), RelationshipPodNode)\n\n\t// RelationshipPodPriorityClass\n\tif pc := pod.Spec.PriorityClassName; len(pc) != 0 {\n\t\tref = ObjectReference{Group: schedulingv1.GroupName, Kind: \"PriorityClass\", Name: pc}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodPriorityClass)\n\t}\n\n\t// RelationshipPodRuntimeClass\n\tif rc := pod.Spec.RuntimeClassName; rc != nil && len(*rc) != 0 {\n\t\tref = ObjectReference{Group: nodev1.GroupName, Kind: \"RuntimeClass\", Name: *rc}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodRuntimeClass)\n\t}\n\n\t// RelationshipPodSecurityPolicy\n\tif psp, ok := pod.Annotations[ValidatedPSPAnnotation]; ok {\n\t\tref = ObjectReference{Group: policyv1beta1.GroupName, Kind: \"PodSecurityPolicy\", Name: psp}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodSecurityPolicy)\n\t}\n\n\t// RelationshipPodServiceAccount\n\tif sa := pod.Spec.ServiceAccountName; len(sa) != 0 {\n\t\tref = ObjectReference{Kind: \"ServiceAccount\", Name: sa, Namespace: ns}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodServiceAccount)\n\t}\n\n\t// RelationshipPodVolume\n\t// RelationshipPodVolumeCSIDriver\n\t// RelationshipPodVolumeCSIDriverSecret\n\tfor _, v := range pod.Spec.Volumes {\n\t\tvs := v.VolumeSource\n\t\tswitch {\n\t\tcase vs.ConfigMap != nil:\n\t\t\tref = ObjectReference{Kind: \"ConfigMap\", Name: vs.ConfigMap.Name, Namespace: ns}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolume)\n\t\tcase vs.CSI != nil:\n\t\t\tcsi := vs.CSI\n\t\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: csi.Driver}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolumeCSIDriver)\n\t\t\tif nps := csi.NodePublishSecretRef; nps != nil {\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: nps.Name, Namespace: ns}\n\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolumeCSIDriverSecret)\n\t\t\t}\n\t\tcase vs.PersistentVolumeClaim != nil:\n\t\t\tref = ObjectReference{Kind: \"PersistentVolumeClaim\", Name: vs.PersistentVolumeClaim.ClaimName, Namespace: ns}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolume)\n\t\tcase vs.Projected != nil:\n\t\t\tfor _, src := range vs.Projected.Sources {\n\t\t\t\tswitch {\n\t\t\t\tcase src.ConfigMap != nil:\n\t\t\t\t\tref = ObjectReference{Kind: \"ConfigMap\", Name: src.ConfigMap.Name, Namespace: ns}\n\t\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolume)\n\t\t\t\tcase src.Secret != nil:\n\t\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: src.Secret.Name, Namespace: ns}\n\t\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolume)\n\t\t\t\t}\n\t\t\t}\n\t\tcase vs.Secret != nil:\n\t\t\tref = ObjectReference{Kind: \"Secret\", Name: vs.Secret.SecretName, Namespace: ns}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodVolume)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getPodDisruptionBudgetRelationships returns a map of relationships that this\n// PodDisruptionBudget has with other objects, based on what was referenced in its\n// manifest.\nfunc getPodDisruptionBudgetRelationships(n *Node) (*RelationshipMap, error) {\n\tvar pdb policyv1.PodDisruptionBudget\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &pdb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ols ObjectLabelSelector\n\tns := pdb.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipPodDisruptionBudget\n\tif s := pdb.Spec.Selector; s != nil {\n\t\tselector, err := metav1.LabelSelectorAsSelector(s)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tols = ObjectLabelSelector{Kind: \"Pod\", Namespace: ns, Selector: selector}\n\t\tresult.AddDependencyByLabelSelector(ols, RelationshipPodDisruptionBudget)\n\t}\n\n\treturn &result, nil\n}\n\n// getPodSecurityPolicyRelationships returns a map of relationships that this\n// PodSecurityPolicy has with other objects, based on what was referenced in its\n// manifest.\nfunc getPodSecurityPolicyRelationships(n *Node) (*RelationshipMap, error) {\n\tvar psp policyv1beta1.PodSecurityPolicy\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &psp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipPodSecurityPolicyAllowedCSIDriver\n\tfor _, csi := range psp.Spec.AllowedCSIDrivers {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: csi.Name}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodSecurityPolicyAllowedCSIDriver)\n\t}\n\tif rc := psp.Spec.RuntimeClass; rc != nil {\n\t\t// RelationshipPodSecurityPolicyAllowedRuntimeClass\n\t\tfor _, n := range psp.Spec.RuntimeClass.AllowedRuntimeClassNames {\n\t\t\tref = ObjectReference{Group: nodev1.GroupName, Kind: \"RuntimeClass\", Name: n}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodSecurityPolicyAllowedRuntimeClass)\n\t\t}\n\n\t\t// RelationshipPodSecurityPolicyDefaultRuntimeClass\n\t\tif n := psp.Spec.RuntimeClass.DefaultRuntimeClassName; n != nil {\n\t\t\tref = ObjectReference{Group: nodev1.GroupName, Kind: \"RuntimeClass\", Name: *n}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipPodSecurityPolicyDefaultRuntimeClass)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getRoleRelationships returns a map of relationships that this Role has with\n// other objects, based on what was referenced in its manifest.\nfunc getRoleRelationships(n *Node) (*RelationshipMap, error) {\n\tvar ro rbacv1.Role\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &ro)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar os ObjectSelector\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipRolePolicyRule\n\tfor _, r := range ro.Rules {\n\t\tif podSecurityPolicyMatches(r) {\n\t\t\tswitch len(r.ResourceNames) {\n\t\t\tcase 0:\n\t\t\t\tos = ObjectSelector{Group: policyv1beta1.GroupName, Kind: \"PodSecurityPolicy\"}\n\t\t\t\tresult.AddDependencyBySelector(os, RelationshipRolePolicyRule)\n\t\t\tdefault:\n\t\t\t\tfor _, n := range r.ResourceNames {\n\t\t\t\t\tref = ObjectReference{Group: policyv1beta1.GroupName, Kind: \"PodSecurityPolicy\", Name: n}\n\t\t\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipRolePolicyRule)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getRoleBindingRelationships returns a map of relationships that this\n// RoleBinding has with other objects, based on what was referenced in its\n// manifest.\n//nolint:funlen,gocognit\nfunc getRoleBindingRelationships(n *Node) (*RelationshipMap, error) {\n\tvar rb rbacv1.RoleBinding\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &rb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar os ObjectSelector\n\tvar ref ObjectReference\n\tns := rb.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipRoleBindingSubject\n\tfor _, s := range rb.Subjects {\n\t\tswitch s.Kind {\n\t\tcase rbacv1.ServiceAccountKind:\n\t\t\tif s.APIGroup == corev1.GroupName && s.Namespace != \"\" {\n\t\t\t\tref = ObjectReference{Kind: \"ServiceAccount\", Namespace: s.Namespace, Name: s.Name}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipRoleBindingSubject)\n\t\t\t}\n\t\tcase rbacv1.GroupKind:\n\t\t\tif s.APIGroup == rbacv1.GroupName && s.Namespace == \"\" {\n\t\t\t\tswitch {\n\t\t\t\t// All ServiceAccounts in the RoleBinding namespace (authenticated users)\n\t\t\t\tcase s.Name == user.AllAuthenticated:\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\", Namespaces: sets.NewString(ns)}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipRoleBindingSubject)\n\t\t\t\t// All ServiceAccounts in the RoleBinding namespace\n\t\t\t\tcase s.Name == serviceaccount.AllServiceAccountsGroup:\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\", Namespaces: sets.NewString(ns)}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipRoleBindingSubject)\n\t\t\t\t// All ServiceAccounts in the namespace (extracted from the SA group)\n\t\t\t\tcase strings.HasPrefix(s.Name, serviceaccount.ServiceAccountGroupPrefix):\n\t\t\t\t\tsns := s.Name[len(serviceaccount.ServiceAccountGroupPrefix):]\n\t\t\t\t\tos = ObjectSelector{Kind: \"ServiceAccount\", Namespaces: sets.NewString(sns)}\n\t\t\t\t\tresult.AddDependentBySelector(os, RelationshipRoleBindingSubject)\n\t\t\t\t}\n\t\t\t}\n\t\tcase rbacv1.UserKind:\n\t\t\tif s.APIGroup == rbacv1.GroupName && s.Namespace == \"\" {\n\t\t\t\tns, sa, err := serviceaccount.SplitUsername(s.Name)\n\t\t\t\tif err == nil {\n\t\t\t\t\tref = ObjectReference{Kind: \"ServiceAccount\", Namespace: ns, Name: sa}\n\t\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipRoleBindingSubject)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// RelationshipRoleBindingRole\n\tif r := rb.RoleRef; r.APIGroup == rbacv1.GroupName {\n\t\tswitch r.Kind {\n\t\tcase \"ClusterRole\":\n\t\t\tref = ObjectReference{Group: rbacv1.GroupName, Kind: \"ClusterRole\", Name: r.Name}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipRoleBindingRole)\n\t\tcase \"Role\":\n\t\t\tref = ObjectReference{Group: rbacv1.GroupName, Kind: \"Role\", Namespace: ns, Name: r.Name}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipRoleBindingRole)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getRuntimeClassRelationships returns a map of relationships that this\n// RuntimeClass has with other objects, based on what was referenced in its\n// manifest.\nfunc getRuntimeClassRelationships(n *Node) (*RelationshipMap, error) {\n\tvar rc nodev1.RuntimeClass\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &rc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ols ObjectLabelSelector\n\tresult := newRelationshipMap()\n\n\t// RelationshipRuntimeClass\n\tif s := rc.Scheduling; s != nil {\n\t\tselector, err := labels.ValidatedSelectorFromSet(labels.Set(s.NodeSelector))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tols = ObjectLabelSelector{Kind: \"Node\", Selector: selector}\n\t\tresult.AddDependencyByLabelSelector(ols, RelationshipRuntimeClass)\n\t}\n\n\treturn &result, nil\n}\n\n// getServiceRelationships returns a map of relationships that this\n// Service has with other objects, based on what was referenced in its\n// manifest.\nfunc getServiceRelationships(n *Node) (*RelationshipMap, error) {\n\tvar svc corev1.Service\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &svc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ols ObjectLabelSelector\n\tns := svc.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipService\n\tselector, err := labels.ValidatedSelectorFromSet(labels.Set(svc.Spec.Selector))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tols = ObjectLabelSelector{Kind: \"Pod\", Namespace: ns, Selector: selector}\n\tresult.AddDependencyByLabelSelector(ols, RelationshipService)\n\n\treturn &result, nil\n}\n\n// getServiceAccountRelationships returns a map of relationships that this\n// ServiceAccount has with other objects, based on what was referenced in its\n// manifest.\nfunc getServiceAccountRelationships(n *Node) (*RelationshipMap, error) {\n\tvar sa corev1.ServiceAccount\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &sa)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tns := sa.Namespace\n\tresult := newRelationshipMap()\n\n\t// RelationshipServiceAccountImagePullSecret\n\tfor _, s := range sa.ImagePullSecrets {\n\t\tref = ObjectReference{Kind: \"Secret\", Name: s.Name, Namespace: ns}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipServiceAccountImagePullSecret)\n\t}\n\n\t// RelationshipServiceAccountSecret\n\tfor _, s := range sa.Secrets {\n\t\tref = ObjectReference{Kind: \"Secret\", Name: s.Name, Namespace: ns}\n\t\tresult.AddDependentByKey(ref.Key(), RelationshipServiceAccountSecret)\n\t}\n\n\treturn &result, nil\n}\n\n// getStorageClassRelationships returns a map of relationships that this\n// StorageClass has with other objects, based on what was referenced in its\n// manifest.\nfunc getStorageClassRelationships(n *Node) (*RelationshipMap, error) {\n\tvar sc storagev1.StorageClass\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &sc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipStorageClassProvisioner (external provisioners only)\n\tif p := sc.Provisioner; len(p) > 0 && !strings.HasPrefix(p, \"kubernetes.io/\") {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: p}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipStorageClassProvisioner)\n\t}\n\n\treturn &result, nil\n}\n\n// getValidatingWebhookConfigurationRelationships returns a map of relationships\n// that this ValidatingWebhookConfiguration has with other objects, based on\n// what was referenced in its manifest.\nfunc getValidatingWebhookConfigurationRelationships(n *Node) (*RelationshipMap, error) {\n\tvar vwc admissionregistrationv1.ValidatingWebhookConfiguration\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &vwc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipWebhookConfigurationService\n\tfor _, wh := range vwc.Webhooks {\n\t\tif svc := wh.ClientConfig.Service; svc != nil {\n\t\t\tref = ObjectReference{Kind: \"Service\", Namespace: svc.Namespace, Name: svc.Name}\n\t\t\tresult.AddDependencyByKey(ref.Key(), RelationshipWebhookConfigurationService)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// getVolumeAttachmentRelationships returns a map of relationships that this\n// VolumeAttachment has with other objects, based on what was referenced in its\n// manifest.\n//nolint:funlen,nestif\nfunc getVolumeAttachmentRelationships(n *Node) (*RelationshipMap, error) {\n\tvar va storagev1.VolumeAttachment\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(n.UnstructuredContent(), &va)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ref ObjectReference\n\tresult := newRelationshipMap()\n\n\t// RelationshipVolumeAttachmentAttacher\n\tif a := va.Spec.Attacher; len(a) > 0 {\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: a}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipVolumeAttachmentAttacher)\n\t}\n\n\t// RelationshipVolumeAttachmentNode\n\tif n := va.Spec.NodeName; len(n) > 0 {\n\t\tref = ObjectReference{Kind: \"Node\", Name: n}\n\t\tresult.AddDependencyByKey(ref.Key(), RelationshipVolumeAttachmentNode)\n\t}\n\n\t// RelationshipVolumeAttachmentSourceVolume\n\tif pvName := va.Spec.Source.PersistentVolumeName; pvName != nil && len(*pvName) > 0 {\n\t\tref = ObjectReference{Kind: \"PersistentVolume\", Name: *pvName}\n\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolume)\n\t}\n\n\tif iv := va.Spec.Source.InlineVolumeSpec; iv != nil {\n\t\t// RelationshipVolumeAttachmentSourceVolumeClaim\n\t\tif iv.ClaimRef != nil {\n\t\t\tref = ObjectReference{Kind: \"PersistentVolumeClaim\", Name: iv.ClaimRef.Name, Namespace: iv.ClaimRef.Namespace}\n\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeClaim)\n\t\t}\n\n\t\t// RelationshipVolumeAttachmentSourceVolumeStorageClass\n\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"StorageClass\", Name: iv.StorageClassName}\n\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeStorageClass)\n\n\t\t// RelationshipVolumeAttachmentSourceVolumeCSIDriver\n\t\t// RelationshipVolumeAttachmentSourceVolumeCSIDriverSecret\n\t\t//nolint:gocritic\n\t\tswitch {\n\t\tcase iv.PersistentVolumeSource.CSI != nil:\n\t\t\tcsi := iv.PersistentVolumeSource.CSI\n\t\t\tif d := csi.Driver; len(d) > 0 {\n\t\t\t\tref = ObjectReference{Group: storagev1.GroupName, Kind: \"CSIDriver\", Name: csi.Driver}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeCSIDriver)\n\t\t\t}\n\t\t\tif ces := csi.ControllerExpandSecretRef; ces != nil {\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: ces.Name, Namespace: ces.Namespace}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeCSIDriverSecret)\n\t\t\t}\n\t\t\tif cps := csi.ControllerPublishSecretRef; cps != nil {\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: cps.Name, Namespace: cps.Namespace}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeCSIDriverSecret)\n\t\t\t}\n\t\t\tif nps := csi.NodePublishSecretRef; nps != nil {\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: nps.Name, Namespace: nps.Namespace}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeCSIDriverSecret)\n\t\t\t}\n\t\t\tif nss := csi.NodeStageSecretRef; nss != nil {\n\t\t\t\tref = ObjectReference{Kind: \"Secret\", Name: nss.Name, Namespace: nss.Namespace}\n\t\t\t\tresult.AddDependentByKey(ref.Key(), RelationshipVolumeAttachmentSourceVolumeCSIDriverSecret)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n// podSecurityPolicyMatches returns true if PolicyRule matches \"policy\" APIGroup,\n// \"podsecuritypolicies\" resource & \"use\" verb.\nfunc podSecurityPolicyMatches(r rbacv1.PolicyRule) bool {\n\t// NOTE: As of Kubernetes v1.22.1, the PodSecurityPolicy admission controller\n\t// \t     still checks against extensions API group for backward compatibility\n\t//       so we're going to do the same over here.\n\t//       See https://github.com/kubernetes/kubernetes/blob/v1.22.1/plugin/pkg/admission/security/podsecuritypolicy/admission.go#L346\n\tif sets.NewString(r.APIGroups...).HasAny(rbacv1.APIGroupAll, extensionsv1beta1.GroupName, policyv1beta1.GroupName) {\n\t\tif sets.NewString(r.Resources...).HasAny(rbacv1.ResourceAll, \"podsecuritypolicies\") {\n\t\t\tif sets.NewString(r.Verbs...).HasAny(rbacv1.VerbAll, \"use\") {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/log/log.go",
    "content": "package log\n\nimport (\n\tgoflag \"flag\"\n\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/klog/v2\"\n)\n\n// AddFlags adds flags for logging.\nfunc AddFlags(flags *pflag.FlagSet) {\n\tklogFlagSet := goflag.NewFlagSet(\"klog\", goflag.ContinueOnError)\n\tklog.InitFlags(klogFlagSet)\n\tflags.AddGoFlagSet(klogFlagSet)\n\n\t// Logs are written to standard error instead of to files\n\t_ = flags.Set(\"logtostderr\", \"true\")\n\n\t// Hide log flags to make our help command consistent with kubectl\n\t_ = flags.MarkHidden(\"add_dir_header\")\n\t_ = flags.MarkHidden(\"alsologtostderr\")\n\t_ = flags.MarkHidden(\"log_backtrace_at\")\n\t_ = flags.MarkHidden(\"log_dir\")\n\t_ = flags.MarkHidden(\"log_file\")\n\t_ = flags.MarkHidden(\"log_file_max_size\")\n\t_ = flags.MarkHidden(\"logtostderr\")\n\t_ = flags.MarkHidden(\"one_output\")\n\t_ = flags.MarkHidden(\"skip_headers\")\n\t_ = flags.MarkHidden(\"skip_log_headers\")\n\t_ = flags.MarkHidden(\"stderrthreshold\")\n\t_ = flags.MarkHidden(\"v\")\n\t_ = flags.MarkHidden(\"vmodule\")\n}\n"
  },
  {
    "path": "internal/printers/flags.go",
    "content": "package printers\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/client\"\n)\n\nconst (\n\tflagOutputFormat          = \"output\"\n\tflagOutputFormatShorthand = \"o\"\n)\n\n// Flags composes common printer flag structs used in the command.\ntype Flags struct {\n\tHumanReadableFlags *HumanPrintFlags\n\tOutputFormat       *string\n}\n\n// AddFlags receives a *pflag.FlagSet reference and binds flags related to\n// human-readable printing to it.\nfunc (f *Flags) AddFlags(flags *pflag.FlagSet) {\n\tf.HumanReadableFlags.AddFlags(flags)\n\n\tif f.OutputFormat != nil {\n\t\tflags.StringVarP(f.OutputFormat, flagOutputFormat, flagOutputFormatShorthand, *f.OutputFormat, fmt.Sprintf(\"Output format. One of: %s.\", strings.Join(f.AllowedFormats(), \"|\")))\n\t}\n}\n\n// AllowedFormats is the list of formats in which data can be displayed.\nfunc (f *Flags) AllowedFormats() []string {\n\tformats := []string{}\n\tformats = append(formats, f.HumanReadableFlags.AllowedFormats()...)\n\treturn formats\n}\n\n// Copy returns a copy of Flags for mutation.\nfunc (f *Flags) Copy() Flags {\n\tprintFlags := *f\n\treturn printFlags\n}\n\n// EnsureWithGroup ensures that human-readable flags return a printer capable of\n// including resource group.\nfunc (f *Flags) EnsureWithGroup() {\n\tf.HumanReadableFlags.EnsureWithGroup()\n}\n\n// IsTableOutputFormat returns true if provided output format is a table format.\nfunc (f *Flags) IsTableOutputFormat(outputFormat string) bool {\n\treturn f.HumanReadableFlags.IsSupportedOutputFormat(outputFormat)\n}\n\n// SetShowNamespace configures whether human-readable flags return a printer\n// capable of printing with a \"namespace\" column.\nfunc (f *Flags) SetShowNamespace(b bool) {\n\tf.HumanReadableFlags.SetShowNamespace(b)\n}\n\n// ToPrinter returns a printer based on current flag values.\nfunc (f *Flags) ToPrinter(client client.Interface) (Interface, error) {\n\toutputFormat := \"\"\n\tif f.OutputFormat != nil {\n\t\toutputFormat = *f.OutputFormat\n\t}\n\n\tvar printer Interface\n\tswitch {\n\tcase f.IsTableOutputFormat(outputFormat), outputFormat == \"\":\n\t\tconfigFlags := f.Copy()\n\t\tprinter = &tablePrinter{\n\t\t\tconfigFlags:  configFlags.HumanReadableFlags,\n\t\t\toutputFormat: outputFormat,\n\t\t\tclient:       client,\n\t\t}\n\tdefault:\n\t\treturn nil, genericclioptions.NoCompatiblePrinterError{\n\t\t\tAllowedFormats: f.AllowedFormats(),\n\t\t\tOutputFormat:   &outputFormat,\n\t\t}\n\t}\n\n\treturn printer, nil\n}\n\n// NewFlags returns flags associated with human-readable printing, with default\n// values set.\nfunc NewFlags() *Flags {\n\toutputFormat := \"\"\n\n\treturn &Flags{\n\t\tOutputFormat:       &outputFormat,\n\t\tHumanReadableFlags: NewHumanPrintFlags(),\n\t}\n}\n"
  },
  {
    "path": "internal/printers/flags_humanreadable.go",
    "content": "package printers\n\nimport (\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\t\"k8s.io/cli-runtime/pkg/printers\"\n)\n\nconst (\n\tflagColumnLabels          = \"label-columns\"\n\tflagColumnLabelsShorthand = \"L\"\n\tflagNoHeaders             = \"no-headers\"\n\tflagShowGroup             = \"show-group\"\n\tflagShowLabels            = \"show-labels\"\n\tflagShowNamespace         = \"show-namespace\"\n)\n\n// List of supported table output formats.\nconst (\n\toutputFormatWide      = \"wide\"\n\toutputFormatSplit     = \"split\"\n\toutputFormatSplitWide = \"split-wide\"\n)\n\n// HumanPrintFlags provides default flags necessary for printing. Given the\n// following flag values, a printer can be requested that knows how to handle\n// printing based on these values.\ntype HumanPrintFlags struct {\n\tColumnLabels  *[]string\n\tNoHeaders     *bool\n\tShowGroup     *bool\n\tShowLabels    *bool\n\tShowNamespace *bool\n}\n\n// EnsureWithGroup sets the \"ShowGroup\" human-readable option to true.\nfunc (f *HumanPrintFlags) EnsureWithGroup() {\n\tshowGroup := true\n\tf.ShowGroup = &showGroup\n}\n\n// SetShowNamespace sets the \"ShowNamespace\" human-readable option.\nfunc (f *HumanPrintFlags) SetShowNamespace(b bool) {\n\tf.ShowNamespace = &b\n}\n\n// AllowedFormats returns more customized formating options.\nfunc (f *HumanPrintFlags) AllowedFormats() []string {\n\treturn []string{\n\t\toutputFormatWide,\n\t\toutputFormatSplit,\n\t\toutputFormatSplitWide,\n\t}\n}\n\n// IsSupportedOutputFormat returns true if provided output format is supported.\nfunc (f *HumanPrintFlags) IsSupportedOutputFormat(outputFormat string) bool {\n\treturn sets.NewString(f.AllowedFormats()...).Has(outputFormat)\n}\n\n// IsSplitOutputFormat returns true if provided output format is a split table\n// format.\nfunc (f *HumanPrintFlags) IsSplitOutputFormat(outputFormat string) bool {\n\treturn outputFormat == outputFormatSplit || outputFormat == outputFormatSplitWide\n}\n\n// IsWideOutputFormat returns true if provided output format is a wide table\n// format.\nfunc (f *HumanPrintFlags) IsWideOutputFormat(outputFormat string) bool {\n\treturn outputFormat == outputFormatWide || outputFormat == outputFormatSplitWide\n}\n\n// ToPrinter receives an outputFormat and returns a printer capable of handling\n// human-readable output.\nfunc (f *HumanPrintFlags) ToPrinterWithGK(outputFormat string, gk schema.GroupKind) (printers.ResourcePrinter, error) {\n\tif len(outputFormat) > 0 && !f.IsSupportedOutputFormat(outputFormat) {\n\t\treturn nil, genericclioptions.NoCompatiblePrinterError{\n\t\t\tOptions:        f,\n\t\t\tAllowedFormats: f.AllowedFormats(),\n\t\t}\n\t}\n\tcolumnLabels := []string{}\n\tif f.ColumnLabels != nil {\n\t\tcolumnLabels = *f.ColumnLabels\n\t}\n\tnoHeaders := false\n\tif f.NoHeaders != nil {\n\t\tnoHeaders = *f.NoHeaders\n\t}\n\tshowLabels := false\n\tif f.ShowLabels != nil {\n\t\tshowLabels = *f.ShowLabels\n\t}\n\tshowNamespace := false\n\tif f.ShowLabels != nil {\n\t\tshowNamespace = *f.ShowNamespace\n\t}\n\tp := printers.NewTablePrinter(printers.PrintOptions{\n\t\tColumnLabels:  columnLabels,\n\t\tNoHeaders:     noHeaders,\n\t\tShowLabels:    showLabels,\n\t\tKind:          gk,\n\t\tWithKind:      !gk.Empty(),\n\t\tWide:          f.IsWideOutputFormat(outputFormat),\n\t\tWithNamespace: showNamespace,\n\t})\n\treturn p, nil\n}\n\n// ToPrinter receives an outputFormat and returns a printer capable of handling\n// human-readable output.\nfunc (f *HumanPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrinter, error) {\n\treturn f.ToPrinterWithGK(outputFormat, schema.GroupKind{})\n}\n\n// AddFlags receives a *pflag.FlagSet reference and binds flags related to\n// human-readable printing to it.\nfunc (f *HumanPrintFlags) AddFlags(flags *pflag.FlagSet) {\n\tif f.ColumnLabels != nil {\n\t\tflags.StringSliceVarP(f.ColumnLabels, flagColumnLabels, flagColumnLabelsShorthand, *f.ColumnLabels, \"Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag options like -L label1 -L label2...\")\n\t}\n\tif f.NoHeaders != nil {\n\t\tflags.BoolVar(f.NoHeaders, flagNoHeaders, *f.NoHeaders, \"When using the default output format, don't print headers (default print headers)\")\n\t}\n\tif f.ShowGroup != nil {\n\t\tflags.BoolVar(f.ShowGroup, flagShowGroup, *f.ShowGroup, \"If present, include the resource group for the requested object(s)\")\n\t}\n\tif f.ShowLabels != nil {\n\t\tflags.BoolVar(f.ShowLabels, flagShowLabels, *f.ShowLabels, \"When printing, show all labels as the last column (default hide labels column)\")\n\t}\n\tif f.ShowNamespace != nil {\n\t\tflags.BoolVar(f.ShowNamespace, flagShowNamespace, *f.ShowNamespace, \"When printing, show namespace as the first column (default hide namespace column if all objects are in the same namespace)\")\n\t}\n}\n\n// NewHumanPrintFlags returns flags associated with human-readable printing,\n// with default values set.\nfunc NewHumanPrintFlags() *HumanPrintFlags {\n\tcolumnLabels := []string{}\n\tnoHeaders := false\n\tshowGroup := false\n\tshowLabels := false\n\tshowNamespace := false\n\n\treturn &HumanPrintFlags{\n\t\tColumnLabels:  &columnLabels,\n\t\tNoHeaders:     &noHeaders,\n\t\tShowGroup:     &showGroup,\n\t\tShowLabels:    &showLabels,\n\t\tShowNamespace: &showNamespace,\n\t}\n}\n"
  },
  {
    "path": "internal/printers/printers.go",
    "content": "package printers\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\n\t\"golang.org/x/sync/errgroup\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/client\"\n\t\"github.com/tohjustin/kube-lineage/internal/graph\"\n)\n\ntype sortableGroupKind []schema.GroupKind\n\nfunc (s sortableGroupKind) Len() int           { return len(s) }\nfunc (s sortableGroupKind) Less(i, j int) bool { return lessGroupKind(s[i], s[j]) }\nfunc (s sortableGroupKind) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\n\nfunc lessGroupKind(lhs, rhs schema.GroupKind) bool {\n\treturn lhs.String() < rhs.String()\n}\n\ntype Interface interface {\n\tPrint(w io.Writer, nodeMap graph.NodeMap, rootUID types.UID, maxDepth uint, depsIsDependencies bool) error\n}\n\ntype tablePrinter struct {\n\tconfigFlags  *HumanPrintFlags\n\toutputFormat string\n\n\t// client for fetching server-printed tables when printing in split output\n\t// format\n\tclient client.Interface\n}\n\nfunc (p *tablePrinter) Print(w io.Writer, nodeMap graph.NodeMap, rootUID types.UID, maxDepth uint, depsIsDependencies bool) error {\n\troot, ok := nodeMap[rootUID]\n\tif !ok {\n\t\treturn fmt.Errorf(\"requested object (uid: %s) not found in list of fetched objects\", rootUID)\n\t}\n\n\tif p.configFlags.IsSplitOutputFormat(p.outputFormat) {\n\t\tif p.client == nil {\n\t\t\treturn fmt.Errorf(\"client must be provided to get server-printed tables\")\n\t\t}\n\t\treturn p.printTablesByGK(w, nodeMap, maxDepth)\n\t}\n\n\treturn p.printTable(w, nodeMap, root, maxDepth, depsIsDependencies)\n}\n\nfunc (p *tablePrinter) printTable(w io.Writer, nodeMap graph.NodeMap, root *graph.Node, maxDepth uint, depsIsDependencies bool) error {\n\t// Generate Table to print\n\tshowGroup := false\n\tif sg := p.configFlags.ShowGroup; sg != nil {\n\t\tshowGroup = *sg\n\t}\n\tshowGroupFn := createShowGroupFn(nodeMap, showGroup, maxDepth)\n\tt, err := nodeMapToTable(nodeMap, root, maxDepth, depsIsDependencies, showGroupFn)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Setup Table printer\n\tp.configFlags.SetShowNamespace(shouldShowNamespace(nodeMap, maxDepth))\n\ttableprinter, err := p.configFlags.ToPrinter(p.outputFormat)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn tableprinter.PrintObj(t, w)\n}\n\nfunc (p *tablePrinter) printTablesByGK(w io.Writer, nodeMap graph.NodeMap, maxDepth uint) error {\n\t// Generate Tables to print\n\tshowGroup, showNamespace := false, false\n\tif sg := p.configFlags.ShowGroup; sg != nil {\n\t\tshowGroup = *sg\n\t}\n\tif sg := p.configFlags.ShowNamespace; sg != nil {\n\t\tshowNamespace = *sg\n\t}\n\tshowGroupFn := createShowGroupFn(nodeMap, showGroup, maxDepth)\n\tshowNamespaceFn := createShowNamespaceFn(nodeMap, showNamespace, maxDepth)\n\n\ttListByGK, err := p.nodeMapToTableByGK(nodeMap, maxDepth)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Sort Tables by GroupKind\n\tvar gkList sortableGroupKind\n\tfor gk := range tListByGK {\n\t\tgkList = append(gkList, gk)\n\t}\n\tsort.Sort(gkList)\n\tfor ix, gk := range gkList {\n\t\tif t, ok := tListByGK[gk]; ok {\n\t\t\t// Setup Table printer\n\t\t\ttgk := gk\n\t\t\tif !showGroupFn(gk.Kind) {\n\t\t\t\ttgk = schema.GroupKind{Kind: gk.Kind}\n\t\t\t}\n\t\t\tp.configFlags.SetShowNamespace(showNamespaceFn(gk))\n\t\t\ttableprinter, err := p.configFlags.ToPrinterWithGK(p.outputFormat, tgk)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Setup Table printer\n\t\t\terr = tableprinter.PrintObj(t, w)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif ix != len(gkList)-1 {\n\t\t\t\tfmt.Fprintf(w, \"\\n\")\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n//nolint:funlen,gocognit\nfunc (p *tablePrinter) nodeMapToTableByGK(nodeMap graph.NodeMap, maxDepth uint) (map[schema.GroupKind](*metav1.Table), error) {\n\t// Filter objects to print based on depth\n\tobjUIDs := []types.UID{}\n\tfor uid, node := range nodeMap {\n\t\tif maxDepth == 0 || node.Depth <= maxDepth {\n\t\t\tobjUIDs = append(objUIDs, uid)\n\t\t}\n\t}\n\n\t// Group objects by GroupKind & Namespace\n\tnodesByGKAndNS := map[schema.GroupKind](map[string]graph.NodeList){}\n\tfor _, uid := range objUIDs {\n\t\tif node, ok := nodeMap[uid]; ok {\n\t\t\tgk := schema.GroupKind{Group: node.Group, Kind: node.Kind}\n\t\t\tns := node.Namespace\n\t\t\tif _, ok := nodesByGKAndNS[gk]; !ok {\n\t\t\t\tnodesByGKAndNS[gk] = map[string]graph.NodeList{}\n\t\t\t}\n\t\t\tnodesByGKAndNS[gk][ns] = append(nodesByGKAndNS[gk][ns], node)\n\t\t}\n\t}\n\n\t// Fan-out to get server-print tables for all objects\n\teg, ctx := errgroup.WithContext(context.Background())\n\ttableByGKAndNS := map[schema.GroupKind](map[string]*metav1.Table){}\n\tfor gk, nodesByNS := range nodesByGKAndNS {\n\t\tif len(gk.Kind) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tfor ns, nodes := range nodesByNS {\n\t\t\tif len(nodes) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tgk, api, ns, names := gk, client.APIResource(nodes[0].GetAPIResource()), ns, []string{}\n\t\t\tfor _, n := range nodes {\n\t\t\t\tnames = append(names, n.Name)\n\t\t\t}\n\t\t\t// Sort TableRows by name\n\t\t\tsortedNames := sets.NewString(names...).List()\n\t\t\teg.Go(func() error {\n\t\t\t\ttable, err := p.client.GetTable(ctx, client.GetTableOptions{\n\t\t\t\t\tAPIResource: api,\n\t\t\t\t\tNamespace:   ns,\n\t\t\t\t\tNames:       sortedNames,\n\t\t\t\t})\n\t\t\t\tif err != nil || table == nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif _, ok := tableByGKAndNS[gk]; !ok {\n\t\t\t\t\ttableByGKAndNS[gk] = map[string]*metav1.Table{}\n\t\t\t\t}\n\t\t\t\tif t, ok := tableByGKAndNS[gk][ns]; !ok {\n\t\t\t\t\ttableByGKAndNS[gk][ns] = table\n\t\t\t\t} else {\n\t\t\t\t\tt.Rows = append(t.Rows, table.Rows...)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t}\n\t}\n\tif err := eg.Wait(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Sort TableRows by namespace\n\ttableByGK := map[schema.GroupKind]*metav1.Table{}\n\tfor gk, tableByNS := range tableByGKAndNS {\n\t\tvar nsList []string\n\t\tfor ns := range tableByNS {\n\t\t\tnsList = append(nsList, ns)\n\t\t}\n\t\tsortedNSList := sets.NewString(nsList...).List()\n\t\tvar table *metav1.Table\n\t\tfor _, ns := range sortedNSList {\n\t\t\tif t, ok := tableByNS[ns]; ok {\n\t\t\t\tif table == nil {\n\t\t\t\t\ttable = t\n\t\t\t\t} else {\n\t\t\t\t\ttable.Rows = append(table.Rows, t.Rows...)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttableByGK[gk] = table\n\t}\n\n\treturn tableByGK, nil\n}\n"
  },
  {
    "path": "internal/printers/printers_humanreadable.go",
    "content": "package printers\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\teventsv1 \"k8s.io/api/events/v1\"\n\tpolicyv1 \"k8s.io/api/policy/v1\"\n\tstoragev1 \"k8s.io/api/storage/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tunstructuredv1 \"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/duration\"\n\t\"k8s.io/client-go/util/jsonpath\"\n\tapiregistrationv1 \"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/graph\"\n)\n\nconst (\n\tcellUnknown       = \"<unknown>\"\n\tcellNotApplicable = \"-\"\n)\n\nvar (\n\t// objectColumnDefinitions holds table column definition for Kubernetes objects.\n\tobjectColumnDefinitions = []metav1.TableColumnDefinition{\n\t\t{Name: \"Name\", Type: \"string\", Format: \"name\", Description: metav1.ObjectMeta{}.SwaggerDoc()[\"name\"]},\n\t\t{Name: \"Ready\", Type: \"string\", Description: \"The readiness state of this object.\"},\n\t\t{Name: \"Status\", Type: \"string\", Description: \"The status of this object.\"},\n\t\t{Name: \"Age\", Type: \"string\", Description: metav1.ObjectMeta{}.SwaggerDoc()[\"creationTimestamp\"]},\n\t\t{Name: \"Relationships\", Type: \"array\", Description: \"The relationships this object has with its parent.\", Priority: -1},\n\t}\n\t// objectReadyReasonJSONPath is the JSON path to get a Kubernetes object's\n\t// \"Ready\" condition reason.\n\tobjectReadyReasonJSONPath = newJSONPath(\"reason\", \"{.status.conditions[?(@.type==\\\"Ready\\\")].reason}\")\n\t// objectReadyStatusJSONPath is the JSON path to get a Kubernetes object's\n\t// \"Ready\" condition status.\n\tobjectReadyStatusJSONPath = newJSONPath(\"status\", \"{.status.conditions[?(@.type==\\\"Ready\\\")].status}\")\n)\n\n// createShowGroupFn creates a function that takes in a resource's kind &\n// determines whether the resource's group should be included in its name.\nfunc createShowGroupFn(nodeMap graph.NodeMap, showGroup bool, maxDepth uint) func(string) bool {\n\t// Create function that returns true, if showGroup is true\n\tif showGroup {\n\t\treturn func(_ string) bool {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Track every object kind in the node map & the groups that they belong to.\n\tkindToGroupSetMap := map[string](map[string]struct{}){}\n\tfor _, node := range nodeMap {\n\t\tif maxDepth != 0 && node.Depth > maxDepth {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := kindToGroupSetMap[node.Kind]; !ok {\n\t\t\tkindToGroupSetMap[node.Kind] = map[string]struct{}{}\n\t\t}\n\t\tkindToGroupSetMap[node.Kind][node.Group] = struct{}{}\n\t}\n\t// When printing an object & if there exists another object in the node map\n\t// that has the same kind but belongs to a different group (eg. \"services.v1\"\n\t// vs \"services.v1.serving.knative.dev\"), we prepend the object's name with\n\t// its GroupKind instead of its Kind to clearly indicate which resource type\n\t// it belongs to.\n\treturn func(kind string) bool {\n\t\treturn len(kindToGroupSetMap[kind]) > 1\n\t}\n}\n\n// createShowNamespaceFn creates a function that takes in a resource's GroupKind\n// & determines whether the resource's namespace should be shown.\nfunc createShowNamespaceFn(nodeMap graph.NodeMap, showNamespace bool, maxDepth uint) func(schema.GroupKind) bool {\n\tshowNS := showNamespace || shouldShowNamespace(nodeMap, maxDepth)\n\tif !showNS {\n\t\treturn func(_ schema.GroupKind) bool {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tclusterScopeGKSet := map[schema.GroupKind]struct{}{}\n\tfor _, node := range nodeMap {\n\t\tif maxDepth != 0 && node.Depth > maxDepth {\n\t\t\tcontinue\n\t\t}\n\t\tgk := node.GroupVersionKind().GroupKind()\n\t\tif !node.Namespaced {\n\t\t\tclusterScopeGKSet[gk] = struct{}{}\n\t\t}\n\t}\n\treturn func(gk schema.GroupKind) bool {\n\t\t_, isClusterScopeGK := clusterScopeGKSet[gk]\n\t\treturn !isClusterScopeGK\n\t}\n}\n\n// shouldShowNamespace determines whether namespace column should be shown.\n// Returns true if objects in the provided node map are in different namespaces.\nfunc shouldShowNamespace(nodeMap graph.NodeMap, maxDepth uint) bool {\n\tnsSet := map[string]struct{}{}\n\tfor _, node := range nodeMap {\n\t\tif maxDepth != 0 && node.Depth > maxDepth {\n\t\t\tcontinue\n\t\t}\n\t\tns := node.Namespace\n\t\tif _, ok := nsSet[ns]; !ok {\n\t\t\tnsSet[ns] = struct{}{}\n\t\t}\n\t}\n\treturn len(nsSet) > 1\n}\n\n// newJSONPath returns a JSONPath object created from parsing the provided JSON\n// path expression.\nfunc newJSONPath(name, jsonPath string) *jsonpath.JSONPath {\n\tjp := jsonpath.New(name).AllowMissingKeys(true)\n\tif err := jp.Parse(jsonPath); err != nil {\n\t\tpanic(err)\n\t}\n\treturn jp\n}\n\n// getNestedString returns the field value of a Kubernetes object at the\n// provided JSON path.\nfunc getNestedString(data map[string]interface{}, jp *jsonpath.JSONPath) (string, error) {\n\tvalues, err := jp.FindResults(data)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tstrValues := []string{}\n\tfor arrIx := range values {\n\t\tfor valIx := range values[arrIx] {\n\t\t\tstrValues = append(strValues, fmt.Sprintf(\"%v\", values[arrIx][valIx].Interface()))\n\t\t}\n\t}\n\tstr := strings.Join(strValues, \",\")\n\n\treturn str, nil\n}\n\n// getObjectReadyStatus returns the ready & status value of a Kubernetes object.\nfunc getObjectReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tdata := u.UnstructuredContent()\n\tready, err := getNestedString(data, objectReadyStatusJSONPath)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tstatus, err := getNestedString(data, objectReadyReasonJSONPath)\n\tif err != nil {\n\t\treturn ready, \"\", err\n\t}\n\n\treturn ready, status, nil\n}\n\n// getAPIServiceReadyStatus returns the ready & status value of a APIService\n// which is based off the table cell values computed by printAPIService from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\nfunc getAPIServiceReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar apisvc apiregistrationv1.APIService\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &apisvc)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tvar ready, status string\n\tfor _, condition := range apisvc.Status.Conditions {\n\t\tif condition.Type == apiregistrationv1.Available {\n\t\t\tready = string(condition.Status)\n\t\t\tif condition.Status != apiregistrationv1.ConditionTrue {\n\t\t\t\tstatus = condition.Reason\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ready, status, nil\n}\n\n// getDaemonSetReadyStatus returns the ready & status value of a DaemonSet\n// which is based off the table cell values computed by printDaemonSet from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:unparam\nfunc getDaemonSetReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar ds appsv1.DaemonSet\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &ds)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tdesiredReplicas := ds.Status.DesiredNumberScheduled\n\treadyReplicas := ds.Status.NumberReady\n\tready := fmt.Sprintf(\"%d/%d\", readyReplicas, desiredReplicas)\n\n\treturn ready, \"\", nil\n}\n\n// getDeploymentReadyStatus returns the ready & status value of a Deployment\n// which is based off the table cell values computed by printDeployment from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:unparam\nfunc getDeploymentReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar deploy appsv1.Deployment\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &deploy)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tdesiredReplicas := deploy.Status.Replicas\n\treadyReplicas := deploy.Status.ReadyReplicas\n\tready := fmt.Sprintf(\"%d/%d\", readyReplicas, desiredReplicas)\n\n\treturn ready, \"\", nil\n}\n\n// getEventCoreReadyStatus returns the ready & status value of a Event.\n//nolint:unparam\nfunc getEventCoreReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar status string\n\tvar ev corev1.Event\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &ev)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tif ev.Count > 1 {\n\t\tstatus = fmt.Sprintf(\"%s: %s (x%d)\", ev.Reason, ev.Message, ev.Count)\n\t} else {\n\t\tstatus = fmt.Sprintf(\"%s: %s\", ev.Reason, ev.Message)\n\t}\n\n\treturn \"\", status, nil\n}\n\n// getEventReadyStatus returns the ready & status value of a Event.events.k8s.io.\n//nolint:unparam\nfunc getEventReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar status string\n\tvar ev eventsv1.Event\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &ev)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tif ev.DeprecatedCount > 1 {\n\t\tstatus = fmt.Sprintf(\"%s: %s (x%d)\", ev.Reason, ev.Note, ev.DeprecatedCount)\n\t} else {\n\t\tstatus = fmt.Sprintf(\"%s: %s\", ev.Reason, ev.Note)\n\t}\n\n\treturn \"\", status, nil\n}\n\n// getPodReadyStatus returns the ready & status value of a Pod which is based\n// off the table cell values computed by printPod from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:funlen,gocognit,gocyclo\nfunc getPodReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar pod corev1.Pod\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &pod)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\ttotalContainers := len(pod.Spec.Containers)\n\treadyContainers := 0\n\treason := string(pod.Status.Phase)\n\tif len(pod.Status.Reason) > 0 {\n\t\treason = pod.Status.Reason\n\t}\n\tinitializing := false\n\tfor i := range pod.Status.InitContainerStatuses {\n\t\tcontainer := pod.Status.InitContainerStatuses[i]\n\t\tstate := container.State\n\t\tswitch {\n\t\tcase state.Terminated != nil && state.Terminated.ExitCode == 0:\n\t\t\tcontinue\n\t\tcase state.Terminated != nil && len(state.Terminated.Reason) > 0:\n\t\t\treason = state.Terminated.Reason\n\t\tcase state.Terminated != nil && len(state.Terminated.Reason) == 0 && state.Terminated.Signal != 0:\n\t\t\treason = fmt.Sprintf(\"Signal:%d\", state.Terminated.Signal)\n\t\tcase state.Terminated != nil && len(state.Terminated.Reason) == 0 && state.Terminated.Signal == 0:\n\t\t\treason = fmt.Sprintf(\"ExitCode:%d\", state.Terminated.ExitCode)\n\t\tcase state.Waiting != nil && len(state.Waiting.Reason) > 0 && state.Waiting.Reason != \"PodInitializing\":\n\t\t\treason = state.Waiting.Reason\n\t\tdefault:\n\t\t\treason = fmt.Sprintf(\"%d/%d\", i, len(pod.Spec.InitContainers))\n\t\t}\n\t\treason = fmt.Sprintf(\"Init:%s\", reason)\n\t\tinitializing = true\n\t\tbreak\n\t}\n\tif !initializing {\n\t\thasRunning := false\n\t\tfor i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- {\n\t\t\tcontainer := pod.Status.ContainerStatuses[i]\n\t\t\tstate := container.State\n\t\t\tswitch {\n\t\t\tcase state.Terminated != nil && len(state.Terminated.Reason) > 0:\n\t\t\t\treason = state.Terminated.Reason\n\t\t\tcase state.Terminated != nil && len(state.Terminated.Reason) == 0 && state.Terminated.Signal != 0:\n\t\t\t\treason = fmt.Sprintf(\"Signal:%d\", state.Terminated.Signal)\n\t\t\tcase state.Terminated != nil && len(state.Terminated.Reason) == 0 && state.Terminated.Signal == 0:\n\t\t\t\treason = fmt.Sprintf(\"ExitCode:%d\", state.Terminated.ExitCode)\n\t\t\tcase state.Waiting != nil && len(state.Waiting.Reason) > 0:\n\t\t\t\treason = state.Waiting.Reason\n\t\t\tcase state.Running != nil && container.Ready:\n\t\t\t\thasRunning = true\n\t\t\t\treadyContainers++\n\t\t\t}\n\t\t}\n\t\t// change pod status back to \"Running\" if there is at least one container still reporting as \"Running\" status\n\t\tif reason == \"Completed\" && hasRunning {\n\t\t\treason = \"NotReady\"\n\t\t\tfor _, condition := range pod.Status.Conditions {\n\t\t\t\tif condition.Type == corev1.PodReady && condition.Status == corev1.ConditionTrue {\n\t\t\t\t\treason = \"Running\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif pod.DeletionTimestamp != nil {\n\t\t// Hardcode \"k8s.io/kubernetes/pkg/util/node.NodeUnreachablePodReason\" as\n\t\t// \"NodeLost\" so we don't need import the entire k8s.io/kubernetes package\n\t\tif pod.Status.Reason == \"NodeLost\" {\n\t\t\treason = \"Unknown\"\n\t\t} else {\n\t\t\treason = \"Terminating\"\n\t\t}\n\t}\n\tready := fmt.Sprintf(\"%d/%d\", readyContainers, totalContainers)\n\n\treturn ready, reason, nil\n}\n\n// getPodDisruptionBudgetReadyStatus returns the ready & status value of a\n// PodDisruptionBudget.\n//nolint:unparam\nfunc getPodDisruptionBudgetReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar pdb policyv1.PodDisruptionBudget\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &pdb)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tvar status string\n\tfor _, condition := range pdb.Status.Conditions {\n\t\tif condition.ObservedGeneration == pdb.Generation {\n\t\t\tif condition.Type == policyv1.DisruptionAllowedCondition {\n\t\t\t\tstatus = condition.Reason\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", status, nil\n}\n\n// getReplicaSetReadyStatus returns the ready & status value of a ReplicaSet\n// which is based off the table cell values computed by printReplicaSet from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:unparam\nfunc getReplicaSetReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar rs appsv1.ReplicaSet\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &rs)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tdesiredReplicas := rs.Status.Replicas\n\treadyReplicas := rs.Status.ReadyReplicas\n\tready := fmt.Sprintf(\"%d/%d\", readyReplicas, desiredReplicas)\n\n\treturn ready, \"\", nil\n}\n\n// getReplicationControllerReadyStatus returns the ready & status value of a\n// ReplicationController which is based off the table cell values computed by\n// printReplicationController from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:unparam\nfunc getReplicationControllerReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar rc corev1.ReplicationController\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &rc)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tdesiredReplicas := rc.Status.Replicas\n\treadyReplicas := rc.Status.ReadyReplicas\n\tready := fmt.Sprintf(\"%d/%d\", readyReplicas, desiredReplicas)\n\n\treturn ready, \"\", nil\n}\n\n// getStatefulSetReadyStatus returns the ready & status value of a StatefulSet\n// which is based off the table cell values computed by printStatefulSet from\n// https://github.com/kubernetes/kubernetes/blob/v1.22.1/pkg/printers/internalversion/printers.go.\n//nolint:unparam\nfunc getStatefulSetReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar sts appsv1.StatefulSet\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &sts)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tdesiredReplicas := sts.Status.Replicas\n\treadyReplicas := sts.Status.ReadyReplicas\n\tready := fmt.Sprintf(\"%d/%d\", readyReplicas, desiredReplicas)\n\n\treturn ready, \"\", nil\n}\n\n// getVolumeAttachmentReadyStatus returns the ready & status value of a\n// VolumeAttachment.\nfunc getVolumeAttachmentReadyStatus(u *unstructuredv1.Unstructured) (string, string, error) {\n\tvar va storagev1.VolumeAttachment\n\terr := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &va)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tvar ready, status string\n\tif va.Status.Attached {\n\t\tready = \"True\"\n\t} else {\n\t\tready = \"False\"\n\t}\n\tvar errTime time.Time\n\tif err := va.Status.AttachError; err != nil {\n\t\tstatus = err.Message\n\t\terrTime = err.Time.Time\n\t}\n\tif err := va.Status.DetachError; err != nil {\n\t\tif err.Time.After(errTime) {\n\t\t\tstatus = err.Message\n\t\t}\n\t}\n\n\treturn ready, status, nil\n}\n\n// nodeToTableRow converts the provided node into a table row.\n//nolint:funlen,gocognit,goconst\nfunc nodeToTableRow(node *graph.Node, rset graph.RelationshipSet, namePrefix string, showGroupFn func(kind string) bool) metav1.TableRow {\n\tvar name, ready, status, age string\n\tvar relationships interface{}\n\n\tswitch {\n\tcase len(node.Kind) == 0:\n\t\tname = node.Name\n\tcase len(node.Group) > 0 && showGroupFn(node.Kind):\n\t\tname = fmt.Sprintf(\"%s%s.%s/%s\", namePrefix, node.Kind, node.Group, node.Name)\n\tdefault:\n\t\tname = fmt.Sprintf(\"%s%s/%s\", namePrefix, node.Kind, node.Name)\n\t}\n\tswitch {\n\tcase node.Group == corev1.GroupName && node.Kind == \"Event\":\n\t\tready, status, _ = getEventCoreReadyStatus(node.Unstructured)\n\tcase node.Group == corev1.GroupName && node.Kind == \"Pod\":\n\t\tready, status, _ = getPodReadyStatus(node.Unstructured)\n\tcase node.Group == corev1.GroupName && node.Kind == \"ReplicationController\":\n\t\tready, status, _ = getReplicationControllerReadyStatus(node.Unstructured)\n\tcase node.Group == appsv1.GroupName && node.Kind == \"DaemonSet\":\n\t\tready, status, _ = getDaemonSetReadyStatus(node.Unstructured)\n\tcase node.Group == appsv1.GroupName && node.Kind == \"Deployment\":\n\t\tready, status, _ = getDeploymentReadyStatus(node.Unstructured)\n\tcase node.Group == appsv1.GroupName && node.Kind == \"ReplicaSet\":\n\t\tready, status, _ = getReplicaSetReadyStatus(node.Unstructured)\n\tcase node.Group == appsv1.GroupName && node.Kind == \"StatefulSet\":\n\t\tready, status, _ = getStatefulSetReadyStatus(node.Unstructured)\n\tcase node.Group == policyv1.GroupName && node.Kind == \"PodDisruptionBudget\":\n\t\tready, status, _ = getPodDisruptionBudgetReadyStatus(node.Unstructured)\n\tcase node.Group == apiregistrationv1.GroupName && node.Kind == \"APIService\":\n\t\tready, status, _ = getAPIServiceReadyStatus(node.Unstructured)\n\tcase node.Group == eventsv1.GroupName && node.Kind == \"Event\":\n\t\tready, status, _ = getEventReadyStatus(node.Unstructured)\n\tcase node.Group == storagev1.GroupName && node.Kind == \"VolumeAttachment\":\n\t\tready, status, _ = getVolumeAttachmentReadyStatus(node.Unstructured)\n\tcase node.Unstructured != nil:\n\t\tready, status, _ = getObjectReadyStatus(node.Unstructured)\n\t}\n\tif len(ready) == 0 {\n\t\tready = cellNotApplicable\n\t}\n\tif node.Unstructured != nil {\n\t\tage = translateTimestampSince(node.GetCreationTimestamp())\n\t}\n\trelationships = []string{}\n\tif rset != nil {\n\t\trelationships = rset.List()\n\t}\n\n\treturn metav1.TableRow{\n\t\tObject: runtime.RawExtension{Object: node.DeepCopyObject()},\n\t\tCells: []interface{}{\n\t\t\tname,\n\t\t\tready,\n\t\t\tstatus,\n\t\t\tage,\n\t\t\trelationships,\n\t\t},\n\t}\n}\n\n// nodeMapToTable converts the provided node & either its dependencies or\n// dependents into table rows.\nfunc nodeMapToTable(\n\tnodeMap graph.NodeMap,\n\troot *graph.Node,\n\tmaxDepth uint,\n\tdepsIsDependencies bool,\n\tshowGroupFn func(kind string) bool) (*metav1.Table, error) {\n\t// Sorts the list of UIDs based on the underlying object in following order:\n\t// Namespace, Kind, Group, Name\n\tsortDepsFn := func(d map[types.UID]graph.RelationshipSet) []types.UID {\n\t\tnodes, ix := make(graph.NodeList, len(d)), 0\n\t\tfor uid := range d {\n\t\t\tnodes[ix] = nodeMap[uid]\n\t\t\tix++\n\t\t}\n\t\tsort.Sort(nodes)\n\t\tsortedUIDs := make([]types.UID, len(d))\n\t\tfor ix, node := range nodes {\n\t\t\tsortedUIDs[ix] = node.UID\n\t\t}\n\t\treturn sortedUIDs\n\t}\n\n\tvar rows []metav1.TableRow\n\trow := nodeToTableRow(root, nil, \"\", showGroupFn)\n\tuidSet := map[types.UID]struct{}{}\n\tdepRows, err := nodeDepsToTableRows(nodeMap, uidSet, root, \"\", 1, maxDepth, depsIsDependencies, sortDepsFn, showGroupFn)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trows = append(rows, row)\n\trows = append(rows, depRows...)\n\ttable := metav1.Table{\n\t\tColumnDefinitions: objectColumnDefinitions,\n\t\tRows:              rows,\n\t}\n\n\treturn &table, nil\n}\n\n// nodeDepsToTableRows converts either the dependencies or dependents of the\n// provided node into table rows.\nfunc nodeDepsToTableRows(\n\tnodeMap graph.NodeMap,\n\tuidSet map[types.UID]struct{},\n\tnode *graph.Node,\n\tprefix string,\n\tdepth uint,\n\tmaxDepth uint,\n\tdepsIsDependencies bool,\n\tsortDepsFn func(d map[types.UID]graph.RelationshipSet) []types.UID,\n\tshowGroupFn func(kind string) bool) ([]metav1.TableRow, error) {\n\trows := make([]metav1.TableRow, 0, len(nodeMap))\n\n\t// Guard against possible cycles\n\tif _, ok := uidSet[node.UID]; ok {\n\t\treturn rows, nil\n\t}\n\tuidSet[node.UID] = struct{}{}\n\n\tdeps := node.GetDeps(depsIsDependencies)\n\tdepUIDs := sortDepsFn(deps)\n\tlastIx := len(depUIDs) - 1\n\tfor ix, childUID := range depUIDs {\n\t\tvar childPrefix, depPrefix string\n\t\tif ix != lastIx {\n\t\t\tchildPrefix, depPrefix = prefix+\"├── \", prefix+\"│   \"\n\t\t} else {\n\t\t\tchildPrefix, depPrefix = prefix+\"└── \", prefix+\"    \"\n\t\t}\n\n\t\tchild, ok := nodeMap[childUID]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"dependent object (uid: %s) not found in list of fetched objects\", childUID)\n\t\t}\n\t\trset, ok := deps[childUID]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"dependent object (uid: %s) not found\", childUID)\n\t\t}\n\t\trow := nodeToTableRow(child, rset, childPrefix, showGroupFn)\n\t\trows = append(rows, row)\n\t\tif maxDepth == 0 || depth < maxDepth {\n\t\t\tdepRows, err := nodeDepsToTableRows(nodeMap, uidSet, child, depPrefix, depth+1, maxDepth, depsIsDependencies, sortDepsFn, showGroupFn)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\trows = append(rows, depRows...)\n\t\t}\n\t}\n\n\treturn rows, nil\n}\n\n// translateTimestampSince returns the elapsed time since timestamp in\n// human-readable approximation.\nfunc translateTimestampSince(timestamp metav1.Time) string {\n\tif timestamp.IsZero() {\n\t\treturn cellUnknown\n\t}\n\n\treturn duration.HumanDuration(time.Since(timestamp.Time))\n}\n"
  },
  {
    "path": "internal/version/version.go",
    "content": "package version\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\nvar (\n\tgitVersion      string // semantic version, derived by build scripts\n\tgitVersionMajor string // major version, always numeric\n\tgitVersionMinor string // minor version, always numeric\n\tgitCommit       string // sha1 from git, output of $(git rev-parse HEAD)\n\tgitTreeState    string // state of git tree, either \"clean\" or \"dirty\"\n\tbuildDate       string // build date in rfc3339 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')\n)\n\n// Info defines the version.\ntype Info struct {\n\tMajor        string `json:\"major,omitempty\"`\n\tMinor        string `json:\"minor,omitempty\"`\n\tGitVersion   string `json:\"gitVersion,omitempty\"`\n\tGitCommit    string `json:\"gitCommit,omitempty\"`\n\tGitTreeState string `json:\"gitTreeState,omitempty\"`\n\tBuildDate    string `json:\"buildDate,omitempty\"`\n\tGoVersion    string `json:\"goVersion,omitempty\"`\n\tCompiler     string `json:\"compiler,omitempty\"`\n\tPlatform     string `json:\"platform,omitempty\"`\n}\n\n// Get returns metadata and information regarding the version.\nfunc Get() Info {\n\treturn Info{\n\t\tMajor:        gitVersionMajor,\n\t\tMinor:        gitVersionMinor,\n\t\tGitVersion:   gitVersion,\n\t\tGitCommit:    gitCommit,\n\t\tGitTreeState: gitTreeState,\n\t\tBuildDate:    buildDate,\n\t\tGoVersion:    runtime.Version(),\n\t\tCompiler:     runtime.Compiler,\n\t\tPlatform:     fmt.Sprintf(\"%s/%s\", runtime.GOOS, runtime.GOARCH),\n\t}\n}\n\n// String returns info as a human-friendly version string.\nfunc (info Info) String() string {\n\treturn info.GitVersion\n}\n"
  },
  {
    "path": "pkg/cmd/helm/completion.go",
    "content": "package helm\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\t\"helm.sh/helm/v3/pkg/action\"\n)\n\n// Provide dynamic auto-completion for release names.\n//\n// Based off `compListReleases` from https://github.com/helm/helm/blob/v3.7.0/cmd/helm/list.go#L221-L243\nfunc compGetHelmReleaseList(opts *CmdOptions, toComplete string) []string {\n\tcobra.CompDebugln(fmt.Sprintf(\"completeHelm with \\\"%s\\\"\", toComplete), false)\n\tif err := opts.Complete(nil, nil); err != nil {\n\t\treturn nil\n\t}\n\thelmClient := action.NewList(opts.ActionConfig)\n\thelmClient.All = true\n\thelmClient.Limit = 0\n\thelmClient.Filter = fmt.Sprintf(\"^%s\", toComplete)\n\thelmClient.SetStateMask()\n\n\tvar choices []string\n\treleases, err := helmClient.Run()\n\tif err != nil {\n\t\tcobra.CompErrorln(fmt.Sprintf(\"Failed to list releases: %s\", err))\n\t\treturn nil\n\t}\n\tfor _, rel := range releases {\n\t\tchoices = append(choices,\n\t\t\tfmt.Sprintf(\"%s\\t%s-%s -> %s\", rel.Name, rel.Chart.Metadata.Name, rel.Chart.Metadata.Version, rel.Info.Status.String()))\n\t}\n\tif len(choices) == 0 {\n\t\tcobra.CompDebugln(\"No releases found\", false)\n\t\treturn nil\n\t}\n\n\treturn choices\n}\n"
  },
  {
    "path": "pkg/cmd/helm/flags.go",
    "content": "package helm\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/completion\"\n)\n\nconst (\n\tflagAllNamespaces          = \"all-namespaces\"\n\tflagAllNamespacesShorthand = \"A\"\n\tflagDepth                  = \"depth\"\n\tflagDepthShorthand         = \"d\"\n\tflagExcludeTypes           = \"exclude-types\"\n\tflagIncludeTypes           = \"include-types\"\n\tflagScopes                 = \"scopes\"\n\tflagScopesShorthand        = \"S\"\n)\n\n// Flags composes common configuration flag structs used in the command.\ntype Flags struct {\n\tAllNamespaces *bool\n\tDepth         *uint\n\tExcludeTypes  *[]string\n\tIncludeTypes  *[]string\n\tScopes        *[]string\n}\n\n// Copy returns a copy of Flags for mutation.\nfunc (f *Flags) Copy() Flags {\n\tFlags := *f\n\treturn Flags\n}\n\n// AddFlags receives a *pflag.FlagSet reference and binds flags related to\n// configuration to it.\nfunc (f *Flags) AddFlags(flags *pflag.FlagSet) {\n\tif f.AllNamespaces != nil {\n\t\tflags.BoolVarP(f.AllNamespaces, flagAllNamespaces, flagAllNamespacesShorthand, *f.AllNamespaces, \"If present, list object relationships across all namespaces\")\n\t}\n\tif f.Depth != nil {\n\t\tflags.UintVarP(f.Depth, flagDepth, flagDepthShorthand, *f.Depth, \"Maximum depth to find relationships\")\n\t}\n\tif f.ExcludeTypes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of resource types to exclude from relationship discovery. You can also use multiple flag options like --%s kind1 --%s kind1...\", flagExcludeTypes, flagExcludeTypes)\n\t\tflags.StringSliceVar(f.ExcludeTypes, flagExcludeTypes, *f.ExcludeTypes, usage)\n\t}\n\tif f.IncludeTypes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of resource types to only include in relationship discovery. You can also use multiple flag options like --%s kind1 --%s kind1...\", flagIncludeTypes, flagIncludeTypes)\n\t\tflags.StringSliceVar(f.IncludeTypes, flagIncludeTypes, *f.IncludeTypes, usage)\n\t}\n\tif f.Scopes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of additional namespaces to find relationships. You can also use multiple flag options like -%s namespace1 -%s namespace2...\", flagScopesShorthand, flagScopesShorthand)\n\t\tflags.StringSliceVarP(f.Scopes, flagScopes, flagScopesShorthand, *f.Scopes, usage)\n\t}\n}\n\n// RegisterFlagCompletionFunc receives a *cobra.Command & register functions to\n// to provide completion for flags related to configuration.\nfunc (*Flags) RegisterFlagCompletionFunc(cmd *cobra.Command, f cmdutil.Factory) {\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\tflagScopes,\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn completion.GetScopeNamespaceList(f, cmd, toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n}\n\n// NewConfigFlags returns flags associated with command configuration,\n// with default values set.\nfunc NewFlags() *Flags {\n\tallNamespaces := false\n\tdepth := uint(0)\n\texcludeTypes := []string{}\n\tincludeTypes := []string{}\n\tscopes := []string{}\n\n\treturn &Flags{\n\t\tAllNamespaces: &allNamespaces,\n\t\tDepth:         &depth,\n\t\tExcludeTypes:  &excludeTypes,\n\t\tIncludeTypes:  &includeTypes,\n\t\tScopes:        &scopes,\n\t}\n}\n"
  },
  {
    "path": "pkg/cmd/helm/helm.go",
    "content": "package helm\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n\t\"helm.sh/helm/v3/pkg/action\"\n\t\"helm.sh/helm/v3/pkg/release\"\n\t\"helm.sh/helm/v3/pkg/storage\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tunstructuredv1 \"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n\t\"k8s.io/klog/v2\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n\t\"k8s.io/kubectl/pkg/util\"\n\t\"k8s.io/kubectl/pkg/util/templates\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/client\"\n\t\"github.com/tohjustin/kube-lineage/internal/graph\"\n\t\"github.com/tohjustin/kube-lineage/internal/log\"\n\tlineageprinters \"github.com/tohjustin/kube-lineage/internal/printers\"\n)\n\nvar (\n\tcmdPath    string\n\tcmdName    = \"helm\"\n\tcmdUse     = \"%CMD% [RELEASE_NAME] [flags]\"\n\tcmdExample = templates.Examples(`\n\t\t# List all resources associated with release named \"bar\" in the current namespace\n\t\t%CMD_PATH% bar\n\n\t\t# List all resources associated with release named \"bar\" in namespace \"foo\"\n\t\t%CMD_PATH% bar --namespace=foo\n\n\t\t# List all resources associated with release named \"bar\" & the corresponding relationship type(s)\n\t\t%CMD_PATH% bar --output=wide\n\n\t\t# List all resources associated with release named \"bar\", excluding event & secret resource types\n\t\t%CMD_PATH% pv/disk --dependencies --exclude-types=ev,secret\n\n\t\t# List only resources provisioned by the release named \"bar\"\n\t\t%CMD_PATH% bar --depth=1`)\n\tcmdShort = \"Display resources associated with a Helm release & their dependents\"\n\tcmdLong  = templates.LongDesc(`\n\t\tDisplay resources associated with a Helm release & their dependents.\n\n\t\tRELEASE_NAME is the name of a particular Helm release.`)\n)\n\n// CmdOptions contains all the options for running the helm command.\ntype CmdOptions struct {\n\t// RequestRelease represents the requested Helm release.\n\tRequestRelease string\n\tFlags          *Flags\n\n\tNamespace    string\n\tHelmDriver   string\n\tActionConfig *action.Configuration\n\tClient       client.Interface\n\tClientFlags  *client.Flags\n\n\tPrinter    lineageprinters.Interface\n\tPrintFlags *lineageprinters.Flags\n\n\tgenericclioptions.IOStreams\n}\n\n// NewCmd returns an initialized Command for the helm command.\nfunc NewCmd(streams genericclioptions.IOStreams, name, parentCmdPath string) *cobra.Command {\n\to := &CmdOptions{\n\t\tFlags:       NewFlags(),\n\t\tClientFlags: client.NewFlags(),\n\t\tPrintFlags:  lineageprinters.NewFlags(),\n\t\tIOStreams:   streams,\n\t}\n\n\tf := cmdutil.NewFactory(o.ClientFlags)\n\tutil.SetFactoryForCompletion(f)\n\n\tif len(name) > 0 {\n\t\tcmdName = name\n\t}\n\tcmdPath = cmdName\n\tif len(parentCmdPath) > 0 {\n\t\tcmdPath = parentCmdPath + \" \" + cmdName\n\t}\n\tcmd := &cobra.Command{\n\t\tUse:                   strings.ReplaceAll(cmdUse, \"%CMD%\", cmdName),\n\t\tExample:               strings.ReplaceAll(cmdExample, \"%CMD_PATH%\", cmdPath),\n\t\tShort:                 cmdShort,\n\t\tLong:                  cmdLong,\n\t\tArgs:                  cobra.MaximumNArgs(1),\n\t\tDisableFlagsInUseLine: true,\n\t\tDisableSuggestions:    true,\n\t\tSilenceUsage:          true,\n\t\tRun: func(c *cobra.Command, args []string) {\n\t\t\tklog.V(4).Infof(\"Version: %s\", c.Root().Version)\n\t\t\tcmdutil.CheckErr(o.Complete(c, args))\n\t\t\tcmdutil.CheckErr(o.Validate())\n\t\t\tcmdutil.CheckErr(o.Run())\n\t\t},\n\t\tValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\tvar comp []string\n\t\t\tif len(args) == 0 {\n\t\t\t\tcomp = compGetHelmReleaseList(o, toComplete)\n\t\t\t}\n\t\t\treturn comp, cobra.ShellCompDirectiveNoFileComp\n\t\t},\n\t}\n\n\t// Setup flags\n\to.Flags.AddFlags(cmd.Flags())\n\to.ClientFlags.AddFlags(cmd.Flags())\n\to.PrintFlags.AddFlags(cmd.Flags())\n\tlog.AddFlags(cmd.Flags())\n\n\t// Setup flag completion function\n\to.Flags.RegisterFlagCompletionFunc(cmd, f)\n\to.ClientFlags.RegisterFlagCompletionFunc(cmd, f)\n\n\treturn cmd\n}\n\n// Complete completes all the required options for the helm command.\nfunc (o *CmdOptions) Complete(cmd *cobra.Command, args []string) error {\n\tvar err error\n\n\t//nolint:gocritic\n\tswitch len(args) {\n\tcase 1:\n\t\to.RequestRelease = args[0]\n\t}\n\n\t// Setup client\n\to.Namespace, _, err = o.ClientFlags.ToRawKubeConfigLoader().Namespace()\n\tif err != nil {\n\t\treturn err\n\t}\n\to.Client, err = o.ClientFlags.ToClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\to.HelmDriver = os.Getenv(\"HELM_DRIVER\")\n\to.ActionConfig = new(action.Configuration)\n\terr = o.ActionConfig.Init(o.ClientFlags, o.Namespace, o.HelmDriver, klog.V(4).Infof)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Setup printer\n\to.Printer, err = o.PrintFlags.ToPrinter(o.Client)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// Validate validates all the required options for the helm command.\nfunc (o *CmdOptions) Validate() error {\n\tif len(o.RequestRelease) == 0 {\n\t\treturn fmt.Errorf(\"release name must be specified\\nSee '%s -h' for help and examples\", cmdPath)\n\t}\n\n\tklog.V(4).Infof(\"Namespace: %s\", o.Namespace)\n\tklog.V(4).Infof(\"RequestRelease: %v\", o.RequestRelease)\n\tklog.V(4).Infof(\"Flags.AllNamespaces: %t\", *o.Flags.AllNamespaces)\n\tklog.V(4).Infof(\"Flags.Depth: %v\", *o.Flags.Depth)\n\tklog.V(4).Infof(\"Flags.ExcludeTypes: %v\", *o.Flags.ExcludeTypes)\n\tklog.V(4).Infof(\"Flags.IncludeTypes: %v\", *o.Flags.IncludeTypes)\n\tklog.V(4).Infof(\"Flags.Scopes: %v\", *o.Flags.Scopes)\n\tklog.V(4).Infof(\"ClientFlags.Context: %s\", *o.ClientFlags.Context)\n\tklog.V(4).Infof(\"ClientFlags.Namespace: %s\", *o.ClientFlags.Namespace)\n\tklog.V(4).Infof(\"PrintFlags.OutputFormat: %s\", *o.PrintFlags.OutputFormat)\n\tklog.V(4).Infof(\"PrintFlags.NoHeaders: %t\", *o.PrintFlags.HumanReadableFlags.NoHeaders)\n\tklog.V(4).Infof(\"PrintFlags.ShowGroup: %t\", *o.PrintFlags.HumanReadableFlags.ShowGroup)\n\tklog.V(4).Infof(\"PrintFlags.ShowLabels: %t\", *o.PrintFlags.HumanReadableFlags.ShowLabels)\n\tklog.V(4).Infof(\"PrintFlags.ShowNamespace: %t\", *o.PrintFlags.HumanReadableFlags.ShowNamespace)\n\n\treturn nil\n}\n\n// Run implements all the necessary functionality for the helm command.\n//nolint:funlen,gocognit,gocyclo\nfunc (o *CmdOptions) Run() error {\n\tctx := context.Background()\n\n\t// First check if Kubernetes cluster is reachable\n\tif err := o.Client.IsReachable(); err != nil {\n\t\treturn err\n\t}\n\n\t// Fetch the release to ensure it exists before proceeding\n\thelmClient := action.NewGet(o.ActionConfig)\n\trls, err := helmClient.Run(o.RequestRelease)\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(4).Infof(\"Release manifest:\\n%s\\n\", rls.Manifest)\n\n\t// Fetch all Helm release objects (i.e. resources found in the helm release\n\t// manifests) from the cluster\n\trlsObjs, err := o.getManifestObjects(ctx, rls)\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(4).Infof(\"Got %d objects from release manifest\", len(rlsObjs))\n\n\t// Fetch the Helm storage object\n\tstgObj, err := o.getStorageObject(ctx, rls)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Determine resources to list\n\texcludeAPIs := []client.APIResource{}\n\tif o.Flags.ExcludeTypes != nil {\n\t\tfor _, kind := range *o.Flags.ExcludeTypes {\n\t\t\tapi, err := o.Client.ResolveAPIResource(kind)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\texcludeAPIs = append(excludeAPIs, *api)\n\t\t}\n\t}\n\tincludeAPIs := []client.APIResource{}\n\tif o.Flags.IncludeTypes != nil {\n\t\tfor _, kind := range *o.Flags.IncludeTypes {\n\t\t\tapi, err := o.Client.ResolveAPIResource(kind)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tincludeAPIs = append(includeAPIs, *api)\n\t\t}\n\t}\n\n\t// Keep only objects that matches any included resource type\n\tif len(includeAPIs) > 0 {\n\t\tincludeGKSet := client.ResourcesToGroupKindSet(includeAPIs)\n\t\tnewRlsObjs := []unstructuredv1.Unstructured{}\n\t\tfor _, i := range rlsObjs {\n\t\t\tif _, ok := includeGKSet[i.GroupVersionKind().GroupKind()]; ok {\n\t\t\t\tnewRlsObjs = append(newRlsObjs, i)\n\t\t\t}\n\t\t}\n\t\trlsObjs = newRlsObjs\n\t\tif stgObj != nil {\n\t\t\tif _, ok := includeGKSet[stgObj.GroupVersionKind().GroupKind()]; !ok {\n\t\t\t\tstgObj = nil\n\t\t\t}\n\t\t}\n\t}\n\t// Filter out objects that matches any excluded resource type\n\tif len(excludeAPIs) > 0 {\n\t\texcludeGKSet := client.ResourcesToGroupKindSet(excludeAPIs)\n\t\tnewRlsObjs := []unstructuredv1.Unstructured{}\n\t\tfor _, i := range rlsObjs {\n\t\t\tif _, ok := excludeGKSet[i.GroupVersionKind().GroupKind()]; !ok {\n\t\t\t\tnewRlsObjs = append(newRlsObjs, i)\n\t\t\t}\n\t\t}\n\t\trlsObjs = newRlsObjs\n\t\tif stgObj != nil {\n\t\t\tif _, ok := excludeGKSet[stgObj.GroupVersionKind().GroupKind()]; ok {\n\t\t\t\tstgObj = nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine the namespaces to list objects\n\tvar namespaces []string\n\tnsSet := map[string]struct{}{o.Namespace: {}}\n\tfor _, obj := range rlsObjs {\n\t\tnsSet[obj.GetNamespace()] = struct{}{}\n\t}\n\tfor ns := range nsSet {\n\t\tnamespaces = append(namespaces, ns)\n\t}\n\tif o.Flags.AllNamespaces != nil && *o.Flags.AllNamespaces {\n\t\tnamespaces = append(namespaces, \"\")\n\t}\n\tif o.Flags.Scopes != nil {\n\t\tnamespaces = append(namespaces, *o.Flags.Scopes...)\n\t}\n\n\t// Fetch resources in the cluster\n\tobjs, err := o.Client.List(ctx, client.ListOptions{\n\t\tAPIResourcesToExclude: excludeAPIs,\n\t\tAPIResourcesToInclude: includeAPIs,\n\t\tNamespaces:            namespaces,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Include release & secret objects into objects to handle cases where user\n\t// has access to get them individually but unable to list their respective\n\t// resource types\n\tobjs.Items = append(objs.Items, rlsObjs...)\n\tif stgObj != nil {\n\t\tobjs.Items = append(objs.Items, *stgObj)\n\t}\n\n\t// Collect UIDs from release & storage objects\n\tvar uids []types.UID\n\tfor _, obj := range rlsObjs {\n\t\tuids = append(uids, obj.GetUID())\n\t}\n\tif stgObj != nil {\n\t\tuids = append(uids, stgObj.GetUID())\n\t}\n\n\t// Find all dependents of the release & storage objects\n\tmapper := o.Client.GetMapper()\n\tnodeMap, err := graph.ResolveDependents(mapper, objs.Items, uids)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Add the Helm release object to the root of the relationship tree\n\trootNode := newReleaseNode(rls)\n\tfor _, obj := range rlsObjs {\n\t\trootNode.AddDependent(obj.GetUID(), graph.RelationshipHelmRelease)\n\t}\n\tif stgObj != nil {\n\t\trootNode.AddDependent(stgObj.GetUID(), graph.RelationshipHelmStorage)\n\t}\n\tfor _, node := range nodeMap {\n\t\tnode.Depth++\n\t}\n\trootUID := rootNode.GetUID()\n\tnodeMap[rootUID] = rootNode\n\n\t// Print output\n\treturn o.Printer.Print(o.Out, nodeMap, rootUID, *o.Flags.Depth, false)\n}\n\n// getManifestObjects fetches all objects found in the manifest of the provided\n// Helm release.\nfunc (o *CmdOptions) getManifestObjects(_ context.Context, rls *release.Release) ([]unstructuredv1.Unstructured, error) {\n\tvar objs []unstructuredv1.Unstructured\n\tname, ns := rls.Name, rls.Namespace\n\tr := strings.NewReader(rls.Manifest)\n\tsource := fmt.Sprintf(\"manifest for release \\\"%s\\\" in the namespace \\\"%s\\\"\", name, ns)\n\tresult := resource.NewBuilder(o.ActionConfig.RESTClientGetter).\n\t\tUnstructured().\n\t\tNamespaceParam(ns).\n\t\tDefaultNamespace().\n\t\tContinueOnError().\n\t\tLatest().\n\t\tFlatten().\n\t\tStream(r, source).\n\t\tDo()\n\tinfos, err := result.Infos()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, info := range infos {\n\t\tu, err := runtime.DefaultUnstructuredConverter.ToUnstructured(info.Object)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tobjs = append(objs, unstructuredv1.Unstructured{Object: u})\n\t}\n\n\treturn objs, nil\n}\n\n// getStorageObject fetches the underlying object that stores the information of\n// the provided Helm release.\nfunc (o *CmdOptions) getStorageObject(ctx context.Context, rls *release.Release) (*unstructuredv1.Unstructured, error) {\n\tvar api client.APIResource\n\tswitch o.HelmDriver {\n\tcase \"secret\", \"\":\n\t\tapi = client.APIResource{Version: \"v1\", Kind: \"Secret\", Name: \"secrets\", Namespaced: true}\n\tcase \"configmap\":\n\t\tapi = client.APIResource{Version: \"v1\", Kind: \"ConfigMap\", Name: \"configmaps\", Namespaced: true}\n\tcase \"memory\", \"sql\":\n\t\treturn nil, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"helm driver \\\"%s\\\" not supported\", o.HelmDriver)\n\t}\n\treturn o.Client.Get(ctx, makeKey(rls.Name, rls.Version), client.GetOptions{\n\t\tAPIResource: api,\n\t\tNamespace:   o.Namespace,\n\t})\n}\n\n// getReleaseReadyStatus returns the ready & status value of a Helm release\n// object.\nfunc getReleaseReadyStatus(rls *release.Release) (string, string) {\n\tswitch rls.Info.Status {\n\tcase release.StatusDeployed:\n\t\treturn \"True\", \"Deployed\"\n\tcase release.StatusFailed:\n\t\treturn \"False\", \"Failed\"\n\tcase release.StatusPendingInstall:\n\t\treturn \"False\", \"PendingInstall\"\n\tcase release.StatusPendingRollback:\n\t\treturn \"False\", \"PendingRollback\"\n\tcase release.StatusPendingUpgrade:\n\t\treturn \"False\", \"PendingUpgrade\"\n\tcase release.StatusSuperseded:\n\t\treturn \"False\", \"Superseded\"\n\tcase release.StatusUninstalled:\n\t\treturn \"False\", \"Uninstalled\"\n\tcase release.StatusUninstalling:\n\t\treturn \"False\", \"Uninstalling\"\n\tcase release.StatusUnknown:\n\t\tfallthrough\n\tdefault:\n\t\treturn \"False\", \"Unknown\"\n\t}\n}\n\n// newReleaseNode converts a Helm release object into a Node in the relationship\n// tree.\nfunc newReleaseNode(rls *release.Release) *graph.Node {\n\troot := new(unstructuredv1.Unstructured)\n\tready, status := getReleaseReadyStatus(rls)\n\t// Set \"Ready\" condition values based on the printer.objectReadyReasonJSONPath\n\t// & printer.objectReadyStatusJSONPath paths\n\troot.SetUnstructuredContent(\n\t\tmap[string]interface{}{\n\t\t\t\"status\": map[string]interface{}{\n\t\t\t\t\"conditions\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"type\":   \"Ready\",\n\t\t\t\t\t\t\"status\": ready,\n\t\t\t\t\t\t\"reason\": status,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n\troot.SetUID(types.UID(\"\"))\n\troot.SetName(rls.Name)\n\troot.SetNamespace(rls.Namespace)\n\troot.SetCreationTimestamp(metav1.Time{Time: rls.Info.FirstDeployed.Time})\n\n\treturn &graph.Node{\n\t\tUnstructured: root,\n\t\tUID:          root.GetUID(),\n\t\tName:         root.GetName(),\n\t\tNamespace:    root.GetNamespace(),\n\t\tDependents:   map[types.UID]graph.RelationshipSet{},\n\t}\n}\n\n// makeKey concatenates the Kubernetes storage object type, a release name and version\n// into a string with format:```<helm_storage_type>.<release_name>.v<release_version>```.\n// The storage type is prepended to keep name uniqueness between different\n// release storage types. An example of clash when not using the type:\n// https://github.com/helm/helm/issues/6435.\n// This key is used to uniquely identify storage objects.\n//\n// NOTE: Unfortunately the makeKey function isn't exported by the\n// helm.sh/helm/v3/pkg/storage package so we will have to copy-paste it here.\n// ref: https://github.com/helm/helm/blob/v3.7.0/pkg/storage/storage.go#L245-L253\nfunc makeKey(rlsname string, version int) string {\n\treturn fmt.Sprintf(\"%s.%s.v%d\", storage.HelmStorageType, rlsname, version)\n}\n"
  },
  {
    "path": "pkg/cmd/lineage/completion.go",
    "content": "package lineage\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n)\n\n// compGetResourceList provides dynamic auto-completion for resource names.\nfunc compGetResourceList(opts *CmdOptions, toComplete string) []string {\n\tcobra.CompDebugln(fmt.Sprintf(\"compGetResourceList with \\\"%s\\\"\", toComplete), false)\n\tif err := opts.Complete(nil, nil); err != nil {\n\t\treturn nil\n\t}\n\n\tvar choices []string\n\tapis, err := opts.Client.GetAPIResources(context.Background())\n\tif err != nil {\n\t\tcobra.CompErrorln(fmt.Sprintf(\"Failed to list API resources: %s\", err))\n\t\treturn nil\n\t}\n\tfor _, api := range apis {\n\t\tchoices = append(choices, api.WithGroupString())\n\t}\n\tif len(choices) == 0 {\n\t\tcobra.CompDebugln(\"No API resources found\", false)\n\t\treturn nil\n\t}\n\n\treturn choices\n}\n"
  },
  {
    "path": "pkg/cmd/lineage/flags.go",
    "content": "package lineage\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/completion\"\n)\n\nconst (\n\tflagAllNamespaces          = \"all-namespaces\"\n\tflagAllNamespacesShorthand = \"A\"\n\tflagDependencies           = \"dependencies\"\n\tflagDependenciesShorthand  = \"D\"\n\tflagDepth                  = \"depth\"\n\tflagDepthShorthand         = \"d\"\n\tflagExcludeTypes           = \"exclude-types\"\n\tflagIncludeTypes           = \"include-types\"\n\tflagScopes                 = \"scopes\"\n\tflagScopesShorthand        = \"S\"\n)\n\n// Flags composes common configuration flag structs used in the command.\ntype Flags struct {\n\tAllNamespaces *bool\n\tDependencies  *bool\n\tDepth         *uint\n\tExcludeTypes  *[]string\n\tIncludeTypes  *[]string\n\tScopes        *[]string\n}\n\n// Copy returns a copy of Flags for mutation.\nfunc (f *Flags) Copy() Flags {\n\tFlags := *f\n\treturn Flags\n}\n\n// AddFlags receives a *pflag.FlagSet reference and binds flags related to\n// configuration to it.\nfunc (f *Flags) AddFlags(flags *pflag.FlagSet) {\n\tif f.AllNamespaces != nil {\n\t\tflags.BoolVarP(f.AllNamespaces, flagAllNamespaces, flagAllNamespacesShorthand, *f.AllNamespaces, \"If present, list object relationships across all namespaces\")\n\t}\n\tif f.Dependencies != nil {\n\t\tflags.BoolVarP(f.Dependencies, flagDependencies, flagDependenciesShorthand, *f.Dependencies, \"If present, list object dependencies instead of dependents\")\n\t}\n\tif f.Depth != nil {\n\t\tflags.UintVarP(f.Depth, flagDepth, flagDepthShorthand, *f.Depth, \"Maximum depth to find relationships\")\n\t}\n\tif f.ExcludeTypes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of resource types to exclude from relationship discovery. You can also use multiple flag options like --%s kind1 --%s kind1...\", flagExcludeTypes, flagExcludeTypes)\n\t\tflags.StringSliceVar(f.ExcludeTypes, flagExcludeTypes, *f.ExcludeTypes, usage)\n\t}\n\tif f.IncludeTypes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of resource types to only include in relationship discovery. You can also use multiple flag options like --%s kind1 --%s kind1...\", flagIncludeTypes, flagIncludeTypes)\n\t\tflags.StringSliceVar(f.IncludeTypes, flagIncludeTypes, *f.IncludeTypes, usage)\n\t}\n\tif f.Scopes != nil {\n\t\tusage := fmt.Sprintf(\"Accepts a comma separated list of additional namespaces to find relationships. You can also use multiple flag options like -%s namespace1 -%s namespace2...\", flagScopesShorthand, flagScopesShorthand)\n\t\tflags.StringSliceVarP(f.Scopes, flagScopes, flagScopesShorthand, *f.Scopes, usage)\n\t}\n}\n\n// RegisterFlagCompletionFunc receives a *cobra.Command & register functions to\n// to provide completion for flags related to configuration.\nfunc (*Flags) RegisterFlagCompletionFunc(cmd *cobra.Command, f cmdutil.Factory) {\n\tcmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(\n\t\tflagScopes,\n\t\tfunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\treturn completion.GetScopeNamespaceList(f, cmd, toComplete), cobra.ShellCompDirectiveNoFileComp\n\t\t}))\n}\n\n// NewFlags returns flags associated with command configuration, with default\n// values set.\nfunc NewFlags() *Flags {\n\tallNamespaces := false\n\tdependencies := false\n\tdepth := uint(0)\n\texcludeTypes := []string{}\n\tincludeTypes := []string{}\n\tscopes := []string{}\n\n\treturn &Flags{\n\t\tAllNamespaces: &allNamespaces,\n\t\tDependencies:  &dependencies,\n\t\tDepth:         &depth,\n\t\tExcludeTypes:  &excludeTypes,\n\t\tIncludeTypes:  &includeTypes,\n\t\tScopes:        &scopes,\n\t}\n}\n"
  },
  {
    "path": "pkg/cmd/lineage/lineage.go",
    "content": "package lineage\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/kubectl/pkg/cmd/get\"\n\tcmdutil \"k8s.io/kubectl/pkg/cmd/util\"\n\t\"k8s.io/kubectl/pkg/util\"\n\t\"k8s.io/kubectl/pkg/util/templates\"\n\n\t\"github.com/tohjustin/kube-lineage/internal/client\"\n\t\"github.com/tohjustin/kube-lineage/internal/graph\"\n\t\"github.com/tohjustin/kube-lineage/internal/log\"\n\tlineageprinters \"github.com/tohjustin/kube-lineage/internal/printers\"\n)\n\nvar (\n\tcmdPath    string\n\tcmdName    = \"lineage\"\n\tcmdUse     = \"%CMD% (TYPE[.VERSION][.GROUP] [NAME] | TYPE[.VERSION][.GROUP]/NAME) [flags]\"\n\tcmdExample = templates.Examples(`\n\t\t# List all dependents of the deployment named \"bar\" in the current namespace\n\t\t%CMD_PATH% deployments bar\n\n\t\t# List all dependents of the cronjob named \"bar\" in namespace \"foo\"\n\t\t%CMD_PATH% cronjobs.batch/bar --namespace=foo\n\n\t\t# List all dependents of the node named \"k3d-dev-server\" & the corresponding relationship type(s)\n\t\t%CMD_PATH% node/k3d-dev-server --output=wide\n\n\t\t# List all dependents of the persistentvolume named \"disk\", excluding event & secret resource types\n\t\t%CMD_PATH% pv/disk --dependencies --exclude-types=ev,secret\n\n\t\t# List all dependencies of the pod named \"bar-5cc79d4bf5-xgvkc\"\n\t\t%CMD_PATH% pod.v1. bar-5cc79d4bf5-xgvkc --dependencies\n\n\t\t# List all dependencies of the serviceaccount named \"default\" in the current namespace, grouped by resource type\n\t\t%CMD_PATH% sa/default --dependencies --output=split`)\n\tcmdShort = \"Display all dependencies or dependents of a Kubernetes object\"\n\tcmdLong  = templates.LongDesc(`\n\t\tDisplay all dependencies or dependents of a Kubernetes object.\n\n\t\tTYPE is a Kubernetes resource. Shortcuts and groups will be resolved.\n\t\tNAME is the name of a particular Kubernetes resource.`)\n)\n\n// CmdOptions contains all the options for running the lineage command.\ntype CmdOptions struct {\n\t// RequestType represents the type of the requested object.\n\tRequestType string\n\t// RequestName represents the name of the requested object.\n\tRequestName string\n\tFlags       *Flags\n\n\tNamespace   string\n\tClient      client.Interface\n\tClientFlags *client.Flags\n\n\tPrinter    lineageprinters.Interface\n\tPrintFlags *lineageprinters.Flags\n\n\tgenericclioptions.IOStreams\n}\n\n// NewCmd returns an initialized Command for the lineage command.\nfunc NewCmd(streams genericclioptions.IOStreams, name, parentCmdPath string) *cobra.Command {\n\to := &CmdOptions{\n\t\tFlags:       NewFlags(),\n\t\tClientFlags: client.NewFlags(),\n\t\tPrintFlags:  lineageprinters.NewFlags(),\n\t\tIOStreams:   streams,\n\t}\n\n\tf := cmdutil.NewFactory(o.ClientFlags)\n\tutil.SetFactoryForCompletion(f)\n\n\tif len(name) > 0 {\n\t\tcmdName = name\n\t}\n\tcmdPath = cmdName\n\tif len(parentCmdPath) > 0 {\n\t\tcmdPath = parentCmdPath + \" \" + cmdName\n\t}\n\tcmd := &cobra.Command{\n\t\tUse:                   strings.ReplaceAll(cmdUse, \"%CMD%\", cmdName),\n\t\tExample:               strings.ReplaceAll(cmdExample, \"%CMD_PATH%\", cmdPath),\n\t\tShort:                 cmdShort,\n\t\tLong:                  cmdLong,\n\t\tArgs:                  cobra.MaximumNArgs(2),\n\t\tDisableFlagsInUseLine: true,\n\t\tDisableSuggestions:    true,\n\t\tSilenceUsage:          true,\n\t\tRun: func(c *cobra.Command, args []string) {\n\t\t\tklog.V(4).Infof(\"Version: %s\", c.Root().Version)\n\t\t\tcmdutil.CheckErr(o.Complete(c, args))\n\t\t\tcmdutil.CheckErr(o.Validate())\n\t\t\tcmdutil.CheckErr(o.Run())\n\t\t},\n\t\tValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\t\tvar comps []string\n\t\t\tswitch len(args) {\n\t\t\tcase 0:\n\t\t\t\tcomps = compGetResourceList(o, toComplete)\n\t\t\tcase 1:\n\t\t\t\tcomps = get.CompGetResource(f, cmd, args[0], toComplete)\n\t\t\t}\n\t\t\treturn comps, cobra.ShellCompDirectiveNoFileComp\n\t\t},\n\t}\n\n\t// Setup flags\n\to.Flags.AddFlags(cmd.Flags())\n\to.ClientFlags.AddFlags(cmd.Flags())\n\to.PrintFlags.AddFlags(cmd.Flags())\n\tlog.AddFlags(cmd.Flags())\n\n\t// Setup flag completion function\n\to.Flags.RegisterFlagCompletionFunc(cmd, f)\n\to.ClientFlags.RegisterFlagCompletionFunc(cmd, f)\n\n\treturn cmd\n}\n\n// Complete completes all the required options for the lineage command.\nfunc (o *CmdOptions) Complete(cmd *cobra.Command, args []string) error {\n\tvar err error\n\n\tswitch len(args) {\n\tcase 1:\n\t\tresourceTokens := strings.SplitN(args[0], \"/\", 2)\n\t\tif len(resourceTokens) != 2 {\n\t\t\treturn fmt.Errorf(\"arguments in <resource>/<name> form must have a single resource and name\\nSee '%s -h' for help and examples\", cmdPath)\n\t\t}\n\t\to.RequestType = resourceTokens[0]\n\t\to.RequestName = resourceTokens[1]\n\tcase 2:\n\t\to.RequestType = args[0]\n\t\to.RequestName = args[1]\n\t}\n\n\t// Setup client\n\to.Namespace, _, err = o.ClientFlags.ToRawKubeConfigLoader().Namespace()\n\tif err != nil {\n\t\treturn err\n\t}\n\to.Client, err = o.ClientFlags.ToClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Setup printer\n\to.Printer, err = o.PrintFlags.ToPrinter(o.Client)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// Validate validates all the required options for the lineage command.\nfunc (o *CmdOptions) Validate() error {\n\tif len(o.RequestType) == 0 || len(o.RequestName) == 0 {\n\t\treturn fmt.Errorf(\"resource must be specified as <resource> <name> or <resource>/<name>\\nSee '%s -h' for help and examples\", cmdPath)\n\t}\n\n\tklog.V(4).Infof(\"Namespace: %s\", o.Namespace)\n\tklog.V(4).Infof(\"RequestType: %v\", o.RequestType)\n\tklog.V(4).Infof(\"RequestName: %v\", o.RequestName)\n\tklog.V(4).Infof(\"Flags.AllNamespaces: %t\", *o.Flags.AllNamespaces)\n\tklog.V(4).Infof(\"Flags.Dependencies: %t\", *o.Flags.Dependencies)\n\tklog.V(4).Infof(\"Flags.Depth: %v\", *o.Flags.Depth)\n\tklog.V(4).Infof(\"Flags.ExcludeTypes: %v\", *o.Flags.ExcludeTypes)\n\tklog.V(4).Infof(\"Flags.IncludeTypes: %v\", *o.Flags.IncludeTypes)\n\tklog.V(4).Infof(\"Flags.Scopes: %v\", *o.Flags.Scopes)\n\tklog.V(4).Infof(\"ClientFlags.Context: %s\", *o.ClientFlags.Context)\n\tklog.V(4).Infof(\"ClientFlags.Namespace: %s\", *o.ClientFlags.Namespace)\n\tklog.V(4).Infof(\"PrintFlags.OutputFormat: %s\", *o.PrintFlags.OutputFormat)\n\tklog.V(4).Infof(\"PrintFlags.NoHeaders: %t\", *o.PrintFlags.HumanReadableFlags.NoHeaders)\n\tklog.V(4).Infof(\"PrintFlags.ShowGroup: %t\", *o.PrintFlags.HumanReadableFlags.ShowGroup)\n\tklog.V(4).Infof(\"PrintFlags.ShowLabels: %t\", *o.PrintFlags.HumanReadableFlags.ShowLabels)\n\tklog.V(4).Infof(\"PrintFlags.ShowNamespace: %t\", *o.PrintFlags.HumanReadableFlags.ShowNamespace)\n\n\treturn nil\n}\n\n// Run implements all the necessary functionality for the lineage command.\n//nolint:funlen\nfunc (o *CmdOptions) Run() error {\n\tctx := context.Background()\n\n\t// First check if Kubernetes cluster is reachable\n\tif err := o.Client.IsReachable(); err != nil {\n\t\treturn err\n\t}\n\n\t// Fetch the provided object to ensure it exists before proceeding\n\tapi, err := o.Client.ResolveAPIResource(o.RequestType)\n\tif err != nil {\n\t\treturn err\n\t}\n\tobj := client.ObjectMeta{\n\t\tAPIResource: *api,\n\t\tName:        o.RequestName,\n\t\tNamespace:   o.Namespace,\n\t}\n\troot, err := o.Client.Get(ctx, obj.Name, client.GetOptions{\n\t\tAPIResource: obj.APIResource,\n\t\tNamespace:   o.Namespace,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Determine resources to list\n\texcludeAPIs := []client.APIResource{}\n\tif o.Flags.ExcludeTypes != nil {\n\t\tfor _, kind := range *o.Flags.ExcludeTypes {\n\t\t\tapi, err := o.Client.ResolveAPIResource(kind)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\texcludeAPIs = append(excludeAPIs, *api)\n\t\t}\n\t}\n\tincludeAPIs := []client.APIResource{}\n\tif o.Flags.IncludeTypes != nil {\n\t\tfor _, kind := range *o.Flags.IncludeTypes {\n\t\t\tapi, err := o.Client.ResolveAPIResource(kind)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tincludeAPIs = append(includeAPIs, *api)\n\t\t}\n\t}\n\n\t// Determine the namespaces to list objects\n\tnamespaces := []string{o.Namespace}\n\tif o.Flags.AllNamespaces != nil && *o.Flags.AllNamespaces {\n\t\tnamespaces = append(namespaces, \"\")\n\t}\n\tif o.Flags.Scopes != nil {\n\t\tnamespaces = append(namespaces, *o.Flags.Scopes...)\n\t}\n\n\t// Fetch resources in the cluster\n\tobjs, err := o.Client.List(ctx, client.ListOptions{\n\t\tAPIResourcesToExclude: excludeAPIs,\n\t\tAPIResourcesToInclude: includeAPIs,\n\t\tNamespaces:            namespaces,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Include root object into objects to handle cases where user has access\n\t// to get the root object but unable to list its resource type\n\tobjs.Items = append(objs.Items, *root)\n\n\t// Find either all dependencies or dependents of the root object\n\tdepsIsDependencies, resolveDeps := false, graph.ResolveDependents\n\tif o.Flags.Dependencies != nil && *o.Flags.Dependencies {\n\t\tdepsIsDependencies, resolveDeps = true, graph.ResolveDependencies\n\t}\n\tmapper := o.Client.GetMapper()\n\trootUID := root.GetUID()\n\tnodeMap, err := resolveDeps(mapper, objs.Items, []types.UID{rootUID})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Print output\n\treturn o.Printer.Print(o.Out, nodeMap, rootUID, *o.Flags.Depth, depsIsDependencies)\n}\n"
  },
  {
    "path": "scripts/fetch.sh",
    "content": "#!/usr/bin/env bash\n\nROOT=$(git rev-parse --show-toplevel)\n\nfetch() {\n  local tool=$1; shift\n  local ver=$1; shift\n\n  local ver_cmd=\"\"\n  local tool_fetch_cmd=\"\"\n  case \"$tool\" in\n    \"golangci-lint\")\n      ver_cmd=\"${ROOT}/bin/golangci-lint --version 2>/dev/null | cut -d' ' -f4\"\n      fetch_cmd=\"curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v${ver}/install.sh | sh -s -- -b \\\"${ROOT}/bin\\\" \\\"v${ver}\\\"\"\n      ;;\n    \"goreleaser\")\n      ver_cmd=\"${ROOT}/bin/goreleaser --version 2>/dev/null | grep 'goreleaser version' | cut -d' ' -f3\"\n      fetch_cmd=\"cat ${ROOT}/scripts/goreleaser_install.sh | sh -s -- -b \\\"${ROOT}/bin\\\" -d \\\"v${ver}\\\"\"\n      ;;\n    *)\n      echo \"unknown tool $tool\"\n      return 1\n      ;;\n  esac\n\n  if [[ \"${ver}\" != \"$(eval ${ver_cmd})\" ]]; then\n    echo \"${tool} missing or not version '${ver}', downloading...\"\n    eval ${fetch_cmd}\n  fi\n}\n"
  },
  {
    "path": "scripts/goreleaser_install.sh",
    "content": "#!/bin/sh\nset -e\n# Code generated by godownloader on 2019-12-25T12:47:14Z. DO NOT EDIT.\n#\n\nusage() {\n\tthis=$1\n\tcat <<EOF\n$this: download go binaries for goreleaser/goreleaser\n\nUsage: $this [-b] bindir [-d] [tag]\n  -b sets bindir or installation directory, Defaults to ./bin\n  -d turns on debug logging\n   [tag] is a tag from\n   https://github.com/goreleaser/goreleaser/releases\n   If tag is missing, then the latest will be used.\n\n Generated by godownloader\n  https://github.com/goreleaser/godownloader\n\nEOF\n\texit 2\n}\n\nparse_args() {\n\t#BINDIR is ./bin unless set be ENV\n\t# over-ridden by flag below\n\n\tBINDIR=${BINDIR:-./bin}\n\twhile getopts \"b:dh?x\" arg; do\n\t\tcase \"$arg\" in\n\t\tb) BINDIR=\"$OPTARG\" ;;\n\t\td) log_set_priority 10 ;;\n\t\th | \\?) usage \"$0\" ;;\n\t\tx) set -x ;;\n\t\tesac\n\tdone\n\tshift $((OPTIND - 1))\n\tTAG=$1\n}\n# this function wraps all the destructive operations\n# if a curl|bash cuts off the end of the script due to\n# network, either nothing will happen or will syntax error\n# out preventing half-done work\nexecute() {\n\ttmpdir=$(mktemp -d)\n\tlog_debug \"downloading files into ${tmpdir}\"\n\thttp_download \"${tmpdir}/${TARBALL}\" \"${TARBALL_URL}\"\n\thttp_download \"${tmpdir}/${CHECKSUM}\" \"${CHECKSUM_URL}\"\n\thash_sha256_verify \"${tmpdir}/${TARBALL}\" \"${tmpdir}/${CHECKSUM}\"\n\tsrcdir=\"${tmpdir}\"\n\t(cd \"${tmpdir}\" && untar \"${TARBALL}\")\n\ttest ! -d \"${BINDIR}\" && install -d \"${BINDIR}\"\n\tfor binexe in $BINARIES; do\n\t\tif [ \"$OS\" = \"windows\" ]; then\n\t\t\tbinexe=\"${binexe}.exe\"\n\t\tfi\n\t\tinstall \"${srcdir}/${binexe}\" \"${BINDIR}/\"\n\t\tlog_info \"installed ${BINDIR}/${binexe}\"\n\tdone\n\trm -rf \"${tmpdir}\"\n}\nget_binaries() {\n\tcase \"$PLATFORM\" in\n\tdarwin/all) BINARIES=\"goreleaser\" ;;\n\tdarwin/386) BINARIES=\"goreleaser\" ;;\n\tdarwin/amd64) BINARIES=\"goreleaser\" ;;\n\tdarwin/arm64) BINARIES=\"goreleaser\" ;;\n\tdarwin/armv6) BINARIES=\"goreleaser\" ;;\n\tlinux/386) BINARIES=\"goreleaser\" ;;\n\tlinux/amd64) BINARIES=\"goreleaser\" ;;\n\tlinux/arm64) BINARIES=\"goreleaser\" ;;\n\tlinux/armv6) BINARIES=\"goreleaser\" ;;\n\twindows/386) BINARIES=\"goreleaser\" ;;\n\twindows/amd64) BINARIES=\"goreleaser\" ;;\n\twindows/arm64) BINARIES=\"goreleaser\" ;;\n\twindows/armv6) BINARIES=\"goreleaser\" ;;\n\t*)\n\t\tlog_crit \"platform $PLATFORM is not supported.  Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new\"\n\t\texit 1\n\t\t;;\n\tesac\n}\ntag_to_version() {\n\tif [ -z \"${TAG}\" ]; then\n\t\tlog_info \"checking GitHub for latest tag\"\n\telse\n\t\tlog_info \"checking GitHub for tag '${TAG}'\"\n\tfi\n\tREALTAG=$(github_release \"$OWNER/$REPO\" \"${TAG}\") && true\n\tif test -z \"$REALTAG\"; then\n\t\tlog_crit \"unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details\"\n\t\texit 1\n\tfi\n\t# if version starts with 'v', remove it\n\tTAG=\"$REALTAG\"\n\tVERSION=${TAG#v}\n}\nadjust_format() {\n\t# change format (tar.gz or zip) based on OS\n\tcase ${OS} in\n\twindows) FORMAT=zip ;;\n\tesac\n\ttrue\n}\nadjust_os() {\n\t# adjust archive name based on OS\n\tcase ${OS} in\n\t386) OS=i386 ;;\n\tamd64) OS=x86_64 ;;\n\tdarwin) OS=Darwin ;;\n\tlinux) OS=Linux ;;\n\twindows) OS=Windows ;;\n\tesac\n\ttrue\n}\nadjust_arch() {\n\t# adjust archive name based on ARCH\n\tcase ${ARCH} in\n\t386) ARCH=i386 ;;\n\tamd64) ARCH=x86_64 ;;\n\tdarwin) ARCH=Darwin ;;\n\tlinux) ARCH=Linux ;;\n\twindows) ARCH=Windows ;;\n\tesac\n\ttrue\n}\n\ncat /dev/null <<EOF\n------------------------------------------------------------------------\nhttps://github.com/client9/shlib - portable posix shell functions\nPublic domain - http://unlicense.org\nhttps://github.com/client9/shlib/blob/master/LICENSE.md\nbut credit (and pull requests) appreciated.\n------------------------------------------------------------------------\nEOF\nis_command() {\n\tcommand -v \"$1\" >/dev/null\n}\nechoerr() {\n\techo \"$@\" 1>&2\n}\nlog_prefix() {\n\techo \"$0\"\n}\n_logp=6\nlog_set_priority() {\n\t_logp=\"$1\"\n}\nlog_priority() {\n\tif test -z \"$1\"; then\n\t\techo \"$_logp\"\n\t\treturn\n\tfi\n\t[ \"$1\" -le \"$_logp\" ]\n}\nlog_tag() {\n\tcase $1 in\n\t0) echo \"emerg\" ;;\n\t1) echo \"alert\" ;;\n\t2) echo \"crit\" ;;\n\t3) echo \"err\" ;;\n\t4) echo \"warning\" ;;\n\t5) echo \"notice\" ;;\n\t6) echo \"info\" ;;\n\t7) echo \"debug\" ;;\n\t*) echo \"$1\" ;;\n\tesac\n}\nlog_debug() {\n\tlog_priority 7 || return 0\n\techoerr \"$(log_prefix)\" \"$(log_tag 7)\" \"$@\"\n}\nlog_info() {\n\tlog_priority 6 || return 0\n\techoerr \"$(log_prefix)\" \"$(log_tag 6)\" \"$@\"\n}\nlog_err() {\n\tlog_priority 3 || return 0\n\techoerr \"$(log_prefix)\" \"$(log_tag 3)\" \"$@\"\n}\nlog_crit() {\n\tlog_priority 2 || return 0\n\techoerr \"$(log_prefix)\" \"$(log_tag 2)\" \"$@\"\n}\nuname_os() {\n\tos=$(uname -s | tr '[:upper:]' '[:lower:]')\n\tcase \"$os\" in\n\tcygwin_nt*) os=\"windows\" ;;\n\tmingw*) os=\"windows\" ;;\n\tmsys_nt*) os=\"windows\" ;;\n\tesac\n\techo \"$os\"\n}\nuname_arch() {\n\tarch=$(uname -m)\n\tcase $arch in\n\tx86_64) arch=\"amd64\" ;;\n\tx86) arch=\"386\" ;;\n\ti686) arch=\"386\" ;;\n\ti386) arch=\"386\" ;;\n\taarch64) arch=\"arm64\" ;;\n\tarmv5*) arch=\"armv5\" ;;\n\tarmv6*) arch=\"armv6\" ;;\n\tarmv7*) arch=\"armv7\" ;;\n\tesac\n\tos=$(uname_os)\n\tcase \"$os\" in\n\tdarwin) arch=\"all\" ;;\n\tesac\n\techo ${arch}\n}\nuname_os_check() {\n\tos=$(uname_os)\n\tcase \"$os\" in\n\tdarwin) return 0 ;;\n\tdragonfly) return 0 ;;\n\tfreebsd) return 0 ;;\n\tlinux) return 0 ;;\n\tandroid) return 0 ;;\n\tnacl) return 0 ;;\n\tnetbsd) return 0 ;;\n\topenbsd) return 0 ;;\n\tplan9) return 0 ;;\n\tsolaris) return 0 ;;\n\twindows) return 0 ;;\n\tall) return 0 ;;\n\tesac\n\tlog_crit \"uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib\"\n\treturn 1\n}\nuname_arch_check() {\n\tarch=$(uname_arch)\n\tcase \"$arch\" in\n\t386) return 0 ;;\n\tamd64) return 0 ;;\n\tarm64) return 0 ;;\n\tarmv5) return 0 ;;\n\tarmv6) return 0 ;;\n\tarmv7) return 0 ;;\n\tppc64) return 0 ;;\n\tppc64le) return 0 ;;\n\tmips) return 0 ;;\n\tmipsle) return 0 ;;\n\tmips64) return 0 ;;\n\tmips64le) return 0 ;;\n\ts390x) return 0 ;;\n\tamd64p32) return 0 ;;\n\tall) return 0 ;;\n\tesac\n\tlog_crit \"uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value.  Please file bug report at https://github.com/client9/shlib\"\n\treturn 1\n}\nuntar() {\n\ttarball=$1\n\tcase \"${tarball}\" in\n\t*.tar.gz | *.tgz) tar --no-same-owner -xzf \"${tarball}\" ;;\n\t*.tar) tar --no-same-owner -xf \"${tarball}\" ;;\n\t*.zip) unzip \"${tarball}\" ;;\n\t*)\n\t\tlog_err \"untar unknown archive format for ${tarball}\"\n\t\treturn 1\n\t\t;;\n\tesac\n}\nhttp_download_curl() {\n\tlocal_file=$1\n\tsource_url=$2\n\theader=$3\n\tif [ -z \"$header\" ]; then\n\t\tcode=$(curl -w '%{http_code}' -sL -o \"$local_file\" \"$source_url\")\n\telse\n\t\tcode=$(curl -w '%{http_code}' -sL -H \"$header\" -o \"$local_file\" \"$source_url\")\n\tfi\n\tif [ \"$code\" != \"200\" ]; then\n\t\tlog_debug \"http_download_curl received HTTP status $code\"\n\t\treturn 1\n\tfi\n\treturn 0\n}\nhttp_download_wget() {\n\tlocal_file=$1\n\tsource_url=$2\n\theader=$3\n\tif [ -z \"$header\" ]; then\n\t\twget -q -O \"$local_file\" \"$source_url\"\n\telse\n\t\twget -q --header \"$header\" -O \"$local_file\" \"$source_url\"\n\tfi\n}\nhttp_download() {\n\tlog_debug \"http_download $2\"\n\tif is_command curl; then\n\t\thttp_download_curl \"$@\"\n\t\treturn\n\telif is_command wget; then\n\t\thttp_download_wget \"$@\"\n\t\treturn\n\tfi\n\tlog_crit \"http_download unable to find wget or curl\"\n\treturn 1\n}\nhttp_copy() {\n\ttmp=$(mktemp)\n\thttp_download \"${tmp}\" \"$1\" \"$2\" || return 1\n\tbody=$(cat \"$tmp\")\n\trm -f \"${tmp}\"\n\techo \"$body\"\n}\ngithub_release() {\n\towner_repo=$1\n\tversion=$2\n\ttest -z \"$version\" && version=\"latest\"\n\tgiturl=\"https://github.com/${owner_repo}/releases/${version}\"\n\tjson=$(http_copy \"$giturl\" \"Accept:application/json\")\n\ttest -z \"$json\" && return 1\n\tversion=$(echo \"$json\" | tr -s '\\n' ' ' | sed 's/.*\"tag_name\":\"//' | sed 's/\".*//')\n\ttest -z \"$version\" && return 1\n\techo \"$version\"\n}\nhash_sha256() {\n\tTARGET=${1:-/dev/stdin}\n\tif is_command gsha256sum; then\n\t\thash=$(gsha256sum \"$TARGET\") || return 1\n\t\techo \"$hash\" | cut -d ' ' -f 1\n\telif is_command sha256sum; then\n\t\thash=$(sha256sum \"$TARGET\") || return 1\n\t\techo \"$hash\" | cut -d ' ' -f 1\n\telif is_command shasum; then\n\t\thash=$(shasum -a 256 \"$TARGET\" 2>/dev/null) || return 1\n\t\techo \"$hash\" | cut -d ' ' -f 1\n\telif is_command openssl; then\n\t\thash=$(openssl -dst openssl dgst -sha256 \"$TARGET\") || return 1\n\t\techo \"$hash\" | cut -d ' ' -f a\n\telse\n\t\tlog_crit \"hash_sha256 unable to find command to compute sha-256 hash\"\n\t\treturn 1\n\tfi\n}\nhash_sha256_verify() {\n\tTARGET=$1\n\tchecksums=$2\n\tif [ -z \"$checksums\" ]; then\n\t\tlog_err \"hash_sha256_verify checksum file not specified in arg2\"\n\t\treturn 1\n\tfi\n\tBASENAME=${TARGET##*/}\n\twant=$(grep \"${BASENAME}\" \"${checksums}\" 2>/dev/null | tr '\\t' ' ' | cut -d ' ' -f 1)\n\tif [ -z \"$want\" ]; then\n\t\tlog_err \"hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'\"\n\t\treturn 1\n\tfi\n\tgot=$(hash_sha256 \"$TARGET\")\n\tif [ \"$want\" != \"$got\" ]; then\n\t\tlog_err \"hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got\"\n\t\treturn 1\n\tfi\n}\ncat /dev/null <<EOF\n------------------------------------------------------------------------\nEnd of functions from https://github.com/client9/shlib\n------------------------------------------------------------------------\nEOF\n\nPROJECT_NAME=\"goreleaser\"\nOWNER=goreleaser\nREPO=\"goreleaser\"\nBINARY=goreleaser\nFORMAT=tar.gz\nOS=$(uname_os)\nARCH=$(uname_arch)\nPREFIX=\"$OWNER/$REPO\"\n\n# use in logging routines\nlog_prefix() {\n\techo \"$PREFIX\"\n}\nPLATFORM=\"${OS}/${ARCH}\"\nGITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download\n\nuname_os_check \"$OS\"\nuname_arch_check \"$ARCH\"\n\nparse_args \"$@\"\n\nget_binaries\n\ntag_to_version\n\nadjust_format\n\nadjust_os\n\nadjust_arch\n\nlog_info \"found version: ${VERSION} for ${TAG}/${OS}/${ARCH}\"\n\nNAME=${PROJECT_NAME}_${OS}_${ARCH}\nTARBALL=${NAME}.${FORMAT}\nTARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}\nCHECKSUM=checksums.txt\nCHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}\n\nexecute"
  }
]