Full Code of estahn/k8s-image-swapper for AI

main 5ea715ab58ca cached
62 files
320.2 KB
114.6k tokens
143 symbols
1 requests
Download .txt
Showing preview only (338K chars total). Download the full file or copy to clipboard to get everything.
Repository: estahn/k8s-image-swapper
Branch: main
Commit: 5ea715ab58ca
Files: 62
Total size: 320.2 KB

Directory structure:
gitextract_aug9culg/

├── .github/
│   ├── FUNDING.yml
│   ├── dependabot.yml
│   ├── release-drafter.yml
│   ├── release.yml
│   └── workflows/
│       ├── auto-approve.yml
│       ├── auto-merge.yml
│       ├── awaiting-reply.yml
│       ├── codeql-analysis.yml
│       ├── deploy.yml
│       ├── docs.yml
│       ├── pre-commit.yml
│       ├── release-drafter.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .goreleaser.yml
├── .k8s-image-swapper.yml
├── .pre-commit-config.yaml
├── .releaserc
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── cmd/
│   └── root.go
├── docs/
│   ├── configuration.md
│   ├── faq.md
│   ├── getting-started.md
│   ├── index.md
│   └── overrides/
│       └── main.html
├── go.mod
├── go.sum
├── main.go
├── mkdocs.yml
├── package.json
├── pkg/
│   ├── config/
│   │   ├── config.go
│   │   └── config_test.go
│   ├── registry/
│   │   ├── client.go
│   │   ├── ecr.go
│   │   ├── ecr_test.go
│   │   ├── gar.go
│   │   ├── gar_test.go
│   │   └── inmemory.go
│   ├── secrets/
│   │   ├── dummy.go
│   │   ├── dummy_test.go
│   │   ├── kubernetes.go
│   │   ├── kubernetes_test.go
│   │   └── provider.go
│   ├── types/
│   │   ├── types.go
│   │   └── types_test.go
│   └── webhook/
│       ├── image_copier.go
│       ├── image_copier_test.go
│       ├── image_swapper.go
│       └── image_swapper_test.go
└── test/
    ├── curl.sh
    ├── e2e_test.go
    ├── kind-with-registry.sh
    ├── kind.yaml
    └── requests/
        ├── admissionreview-imagepullsecrets.json
        └── admissionreview-simple.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [estahn]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    target-branch: "main"
    schedule:
      interval: "weekly"

  - package-ecosystem: "docker"
    directory: "/"
    target-branch: "main"
    schedule:
      interval: "daily"

  - package-ecosystem: "gomod"
    directory: "/"
    target-branch: "main"
    schedule:
      interval: "weekly"

  - package-ecosystem: "npm"
    directory: "/"
    target-branch: "main"
    schedule:
      interval: "weekly"
    versioning-strategy: increase


================================================
FILE: .github/release-drafter.yml
================================================
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
categories:
  - title: '🚀 Features'
    labels:
      - 'feature'
      - 'enhancement'
  - title: '🐛 Bug Fixes'
    labels:
      - 'fix'
      - 'bugfix'
      - 'bug'
  - title: '📝 Documentation'
    label: 'docs'
  - title: '🧰 Maintenance'
    label: 'chore'
  - title: '⬆️ Dependencies'
    collapse-after: 3
    labels:
      - 'dependencies'
  - title: '👷 Continuous Integration'
    collapse-after: 3
    labels:
      - 'ci'

exclude-labels:
  - 'ignore-for-release'

replacers:
  - search: '/^(fix|feat|ci|build)(\(.+?\))?: /g'
    replace: ''

template: |
  ## What's Changed

  $CHANGES

version-resolver:
  major:
    labels:
      - 'type: breaking'
  minor:
    labels:
      - 'enhancement'
  patch:
    labels:
      - 'bugfix'
      - 'maintenance'
      - 'docs'
      - 'dependencies'
      - 'security'

autolabeler:
  - label: 'bugfix'
    title:
      - '/fix:/i'
  - label: 'enhancement'
    title:
      - '/feat:/i'
  - label: 'docs'
    title:
      - '/docs:/i'
  - label: 'chore'
    title:
      - '/chore:/i'


================================================
FILE: .github/release.yml
================================================
changelog:
  exclude:
    labels:
      - ignore-for-release
    authors:
      - octocat
  categories:
    - title: 🛠 Breaking Changes
      labels:
        - breaking-change
    - title: '🚀 Features'
      labels:
        - 'feature'
        - 'enhancement'
    - title: '🐛 Bug Fixes'
      labels:
        - 'fix'
        - 'bugfix'
        - 'bug'
    - title: '📝 Documentation'
      label: 'docs'
    - title: '🧰 Maintenance'
      label: 'chore'
    - title: '⬆️ Dependencies'
      collapse-after: 3
      labels:
        - 'dependencies'
    - title: '👷 Continuous Integration'
      collapse-after: 3
      labels:
        - 'ci'
    - title: Other Changes
      labels:
        - "*"


================================================
FILE: .github/workflows/auto-approve.yml
================================================
name: Auto approve

on:
  pull_request_target

jobs:
  auto-approve:
    runs-on: ubuntu-latest
    steps:
    - uses: hmarr/auto-approve-action@v4
      if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
      with:
        github-token: "${{ secrets.GITHUB_TOKEN }}"


================================================
FILE: .github/workflows/auto-merge.yml
================================================
name: Auto-Merge
on: pull_request

permissions:
  pull-requests: write
  contents: write

jobs:
  automerge:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - uses: peter-evans/enable-pull-request-automerge@v3
        with:
          pull-request-number: ${{ github.event.pull_request.number }}
          merge-method: squash


================================================
FILE: .github/workflows/awaiting-reply.yml
================================================
on:
  issue_comment:
    types: [created]

jobs:
  awaiting_reply:
    runs-on: ubuntu-latest
    name: Toggle label upon reply
    steps:
      - name: Toggle label
        uses: jd-0001/gh-action-toggle-awaiting-reply-label@v2.1.2
        with:
          label: awaiting-reply
          exclude-members: estahn


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ main ]
    paths-ignore:
      - 'docs/**'
      - 'mkdocs.yml'
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ main ]
  schedule:
    - cron: '42 5 * * 5'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        language: [ 'go' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

    steps:
    - name: Checkout repository
      uses: actions/checkout@v6

    - name: Set up Go
      uses: actions/setup-go@v6
      with:
        go-version-file: 'go.mod'
        check-latest: true
        cache: true

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v4
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v4

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v4


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy

on:
  workflow_call:
    inputs:
      forRef:
        required: true
        type: string
  workflow_dispatch:
    inputs:
      forRef:
        description: 'Branch, SHA or Tag to release'
        required: false
        type: string

permissions:
  contents: write
  packages: write

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  generate-artifacts:
    name: Generate artifacts
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v6
      with:
        ref: ${{ inputs.forRef }}

    - name: Unshallow
      run: git fetch --prune --unshallow

    - name: Ensure release-notes exists
      run: touch /tmp/release-notes.md

    - name: Set up QEMU
      uses: docker/setup-qemu-action@v4

    - name: Set up Docker Buildx
      id: buildx
      uses: docker/setup-buildx-action@v3

    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y libdevmapper-dev libbtrfs-dev

    - name: Set up Go
      uses: actions/setup-go@v6
      with:
        go-version-file: 'go.mod'
        check-latest: true
        cache: true

    - name: Login to github registry
      uses: docker/login-action@v4.1.0
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    - name: Run GoReleaser
      uses: goreleaser/goreleaser-action@v7.0.0
      with:
        version: latest
        args: release --clean
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/docs.yml
================================================
#name: Publish docs
#on:
#  workflow_dispatch:
#  push:
#    branches:
#      - main
#    paths:
#      - 'docs/**'
#      - mkdocs.yml
#
#jobs:
#  build:
#    name: Deploy docs
#    runs-on: ubuntu-latest
#    steps:
#      - name: Checkout main
#        uses: actions/checkout@v3
#        with:
#          fetch-depth: 0
#
#      - uses: actions/setup-python@v4.5.0
#        with:
#          python-version: '3.x'
#
#      - name: Install mkdocs
#        run: pip install --upgrade pip && pip install mike mkdocs mkdocs-minify-plugin mkdocs-markdownextradata-plugin mkdocs-macros-plugin pymdown-extensions mkdocs-material
#
#      - run: git config user.name 'github-actions[bot]' && git config user.email 'github-actions[bot]@users.noreply.github.com'
#
#      - name: Publish docs
#        run: mkdocs gh-deploy


================================================
FILE: .github/workflows/pre-commit.yml
================================================
name: pre-commit

on:
  pull_request:
  push:
    branches: [master]

jobs:
  pre-commit:
    runs-on: ubuntu-latest

    # don't run this on the master branch
    if: github.ref != 'refs/heads/master'

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: actions/setup-python@v6.2.0
        with:
          python-version: '3.x'
      - uses: actions/setup-go@v6
        with:
          go-version-file: 'go.mod'
          check-latest: true
          cache: true
      - name: Install dependencies
        run: sudo apt-get update && sudo apt-get install -y libdevmapper-dev libbtrfs-dev
      - uses: pre-commit/action@v3.0.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/release-drafter.yml
================================================
name: Release Drafter

on:
  workflow_dispatch:
  push:
    # branches to consider in the event; optional, defaults to all
    branches:
      - main
  # pull_request event is required only for autolabeler
  pull_request:
    # Only following types are handled by the action, but one can default to all as well
    types: [opened, reopened, synchronize]
  # pull_request_target event is required for autolabeler to support PRs from forks
  pull_request_target:
    types: [opened, reopened, synchronize]

permissions:
  contents: read

jobs:
  update_release_draft:
    permissions:
      # write permission is required to create a github release
      contents: write
      # write permission is required for autolabeler
      # otherwise, read permission is required at least
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      # (Optional) GitHub Enterprise requires GHE_HOST variable set
      #- name: Set GHE_HOST
      #  run: |
      #    echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV

      # Drafts your next Release notes as Pull Requests are merged into "master"
      - uses: release-drafter/release-drafter@v7
        # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
        # with:
        #   config-name: my-config.yml
        #   disable-autolabeler: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
  workflow_dispatch:
  # Release patches and secruity updates on a schedule
  schedule:
    - cron: "0 0 1 * *"

jobs:
  release:
    permissions:
      contents: write
      pull-requests: write
    runs-on: ubuntu-latest
    outputs:
      tag_name: ${{ steps.release-drafter.outputs.tag_name }}
    steps:
      - id: release-drafter
        uses: release-drafter/release-drafter@v7
        with:
          publish: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  deploy:
    needs: [release]
    uses: ./.github/workflows/deploy.yml
    secrets: inherit
    permissions:
      packages: write
      contents: write
    with:
      forRef: ${{ needs.release.outputs.tag_name }}


================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
  pull_request:
  workflow_dispatch:
  push:
    branches:
      - main
      - 'releases/*'
    paths-ignore:
      - 'docs/**'
      - 'mkdocs.yml'

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

jobs:

  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:

    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y libdevmapper-dev libbtrfs-dev

    - name: Checkout
      uses: actions/checkout@v6

    - name: Set up Go
      uses: actions/setup-go@v6
      with:
        go-version-file: 'go.mod'
        check-latest: true
        cache: true

    - name: golangci-lint
      uses: golangci/golangci-lint-action@v9.2.0
      with:
        version: latest
        args: --timeout=5m

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y libdevmapper-dev libbtrfs-dev

    - name: Checkout
      uses: actions/checkout@v6

    - name: Set up Go
      uses: actions/setup-go@v6
      with:
        go-version-file: 'go.mod'
        check-latest: true
        cache: true

    - uses: actions/cache@v5.0.4
      with:
        path: |
          ~/go/pkg/mod              # Module download cache
          ~/.cache/go-build         # Build cache (Linux)
          ~/Library/Caches/go-build # Build cache (Mac)
          '%LocalAppData%\go-build' # Build cache (Windows)
        key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-

    - name: Test
      run: go test -coverprofile cover.out ./...

    - uses: codecov/codecov-action@v6
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        file: ./cover.out # optional
        fail_ci_if_error: true
        verbose: true

  image-scan:
    name: Image Scan
    runs-on: ubuntu-latest
    steps:

    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y libdevmapper-dev libbtrfs-dev

    - name: Checkout
      uses: actions/checkout@v6

    - name: Set up QEMU
      uses: docker/setup-qemu-action@v4

    - name: Set up Docker Buildx
      id: buildx
      uses: docker/setup-buildx-action@v3

    - name: Unshallow
      run: git fetch --prune --unshallow

    - name: Set up Go
      uses: actions/setup-go@v6
      with:
        go-version-file: 'go.mod'
        check-latest: true
        cache: true

    - uses: actions/cache@v5.0.4
      with:
        path: |
          ~/go/pkg/mod              # Module download cache
          ~/.cache/go-build         # Build cache (Linux)
          ~/Library/Caches/go-build # Build cache (Mac)
          '%LocalAppData%\go-build' # Build cache (Windows)
        key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-

    - name: Run GoReleaser
      uses: goreleaser/goreleaser-action@v7.0.0
      with:
        version: latest
        args: release --clean --skip=validate,publish
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Scan image
      uses: anchore/scan-action@v7
      id: scan
      with:
        image: "ghcr.io/estahn/k8s-image-swapper:latest"
        fail-build: false
        acs-report-enable: true

    - name: Upload Anchore scan SARIF report
      uses: github/codeql-action/upload-sarif@v4
      with:
        sarif_file: ${{ steps.scan.outputs.sarif }}


================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

.idea/
coverage.txt
k8s-image-swapper


================================================
FILE: .goreleaser.yml
================================================
env:
  - GO111MODULE=on

gomod:
  proxy: true

builds:
  - env:
      - CGO_ENABLED=0
    goos:
      #- windows
      - darwin
      - linux
    goarch:
      - amd64
      - arm64
    mod_timestamp: '{{ .CommitTimestamp }}'
    flags:
      - -trimpath
    ldflags:
      - -s -w

dockers:
  - image_templates:
      - "ghcr.io/estahn/k8s-image-swapper:latest-amd64"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Version }}-amd64"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}.{{ .Patch }}-amd64"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}-amd64"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}-amd64"
    use: buildx
    dockerfile: Dockerfile
    goarch: amd64
    build_flag_templates:
      - "--pull"
      - "--label=org.opencontainers.image.created={{.Date}}"
      - "--label=org.opencontainers.image.title={{.ProjectName}}"
      - "--label=org.opencontainers.image.revision={{.FullCommit}}"
      - "--label=org.opencontainers.image.version={{.Version}}"
      - "--build-arg=VERSION={{.Version}}"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--platform=linux/amd64"
  - image_templates:
      - "ghcr.io/estahn/k8s-image-swapper:latest-arm64v8"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Version }}-arm64v8"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}.{{ .Patch }}-arm64v8"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}-arm64v8"
      - "ghcr.io/estahn/k8s-image-swapper:{{ .Major }}-arm64v8"
    use: buildx
    dockerfile: Dockerfile
    goarch: arm64
    build_flag_templates:
    - "--pull"
    - "--label=org.opencontainers.image.created={{.Date}}"
    - "--label=org.opencontainers.image.title={{.ProjectName}}"
    - "--label=org.opencontainers.image.revision={{.FullCommit}}"
    - "--label=org.opencontainers.image.version={{.Version}}"
    - "--build-arg=VERSION={{.Version}}"
    - "--build-arg=BUILD_DATE={{.Date}}"
    - "--build-arg=VCS_REF={{.FullCommit}}"
    - "--platform=linux/arm64/v8"

docker_manifests:
  - name_template: ghcr.io/estahn/k8s-image-swapper:latest
    image_templates:
    - ghcr.io/estahn/k8s-image-swapper:latest-amd64
    - ghcr.io/estahn/k8s-image-swapper:latest-arm64v8
  - name_template: ghcr.io/estahn/k8s-image-swapper:{{ .Version }}
    image_templates:
    - ghcr.io/estahn/k8s-image-swapper:{{ .Version }}-amd64
    - ghcr.io/estahn/k8s-image-swapper:{{ .Version }}-arm64v8
  - name_template: ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}.{{ .Patch }}
    image_templates:
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}.{{ .Patch }}-amd64
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}.{{ .Patch }}-arm64v8
  - name_template: ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}
    image_templates:
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}-amd64
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}.{{ .Minor }}-arm64v8
  - name_template: ghcr.io/estahn/k8s-image-swapper:{{ .Major }}
    image_templates:
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}-amd64
    - ghcr.io/estahn/k8s-image-swapper:{{ .Major }}-arm64v8

release:
  prerelease: auto

changelog:
  filters:
    exclude:
      - '^docs:'
      - '^chore:'

archives:
  - format: binary


================================================
FILE: .k8s-image-swapper.yml
================================================
dryRun: true

logLevel: trace
logFormat: console

# imageSwapPolicy defines the mutation strategy used by the webhook.
# - always: Will always swap the image regardless of the image existence in the target registry.
#           This can result in pods ending in state ImagePullBack if images fail to be copied to the target registry.
# - exists: Only swaps the image if it exits in the target registry.
#           This can result in pods pulling images from the source registry, e.g. the first pod pulls
#           from source registry, subsequent pods pull from target registry.
imageSwapPolicy: exists

# imageCopyPolicy defines the image copy strategy used by the webhook.
# - delayed: Submits the copy job to a process queue and moves on.
# - immediate: Submits the copy job to a process queue and waits for it to finish (deadline 8s).
# - force: Attempts to immediately copy the image (deadline 8s).
# - none: Do not copy the image.
imageCopyPolicy: delayed

source:
  # Filters provide control over what pods will be processed.
  # By default all pods will be processed. If a condition matches, the pod will NOT be processed.
  # For query language details see https://jmespath.org/
  filters:
    # Do not process if namespace equals "kube-system"
    - jmespath: "obj.metadata.namespace == 'kube-system'"

    # Only process if namespace equals "playground"
    #- jmespath: "obj.metadata.namespace != 'playground'"

    # Only process if namespace ends with "-dev"
    #- jmespath: "ends_with(obj.metadata.namespace,'-dev')"

#  registries:
#    dockerio:
#      username:
#      password:

target:
  type: aws
  aws:
    accountId: 123456789
    region: ap-southeast-2
    role: arn:aws:iam::123456789012:role/roleName
    ecrOptions:
      tags:
        - key: CreatedBy
          value: k8s-image-swapper
        - key: AnotherTag
          value: another-tag
      imageTagMutability: MUTABLE
      imageScanningConfiguration:
        imageScanOnPush: true
      encryptionConfiguration:
        encryptionType: AES256
        kmsKey: string
      accessPolicy: |
        {
          "Version": "2008-10-17",
          "Statement": [
            {
              "Sid": "AllowCrossAccountPull",
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability"
              ],
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalOrgID": [
                    "o-xxxxxxxx"
                  ]
                }
              }
            }
          ]
        }

      lifecyclePolicy: |
        {
          "rules": [
            {
              "rulePriority": 1,
              "description": "Rule 1",
              "selection": {
                "tagStatus": "any",
                "countType": "imageCountMoreThan",
                "countNumber": 1
              },
              "action": {
                "type": "expire"
              }
            }
          ]
        }
#    dockerio:
#    quayio:


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: 38b88246ccc552bffaaf54259d064beeee434539 # v4.0.1
  hooks:
  - id: trailing-whitespace
  - id: check-added-large-files
  - id: check-json
  - id: pretty-format-json
    args: ['--autofix']
    exclude: package-lock.json
  - id: check-merge-conflict
  - id: check-symlinks
  - id: check-yaml
    exclude: 'hack/charts/.*\.yaml'
  - id: detect-private-key
  - id: check-merge-conflict
  - id: check-executables-have-shebangs
  - id: end-of-file-fixer
  - id: mixed-line-ending
#- repo: https://github.com/thlorenz/doctoc
#  rev: v2.0.0
#  hooks:
#  - id: doctoc
#    args: ['--title', '## Table of Contents']
- repo:  https://github.com/golangci/golangci-lint
  rev: v1.55.2
  hooks:
    - id: golangci-lint
      args: ['--timeout', '5m']
- repo:  https://github.com/dnephin/pre-commit-golang
  rev: ac0f6582d2484b3aa90b05d568e70f9f3c1374c7 # v0.0.17
  hooks:
    - id: go-mod-tidy
    - id: go-fmt
    - id: go-imports


================================================
FILE: .releaserc
================================================
---
#verifyConditions: ['@semantic-release/github']
#prepare: []
#publish: ['@semantic-release/github']
#success: ['@semantic-release/github']
#fail: ['@semantic-release/github']
plugins:
- "@semantic-release/commit-analyzer"
- "@semantic-release/release-notes-generator"
- "@semantic-release/changelog"
- "@semantic-release/github"
- "@semantic-release/git"
- - "@semantic-release/exec"
  - generateNotesCmd: |
      echo "${nextRelease.notes}" > /tmp/release-notes.md
    verifyReleaseCmd: |
      echo "${nextRelease.version}" > /tmp/next-release-version.txt

branch: main
branches:
- '+([0-9])?(.{+([0-9]),x}).x'
- 'main'
- 'next'
- 'next-major'
- {name: 'beta', prerelease: true}
- {name: 'alpha', prerelease: true}

analyzeCommits:
  - path: "@semantic-release/commit-analyzer"
    releaseRules:
    - type: "build"
      scope: "deps"
      release: "patch"

generateNotes:
  - path: "@semantic-release/release-notes-generator"
    preset: "conventionalcommits"
    presetConfig:
      types:
        - { type: 'feat', section: ':tada: Features' }
        - { type: 'feature', section: ':tada: Features' }
        - { type: 'fix', section: ':bug: Bug Fixes' }
        - { type: 'perf', section: ':zap: Performance Improvements' }
        - { type: 'revert', section: ':rewind: Reverts' }
        - { type: 'docs', section: ':memo: Documentation', hidden: false }
        - { type: 'style', section: 'Styles', hidden: true }
        - { type: 'chore', section: 'Miscellaneous Chores', hidden: true }
        - { type: 'refactor', section: 'Code Refactoring', hidden: true }
        - { type: 'test', section: ':test_tube: Tests', hidden: true }
        - { type: 'build', scope: 'deps', section: ':arrow_up: Dependencies' }
        - { type: 'build', section: ':construction_worker: Build System' }
        - { type: 'ci', section: 'Continuous Integration', hidden: true }


================================================
FILE: CHANGELOG.md
================================================
## [1.4.0](https://github.com/estahn/k8s-image-swapper/compare/v1.3.3...v1.4.0) (2023-01-01)


### :construction_worker: Build System

* **deps-dev:** Bump @semantic-release/changelog from 6.0.1 to 6.0.2 ([#404](https://github.com/estahn/k8s-image-swapper/issues/404)) ([ee56dbc](https://github.com/estahn/k8s-image-swapper/commit/ee56dbc0e352a191e861d1f77839209e561cfd15)), closes [#276](https://github.com/estahn/k8s-image-swapper/issues/276) [#276](https://github.com/estahn/k8s-image-swapper/issues/276) [#272](https://github.com/estahn/k8s-image-swapper/issues/272) [#275](https://github.com/estahn/k8s-image-swapper/issues/275) [#273](https://github.com/estahn/k8s-image-swapper/issues/273) [#274](https://github.com/estahn/k8s-image-swapper/issues/274) [#271](https://github.com/estahn/k8s-image-swapper/issues/271) [#270](https://github.com/estahn/k8s-image-swapper/issues/270) [#269](https://github.com/estahn/k8s-image-swapper/issues/269) [#268](https://github.com/estahn/k8s-image-swapper/issues/268) [#267](https://github.com/estahn/k8s-image-swapper/issues/267)


### :tada: Features

* add custom tags to created ECR repositories ([#191](https://github.com/estahn/k8s-image-swapper/issues/191)) ([9849df2](https://github.com/estahn/k8s-image-swapper/commit/9849df2e6f706ebd48c629b3bb1bf6ddb91faf32))


### :memo: Documentation

* fix indentation ([b00c57e](https://github.com/estahn/k8s-image-swapper/commit/b00c57ea13a7827458acaf5d2f8c5833d7dfc19d))


### :arrow_up: Dependencies

* **deps:** Bump actions/cache from 3.0.11 to 3.2.1 ([#417](https://github.com/estahn/k8s-image-swapper/issues/417)) ([7e7eb8f](https://github.com/estahn/k8s-image-swapper/commit/7e7eb8f9658fe5e890ec52dc3e30a2f2cf645fe9)), closes [actions/cache#1039](https://github.com/actions/cache/issues/1039) [actions/cache#1023](https://github.com/actions/cache/issues/1023) [actions/cache#959](https://github.com/actions/cache/issues/959) [actions/cache#960](https://github.com/actions/cache/issues/960) [actions/cache#963](https://github.com/actions/cache/issues/963) [actions/cache#961](https://github.com/actions/cache/issues/961) [actions/cache#976](https://github.com/actions/cache/issues/976) [actions/cache#971](https://github.com/actions/cache/issues/971) [actions/cache#979](https://github.com/actions/cache/issues/979) [actions/cache#986](https://github.com/actions/cache/issues/986) [actions/cache#981](https://github.com/actions/cache/issues/981) [actions/cache#997](https://github.com/actions/cache/issues/997) [actions/cache#998](https://github.com/actions/cache/issues/998) [actions/cache#1005](https://github.com/actions/cache/issues/1005) [actions/cache#1007](https://github.com/actions/cache/issues/1007) [actions/cache#1013](https://github.com/actions/cache/issues/1013) [actions/cache#1004](https://github.com/actions/cache/issues/1004) [actions/cache#1014](https://github.com/actions/cache/issues/1014) [actions/cache#1008](https://github.com/actions/cache/issues/1008) [actions/cache#1026](https://github.com/actions/cache/issues/1026) [actions/cache#929](https://github.com/actions/cache/issues/929) [actions/cache#1035](https://github.com/actions/cache/issues/1035) [actions/cache#959](https://github.com/actions/cache/issues/959) [actions/cache#979](https://github.com/actions/cache/issues/979) [actions/cache#1013](https://github.com/actions/cache/issues/1013) [actions/cache#1026](https://github.com/actions/cache/issues/1026) [actions/cache#929](https://github.com/actions/cache/issues/929) [actions/cache#1006](https://github.com/actions/cache/issues/1006) [#1023](https://github.com/estahn/k8s-image-swapper/issues/1023) [#1039](https://github.com/estahn/k8s-image-swapper/issues/1039) [#1035](https://github.com/estahn/k8s-image-swapper/issues/1035) [#929](https://github.com/estahn/k8s-image-swapper/issues/929) [#1026](https://github.com/estahn/k8s-image-swapper/issues/1026) [#1008](https://github.com/estahn/k8s-image-swapper/issues/1008) [#1014](https://github.com/estahn/k8s-image-swapper/issues/1014) [#1004](https://github.com/estahn/k8s-image-swapper/issues/1004)
* **deps:** Bump actions/setup-python from 4.3.0 to 4.3.1 ([#406](https://github.com/estahn/k8s-image-swapper/issues/406)) ([16da762](https://github.com/estahn/k8s-image-swapper/commit/16da762a8223a7802e931a404b236dc18b19cc33)), closes [actions/setup-python#559](https://github.com/actions/setup-python/issues/559) [actions/setup-python#511](https://github.com/actions/setup-python/issues/511) [actions/setup-python#558](https://github.com/actions/setup-python/issues/558) [#559](https://github.com/estahn/k8s-image-swapper/issues/559) [#558](https://github.com/estahn/k8s-image-swapper/issues/558) [#549](https://github.com/estahn/k8s-image-swapper/issues/549) [#546](https://github.com/estahn/k8s-image-swapper/issues/546) [#545](https://github.com/estahn/k8s-image-swapper/issues/545) [#535](https://github.com/estahn/k8s-image-swapper/issues/535) [#510](https://github.com/estahn/k8s-image-swapper/issues/510) [#511](https://github.com/estahn/k8s-image-swapper/issues/511) [#520](https://github.com/estahn/k8s-image-swapper/issues/520)
* **deps:** Bump actions/setup-python from 4.3.1 to 4.4.0 ([#418](https://github.com/estahn/k8s-image-swapper/issues/418)) ([77872f8](https://github.com/estahn/k8s-image-swapper/commit/77872f801aee9b15d1e878a927372dc5bcf49089)), closes [actions/setup-python#566](https://github.com/actions/setup-python/issues/566) [#567](https://github.com/estahn/k8s-image-swapper/issues/567) [#569](https://github.com/estahn/k8s-image-swapper/issues/569) [#566](https://github.com/estahn/k8s-image-swapper/issues/566)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.146 to 1.44.152 ([#403](https://github.com/estahn/k8s-image-swapper/issues/403)) ([9db51fd](https://github.com/estahn/k8s-image-swapper/commit/9db51fd866049c99d1a6d86cfb4f91570a10cad7)), closes [#4652](https://github.com/estahn/k8s-image-swapper/issues/4652) [#4650](https://github.com/estahn/k8s-image-swapper/issues/4650) [#4648](https://github.com/estahn/k8s-image-swapper/issues/4648) [#4647](https://github.com/estahn/k8s-image-swapper/issues/4647) [#4646](https://github.com/estahn/k8s-image-swapper/issues/4646) [#4644](https://github.com/estahn/k8s-image-swapper/issues/4644) [#4639](https://github.com/estahn/k8s-image-swapper/issues/4639)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.152 to 1.44.157 ([#411](https://github.com/estahn/k8s-image-swapper/issues/411)) ([2188432](https://github.com/estahn/k8s-image-swapper/commit/218843218c86f16f85546a037bd976841f220a82)), closes [#4658](https://github.com/estahn/k8s-image-swapper/issues/4658) [#4657](https://github.com/estahn/k8s-image-swapper/issues/4657) [#4656](https://github.com/estahn/k8s-image-swapper/issues/4656) [#4654](https://github.com/estahn/k8s-image-swapper/issues/4654) [#4653](https://github.com/estahn/k8s-image-swapper/issues/4653)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.157 to 1.44.162 ([#415](https://github.com/estahn/k8s-image-swapper/issues/415)) ([f70fcd9](https://github.com/estahn/k8s-image-swapper/commit/f70fcd98419f805c8314070fb73ca9a6122ad7e2)), closes [#4666](https://github.com/estahn/k8s-image-swapper/issues/4666) [#4665](https://github.com/estahn/k8s-image-swapper/issues/4665) [#4663](https://github.com/estahn/k8s-image-swapper/issues/4663) [#4661](https://github.com/estahn/k8s-image-swapper/issues/4661) [#4660](https://github.com/estahn/k8s-image-swapper/issues/4660)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.162 to 1.44.167 ([#419](https://github.com/estahn/k8s-image-swapper/issues/419)) ([f8b91fe](https://github.com/estahn/k8s-image-swapper/commit/f8b91fe6cbca3ff9a69a9c26e156eadbb8092336)), closes [#4671](https://github.com/estahn/k8s-image-swapper/issues/4671) [#4670](https://github.com/estahn/k8s-image-swapper/issues/4670) [#4669](https://github.com/estahn/k8s-image-swapper/issues/4669) [#4668](https://github.com/estahn/k8s-image-swapper/issues/4668) [#4667](https://github.com/estahn/k8s-image-swapper/issues/4667)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.41.3 to 0.41.4 ([#402](https://github.com/estahn/k8s-image-swapper/issues/402)) ([16dde07](https://github.com/estahn/k8s-image-swapper/commit/16dde0720dabfa966199f8cd4d57e2de65aaeee3)), closes [#1208](https://github.com/estahn/k8s-image-swapper/issues/1208)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.41.4 to 0.41.6 ([#409](https://github.com/estahn/k8s-image-swapper/issues/409)) ([9fc87df](https://github.com/estahn/k8s-image-swapper/commit/9fc87df1d6cd4f1979ef64346c88e1601e81855e)), closes [#1214](https://github.com/estahn/k8s-image-swapper/issues/1214) [#1198](https://github.com/estahn/k8s-image-swapper/issues/1198)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.41.6 to 0.41.7 ([#420](https://github.com/estahn/k8s-image-swapper/issues/420)) ([9ab97f2](https://github.com/estahn/k8s-image-swapper/commit/9ab97f2d3e00c1700efeaef20f3de74471d4dc4a)), closes [gruntwork-io/terratest#1217](https://github.com/gruntwork-io/terratest/issues/1217) [#1217](https://github.com/estahn/k8s-image-swapper/issues/1217)
* **deps:** Bump goreleaser/goreleaser-action from 3.1.0 to 4.1.0 ([#414](https://github.com/estahn/k8s-image-swapper/issues/414)) ([e963ba1](https://github.com/estahn/k8s-image-swapper/commit/e963ba13406d43412962a025aece512846f85530)), closes [goreleaser/goreleaser-action#382](https://github.com/goreleaser/goreleaser-action/issues/382) [goreleaser/goreleaser-action#366](https://github.com/goreleaser/goreleaser-action/issues/366) [goreleaser/goreleaser-action#379](https://github.com/goreleaser/goreleaser-action/issues/379) [goreleaser/goreleaser-action#383](https://github.com/goreleaser/goreleaser-action/issues/383) [goreleaser/goreleaser-action#366](https://github.com/goreleaser/goreleaser-action/issues/366) [goreleaser/goreleaser-action#379](https://github.com/goreleaser/goreleaser-action/issues/379) [goreleaser/goreleaser-action#370](https://github.com/goreleaser/goreleaser-action/issues/370) [#374](https://github.com/estahn/k8s-image-swapper/issues/374) [#372](https://github.com/estahn/k8s-image-swapper/issues/372) [#373](https://github.com/estahn/k8s-image-swapper/issues/373) [#383](https://github.com/estahn/k8s-image-swapper/issues/383) [#366](https://github.com/estahn/k8s-image-swapper/issues/366) [#382](https://github.com/estahn/k8s-image-swapper/issues/382) [#370](https://github.com/estahn/k8s-image-swapper/issues/370)
* **deps:** Bump k8s.io/api from 0.25.4 to 0.26.0 ([#407](https://github.com/estahn/k8s-image-swapper/issues/407)) ([d13bf5e](https://github.com/estahn/k8s-image-swapper/commit/d13bf5e751ed7638fb418add00ed40f1ceb04f07)), closes [#111023](https://github.com/estahn/k8s-image-swapper/issues/111023) [#113375](https://github.com/estahn/k8s-image-swapper/issues/113375) [#113186](https://github.com/estahn/k8s-image-swapper/issues/113186)
* **deps:** Bump k8s.io/client-go from 0.25.4 to 0.26.0 ([#410](https://github.com/estahn/k8s-image-swapper/issues/410)) ([bcc56b5](https://github.com/estahn/k8s-image-swapper/commit/bcc56b57ac91c1e8312f4e558283c68684a38678)), closes [#113797](https://github.com/estahn/k8s-image-swapper/issues/113797) [#111023](https://github.com/estahn/k8s-image-swapper/issues/111023) [#113826](https://github.com/estahn/k8s-image-swapper/issues/113826) [#113375](https://github.com/estahn/k8s-image-swapper/issues/113375)

## [1.3.3](https://github.com/estahn/k8s-image-swapper/compare/v1.3.2...v1.3.3) (2022-12-01)


### :arrow_up: Dependencies

* **deps:** Bump alpine from 3.16.2 to 3.16.3 ([#388](https://github.com/estahn/k8s-image-swapper/issues/388)) ([ffae497](https://github.com/estahn/k8s-image-swapper/commit/ffae497511dd6fb3adcac748f06684e50474446c))
* **deps:** Bump alpine from 3.16.3 to 3.17.0 ([#395](https://github.com/estahn/k8s-image-swapper/issues/395)) ([d32255d](https://github.com/estahn/k8s-image-swapper/commit/d32255d0b7f0685e837eb2906868b0b7c73bd022))
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.126 to 1.44.136 ([#391](https://github.com/estahn/k8s-image-swapper/issues/391)) ([61a6ae2](https://github.com/estahn/k8s-image-swapper/commit/61a6ae23f015d7ee0c1c4300a3a7e9a76e2acd09)), closes [#4620](https://github.com/estahn/k8s-image-swapper/issues/4620) [#4619](https://github.com/estahn/k8s-image-swapper/issues/4619) [#4617](https://github.com/estahn/k8s-image-swapper/issues/4617) [#4616](https://github.com/estahn/k8s-image-swapper/issues/4616) [#4615](https://github.com/estahn/k8s-image-swapper/issues/4615) [#4614](https://github.com/estahn/k8s-image-swapper/issues/4614) [#4613](https://github.com/estahn/k8s-image-swapper/issues/4613) [#4611](https://github.com/estahn/k8s-image-swapper/issues/4611) [#4608](https://github.com/estahn/k8s-image-swapper/issues/4608) [#4609](https://github.com/estahn/k8s-image-swapper/issues/4609)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.136 to 1.44.146 ([#397](https://github.com/estahn/k8s-image-swapper/issues/397)) ([d4a6136](https://github.com/estahn/k8s-image-swapper/commit/d4a61369b50b03dd56c1025557b3b65169beea7e)), closes [#4638](https://github.com/estahn/k8s-image-swapper/issues/4638) [#4636](https://github.com/estahn/k8s-image-swapper/issues/4636) [#4633](https://github.com/estahn/k8s-image-swapper/issues/4633) [#4632](https://github.com/estahn/k8s-image-swapper/issues/4632) [#4630](https://github.com/estahn/k8s-image-swapper/issues/4630) [#4628](https://github.com/estahn/k8s-image-swapper/issues/4628) [#4627](https://github.com/estahn/k8s-image-swapper/issues/4627) [#4626](https://github.com/estahn/k8s-image-swapper/issues/4626) [#4625](https://github.com/estahn/k8s-image-swapper/issues/4625) [#4624](https://github.com/estahn/k8s-image-swapper/issues/4624)
* **deps:** Bump github.com/containers/image/v5 from 5.23.0 to 5.23.1 ([#393](https://github.com/estahn/k8s-image-swapper/issues/393)) ([84f4d18](https://github.com/estahn/k8s-image-swapper/commit/84f4d1800f0e0937560963b5bac6ed52ec824182))
* **deps:** Bump github.com/go-co-op/gocron from 1.17.1 to 1.18.0 ([#390](https://github.com/estahn/k8s-image-swapper/issues/390)) ([1750ee9](https://github.com/estahn/k8s-image-swapper/commit/1750ee9ebe3dd7e5455d8a8490b90bcccd019eb8)), closes [go-co-op/gocron#388](https://github.com/go-co-op/gocron/issues/388) [go-co-op/gocron#389](https://github.com/go-co-op/gocron/issues/389) [go-co-op/gocron#392](https://github.com/go-co-op/gocron/issues/392) [go-co-op/gocron#394](https://github.com/go-co-op/gocron/issues/394) [go-co-op/gocron#393](https://github.com/go-co-op/gocron/issues/393) [go-co-op/gocron#392](https://github.com/go-co-op/gocron/issues/392) [go-co-op/gocron#394](https://github.com/go-co-op/gocron/issues/394) [#393](https://github.com/estahn/k8s-image-swapper/issues/393) [#394](https://github.com/estahn/k8s-image-swapper/issues/394) [#392](https://github.com/estahn/k8s-image-swapper/issues/392) [#389](https://github.com/estahn/k8s-image-swapper/issues/389)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.40.24 to 0.41.3 ([#398](https://github.com/estahn/k8s-image-swapper/issues/398)) ([ab35b1a](https://github.com/estahn/k8s-image-swapper/commit/ab35b1a31d45e2c3f395a69f8fb1f11aad6485c0)), closes [gruntwork-io/terratest#1203](https://github.com/gruntwork-io/terratest/issues/1203) [gruntwork-io/terratest#1202](https://github.com/gruntwork-io/terratest/issues/1202) [gruntwork-io/terratest#1201](https://github.com/gruntwork-io/terratest/issues/1201) [gruntwork-io/terratest#1199](https://github.com/gruntwork-io/terratest/issues/1199) [gruntwork-io/terratest#1196](https://github.com/gruntwork-io/terratest/issues/1196) [#1202](https://github.com/estahn/k8s-image-swapper/issues/1202) [#1203](https://github.com/estahn/k8s-image-swapper/issues/1203) [#1201](https://github.com/estahn/k8s-image-swapper/issues/1201) [#1199](https://github.com/estahn/k8s-image-swapper/issues/1199) [#1196](https://github.com/estahn/k8s-image-swapper/issues/1196)
* **deps:** Bump github.com/prometheus/client_golang from 1.13.0 to 1.13.1 ([#387](https://github.com/estahn/k8s-image-swapper/issues/387)) ([b155a16](https://github.com/estahn/k8s-image-swapper/commit/b155a160cf3f90e3bbbaa8c0a639496d5633072f)), closes [#1146](https://github.com/estahn/k8s-image-swapper/issues/1146) [#1148](https://github.com/estahn/k8s-image-swapper/issues/1148) [#1118](https://github.com/estahn/k8s-image-swapper/issues/1118) [#1146](https://github.com/estahn/k8s-image-swapper/issues/1146) [#1148](https://github.com/estahn/k8s-image-swapper/issues/1148) [#1118](https://github.com/estahn/k8s-image-swapper/issues/1118) [#1157](https://github.com/estahn/k8s-image-swapper/issues/1157) [#1146](https://github.com/estahn/k8s-image-swapper/issues/1146) [#1148](https://github.com/estahn/k8s-image-swapper/issues/1148) [#1118](https://github.com/estahn/k8s-image-swapper/issues/1118)
* **deps:** Bump github.com/prometheus/client_golang from 1.13.1 to 1.14.0 ([#392](https://github.com/estahn/k8s-image-swapper/issues/392)) ([af00594](https://github.com/estahn/k8s-image-swapper/commit/af00594c9494182d1b6803efa44bc8d13ca7bad6)), closes [#1150](https://github.com/estahn/k8s-image-swapper/issues/1150) [#1103](https://github.com/estahn/k8s-image-swapper/issues/1103) [prometheus/client_golang#1118](https://github.com/prometheus/client_golang/issues/1118) [prometheus/client_golang#1103](https://github.com/prometheus/client_golang/issues/1103) [prometheus/client_golang#1125](https://github.com/prometheus/client_golang/issues/1125) [prometheus/client_golang#1130](https://github.com/prometheus/client_golang/issues/1130) [prometheus/client_golang#1148](https://github.com/prometheus/client_golang/issues/1148) [prometheus/client_golang#1146](https://github.com/prometheus/client_golang/issues/1146) [prometheus/client_golang#1152](https://github.com/prometheus/client_golang/issues/1152) [#1150](https://github.com/estahn/k8s-image-swapper/issues/1150) [#1103](https://github.com/estahn/k8s-image-swapper/issues/1103) [#1162](https://github.com/estahn/k8s-image-swapper/issues/1162) [#1161](https://github.com/estahn/k8s-image-swapper/issues/1161) [#1160](https://github.com/estahn/k8s-image-swapper/issues/1160) [#1136](https://github.com/estahn/k8s-image-swapper/issues/1136) [#1133](https://github.com/estahn/k8s-image-swapper/issues/1133) [#1150](https://github.com/estahn/k8s-image-swapper/issues/1150) [#1152](https://github.com/estahn/k8s-image-swapper/issues/1152)
* **deps:** Bump github.com/spf13/viper from 1.13.0 to 1.14.0 ([#385](https://github.com/estahn/k8s-image-swapper/issues/385)) ([6f79498](https://github.com/estahn/k8s-image-swapper/commit/6f79498631d0382645ab9e1a031f80f130ea55a6)), closes [spf13/viper#1457](https://github.com/spf13/viper/issues/1457) [spf13/viper#1458](https://github.com/spf13/viper/issues/1458) [spf13/viper#1460](https://github.com/spf13/viper/issues/1460) [spf13/viper#1428](https://github.com/spf13/viper/issues/1428) [spf13/viper#1406](https://github.com/spf13/viper/issues/1406) [spf13/viper#1437](https://github.com/spf13/viper/issues/1437) [spf13/viper#1453](https://github.com/spf13/viper/issues/1453) [spf13/viper#1449](https://github.com/spf13/viper/issues/1449) [spf13/viper#1461](https://github.com/spf13/viper/issues/1461)
* **deps:** Bump golangci/golangci-lint-action from 3.3.0 to 3.3.1 ([#389](https://github.com/estahn/k8s-image-swapper/issues/389)) ([0b50f7b](https://github.com/estahn/k8s-image-swapper/commit/0b50f7b725bd20f5a2fbe3d7bf74365250de8efd)), closes [golangci/golangci-lint-action#590](https://github.com/golangci/golangci-lint-action/issues/590) [golangci/golangci-lint-action#591](https://github.com/golangci/golangci-lint-action/issues/591) [golangci/golangci-lint-action#592](https://github.com/golangci/golangci-lint-action/issues/592) [golangci/golangci-lint-action#593](https://github.com/golangci/golangci-lint-action/issues/593) [golangci/golangci-lint-action#594](https://github.com/golangci/golangci-lint-action/issues/594) [golangci/golangci-lint-action#595](https://github.com/golangci/golangci-lint-action/issues/595) [golangci/golangci-lint-action#596](https://github.com/golangci/golangci-lint-action/issues/596) [golangci/golangci-lint-action#597](https://github.com/golangci/golangci-lint-action/issues/597) [golangci/golangci-lint-action#598](https://github.com/golangci/golangci-lint-action/issues/598) [golangci/golangci-lint-action#599](https://github.com/golangci/golangci-lint-action/issues/599) [#599](https://github.com/estahn/k8s-image-swapper/issues/599) [#598](https://github.com/estahn/k8s-image-swapper/issues/598) [#596](https://github.com/estahn/k8s-image-swapper/issues/596) [#595](https://github.com/estahn/k8s-image-swapper/issues/595) [#593](https://github.com/estahn/k8s-image-swapper/issues/593) [#591](https://github.com/estahn/k8s-image-swapper/issues/591) [#590](https://github.com/estahn/k8s-image-swapper/issues/590)
* **deps:** Bump hmarr/auto-approve-action from 2 to 3 ([#396](https://github.com/estahn/k8s-image-swapper/issues/396)) ([0b982a2](https://github.com/estahn/k8s-image-swapper/commit/0b982a220226bad863a4aa4819a080a343c8b238)), closes [hmarr/auto-approve-action#205](https://github.com/hmarr/auto-approve-action/issues/205) [hmarr/auto-approve-action#202](https://github.com/hmarr/auto-approve-action/issues/202) [hmarr/auto-approve-action#202](https://github.com/hmarr/auto-approve-action/issues/202) [hmarr/auto-approve-action#200](https://github.com/hmarr/auto-approve-action/issues/200) [hmarr/auto-approve-action#200](https://github.com/hmarr/auto-approve-action/issues/200) [hmarr/auto-approve-action#186](https://github.com/hmarr/auto-approve-action/issues/186) [hmarr/auto-approve-action#191](https://github.com/hmarr/auto-approve-action/issues/191) [#210](https://github.com/estahn/k8s-image-swapper/issues/210) [#205](https://github.com/estahn/k8s-image-swapper/issues/205)
* **deps:** Bump k8s.io/api from 0.25.3 to 0.25.4 ([#401](https://github.com/estahn/k8s-image-swapper/issues/401)) ([0f80b5d](https://github.com/estahn/k8s-image-swapper/commit/0f80b5d9802cfe9edf69b69e341b3cff5e22f918))
* **deps:** Bump k8s.io/apimachinery from 0.25.3 to 0.25.4 ([#399](https://github.com/estahn/k8s-image-swapper/issues/399)) ([1f0944f](https://github.com/estahn/k8s-image-swapper/commit/1f0944ff59bb3803d7e8e379c32838c937ccbed8)), closes [#112218](https://github.com/estahn/k8s-image-swapper/issues/112218) [haoruan/automated-cherry-pick-of-#111936](https://github.com/haoruan/automated-cherry-pick-of-/issues/111936)
* **deps:** Bump k8s.io/client-go from 0.25.3 to 0.25.4 ([#400](https://github.com/estahn/k8s-image-swapper/issues/400)) ([ad036e0](https://github.com/estahn/k8s-image-swapper/commit/ad036e08999cf58a5c9bd3300d63222c4a1b48e1))

## [1.3.2](https://github.com/estahn/k8s-image-swapper/compare/v1.3.1...v1.3.2) (2022-11-01)


### :arrow_up: Dependencies

* **deps:** Bump actions/cache from 3.0.10 to 3.0.11 ([#365](https://github.com/estahn/k8s-image-swapper/issues/365)) ([4e88994](https://github.com/estahn/k8s-image-swapper/commit/4e88994fed8d51b8e21d8c0e5bdeef8edfcf6edb)), closes [actions/cache#946](https://github.com/actions/cache/issues/946) [actions/cache#950](https://github.com/actions/cache/issues/950) [actions/cache#956](https://github.com/actions/cache/issues/956) [actions/cache#950](https://github.com/actions/cache/issues/950) [#956](https://github.com/estahn/k8s-image-swapper/issues/956) [#950](https://github.com/estahn/k8s-image-swapper/issues/950) [#946](https://github.com/estahn/k8s-image-swapper/issues/946)
* **deps:** bump actions/cache from 3.0.8 to 3.0.10 ([#358](https://github.com/estahn/k8s-image-swapper/issues/358)) ([921d9e2](https://github.com/estahn/k8s-image-swapper/commit/921d9e2df56e860ca2b09c87ed874bce4525260e)), closes [#809](https://github.com/estahn/k8s-image-swapper/issues/809) [#833](https://github.com/estahn/k8s-image-swapper/issues/833) [#810](https://github.com/estahn/k8s-image-swapper/issues/810) [#931](https://github.com/estahn/k8s-image-swapper/issues/931) [#942](https://github.com/estahn/k8s-image-swapper/issues/942) [#930](https://github.com/estahn/k8s-image-swapper/issues/930) [#920](https://github.com/estahn/k8s-image-swapper/issues/920) [#936](https://github.com/estahn/k8s-image-swapper/issues/936) [#925](https://github.com/estahn/k8s-image-swapper/issues/925)
* **deps:** Bump actions/setup-python from 4.2.0 to 4.3.0 ([#362](https://github.com/estahn/k8s-image-swapper/issues/362)) ([05a7ab3](https://github.com/estahn/k8s-image-swapper/commit/05a7ab3cd2df647927fdd85a159dc21dbe181cc9)), closes [#517](https://github.com/estahn/k8s-image-swapper/issues/517) [#499](https://github.com/estahn/k8s-image-swapper/issues/499) [#443](https://github.com/estahn/k8s-image-swapper/issues/443) [#477](https://github.com/estahn/k8s-image-swapper/issues/477) [#479](https://github.com/estahn/k8s-image-swapper/issues/479) [#491](https://github.com/estahn/k8s-image-swapper/issues/491) [#492](https://github.com/estahn/k8s-image-swapper/issues/492) [#517](https://github.com/estahn/k8s-image-swapper/issues/517) [#503](https://github.com/estahn/k8s-image-swapper/issues/503) [#499](https://github.com/estahn/k8s-image-swapper/issues/499) [#495](https://github.com/estahn/k8s-image-swapper/issues/495) [#443](https://github.com/estahn/k8s-image-swapper/issues/443) [#492](https://github.com/estahn/k8s-image-swapper/issues/492) [#491](https://github.com/estahn/k8s-image-swapper/issues/491)
* **deps:** Bump docker/login-action from 2.0.0 to 2.1.0 ([#364](https://github.com/estahn/k8s-image-swapper/issues/364)) ([ca6a535](https://github.com/estahn/k8s-image-swapper/commit/ca6a535e78ddc3bba389b1454c4ae6af7c41104b)), closes [#275](https://github.com/estahn/k8s-image-swapper/issues/275) [#252](https://github.com/estahn/k8s-image-swapper/issues/252) [#292](https://github.com/estahn/k8s-image-swapper/issues/292) [#298](https://github.com/estahn/k8s-image-swapper/issues/298) [#299](https://github.com/estahn/k8s-image-swapper/issues/299) [#299](https://github.com/estahn/k8s-image-swapper/issues/299) [#298](https://github.com/estahn/k8s-image-swapper/issues/298) [#292](https://github.com/estahn/k8s-image-swapper/issues/292) [#275](https://github.com/estahn/k8s-image-swapper/issues/275)
* **deps:** Bump github.com/alitto/pond from 1.8.1 to 1.8.2 ([#371](https://github.com/estahn/k8s-image-swapper/issues/371)) ([417edd5](https://github.com/estahn/k8s-image-swapper/commit/417edd5f35b4194c78f0ff28ba26cb4930202f1f)), closes [alitto/pond#37](https://github.com/alitto/pond/issues/37) [#37](https://github.com/estahn/k8s-image-swapper/issues/37)
* **deps:** bump github.com/aws/aws-sdk-go from 1.44.100 to 1.44.109 ([#359](https://github.com/estahn/k8s-image-swapper/issues/359)) ([b9acd7d](https://github.com/estahn/k8s-image-swapper/commit/b9acd7d6abaa0d893d084d39655fa6e9c7c6ee03)), closes [#4574](https://github.com/estahn/k8s-image-swapper/issues/4574) [#4573](https://github.com/estahn/k8s-image-swapper/issues/4573) [#4571](https://github.com/estahn/k8s-image-swapper/issues/4571) [#4568](https://github.com/estahn/k8s-image-swapper/issues/4568) [#4567](https://github.com/estahn/k8s-image-swapper/issues/4567) [#4566](https://github.com/estahn/k8s-image-swapper/issues/4566) [#4565](https://github.com/estahn/k8s-image-swapper/issues/4565) [#4562](https://github.com/estahn/k8s-image-swapper/issues/4562) [#4561](https://github.com/estahn/k8s-image-swapper/issues/4561)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.109 to 1.44.114 ([#363](https://github.com/estahn/k8s-image-swapper/issues/363)) ([832a21d](https://github.com/estahn/k8s-image-swapper/commit/832a21d5a4911b73adec3c3922691e64dabeb367)), closes [#4580](https://github.com/estahn/k8s-image-swapper/issues/4580) [#4579](https://github.com/estahn/k8s-image-swapper/issues/4579) [#4578](https://github.com/estahn/k8s-image-swapper/issues/4578) [#4576](https://github.com/estahn/k8s-image-swapper/issues/4576) [#4575](https://github.com/estahn/k8s-image-swapper/issues/4575)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.114 to 1.44.121 ([#377](https://github.com/estahn/k8s-image-swapper/issues/377)) ([26f4103](https://github.com/estahn/k8s-image-swapper/commit/26f410377e56ddd55a3b8f204422492ecb96d45c)), closes [#4596](https://github.com/estahn/k8s-image-swapper/issues/4596) [#4595](https://github.com/estahn/k8s-image-swapper/issues/4595) [#4593](https://github.com/estahn/k8s-image-swapper/issues/4593) [#4519](https://github.com/estahn/k8s-image-swapper/issues/4519) [#4590](https://github.com/estahn/k8s-image-swapper/issues/4590) [#4589](https://github.com/estahn/k8s-image-swapper/issues/4589) [#4587](https://github.com/estahn/k8s-image-swapper/issues/4587) [#4586](https://github.com/estahn/k8s-image-swapper/issues/4586)
* **deps:** Bump github.com/aws/aws-sdk-go from 1.44.121 to 1.44.126 ([#383](https://github.com/estahn/k8s-image-swapper/issues/383)) ([b7e43d9](https://github.com/estahn/k8s-image-swapper/commit/b7e43d9312709eb9e81e1c941d0915776ca73c10)), closes [#4603](https://github.com/estahn/k8s-image-swapper/issues/4603) [#4602](https://github.com/estahn/k8s-image-swapper/issues/4602) [#4601](https://github.com/estahn/k8s-image-swapper/issues/4601) [#4600](https://github.com/estahn/k8s-image-swapper/issues/4600) [#4598](https://github.com/estahn/k8s-image-swapper/issues/4598)
* **deps:** bump github.com/containers/image/v5 from 5.22.0 to 5.23.0 ([#360](https://github.com/estahn/k8s-image-swapper/issues/360)) ([250d9e4](https://github.com/estahn/k8s-image-swapper/commit/250d9e4c6c4af0ad80d185e3e28bc72f3bc2a9e2)), closes [#1665](https://github.com/estahn/k8s-image-swapper/issues/1665) [#1666](https://github.com/estahn/k8s-image-swapper/issues/1666) [#1664](https://github.com/estahn/k8s-image-swapper/issues/1664) [#1662](https://github.com/estahn/k8s-image-swapper/issues/1662)
* **deps:** Bump github.com/dgraph-io/ristretto from 0.1.0 to 0.1.1 ([#368](https://github.com/estahn/k8s-image-swapper/issues/368)) ([0e9c9df](https://github.com/estahn/k8s-image-swapper/commit/0e9c9df74847dea68668137677391541df4a9977)), closes [#285](https://github.com/estahn/k8s-image-swapper/issues/285) [dgraph-io/ristretto#311](https://github.com/dgraph-io/ristretto/issues/311) [#304](https://github.com/estahn/k8s-image-swapper/issues/304) [dgraph-io/ristretto#304](https://github.com/dgraph-io/ristretto/issues/304) [#287](https://github.com/estahn/k8s-image-swapper/issues/287) [dgraph-io/ristretto#307](https://github.com/dgraph-io/ristretto/issues/307) [#285](https://github.com/estahn/k8s-image-swapper/issues/285) [dgraph-io/ristretto#311](https://github.com/dgraph-io/ristretto/issues/311) [#304](https://github.com/estahn/k8s-image-swapper/issues/304) [dgraph-io/ristretto#304](https://github.com/dgraph-io/ristretto/issues/304) [#287](https://github.com/estahn/k8s-image-swapper/issues/287) [dgraph-io/ristretto#307](https://github.com/dgraph-io/ristretto/issues/307) [#312](https://github.com/estahn/k8s-image-swapper/issues/312) [#285](https://github.com/estahn/k8s-image-swapper/issues/285) [#310](https://github.com/estahn/k8s-image-swapper/issues/310) [#306](https://github.com/estahn/k8s-image-swapper/issues/306) [#309](https://github.com/estahn/k8s-image-swapper/issues/309) [#308](https://github.com/estahn/k8s-image-swapper/issues/308) [#287](https://github.com/estahn/k8s-image-swapper/issues/287) [#307](https://github.com/estahn/k8s-image-swapper/issues/307) [#304](https://github.com/estahn/k8s-image-swapper/issues/304)
* **deps:** Bump github.com/go-co-op/gocron from 1.17.0 to 1.17.1 ([#380](https://github.com/estahn/k8s-image-swapper/issues/380)) ([8c4cef8](https://github.com/estahn/k8s-image-swapper/commit/8c4cef891249bc5e9b699e4df492eb343ee005b6)), closes [go-co-op/gocron#382](https://github.com/go-co-op/gocron/issues/382) [go-co-op/gocron#386](https://github.com/go-co-op/gocron/issues/386) [go-co-op/gocron#386](https://github.com/go-co-op/gocron/issues/386) [#386](https://github.com/estahn/k8s-image-swapper/issues/386) [#382](https://github.com/estahn/k8s-image-swapper/issues/382)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.40.22 to 0.40.23 ([#367](https://github.com/estahn/k8s-image-swapper/issues/367)) ([a07149b](https://github.com/estahn/k8s-image-swapper/commit/a07149b44a5814d06121de06cf117c8cb1baedc2)), closes [gruntwork-io/terratest#1186](https://github.com/gruntwork-io/terratest/issues/1186) [gruntwork-io/terratest#1189](https://github.com/gruntwork-io/terratest/issues/1189) [#1189](https://github.com/estahn/k8s-image-swapper/issues/1189) [#1186](https://github.com/estahn/k8s-image-swapper/issues/1186)
* **deps:** Bump github.com/gruntwork-io/terratest from 0.40.23 to 0.40.24 ([#378](https://github.com/estahn/k8s-image-swapper/issues/378)) ([e57939d](https://github.com/estahn/k8s-image-swapper/commit/e57939daf1efa9d3c9e879c5468a7e6451393c69)), closes [gruntwork-io/terratest#1191](https://github.com/gruntwork-io/terratest/issues/1191) [#1191](https://github.com/estahn/k8s-image-swapper/issues/1191)
* **deps:** Bump github.com/slok/kubewebhook/v2 from 2.3.0 to 2.5.0 ([#372](https://github.com/estahn/k8s-image-swapper/issues/372)) ([249a996](https://github.com/estahn/k8s-image-swapper/commit/249a9961d438d4057e74cca8f5358640a836d521)), closes [#218](https://github.com/estahn/k8s-image-swapper/issues/218) [#217](https://github.com/estahn/k8s-image-swapper/issues/217) [#187](https://github.com/estahn/k8s-image-swapper/issues/187)
* **deps:** Bump github.com/spf13/cobra from 1.5.0 to 1.6.0 ([#373](https://github.com/estahn/k8s-image-swapper/issues/373)) ([39cfd45](https://github.com/estahn/k8s-image-swapper/commit/39cfd45c188b19fc48ccb06b68542089da2440ca)), closes [#1003](https://github.com/estahn/k8s-image-swapper/issues/1003) [#1802](https://github.com/estahn/k8s-image-swapper/issues/1802) [#1760](https://github.com/estahn/k8s-image-swapper/issues/1760) [#1707](https://github.com/estahn/k8s-image-swapper/issues/1707) [#1813](https://github.com/estahn/k8s-image-swapper/issues/1813) [#1788](https://github.com/estahn/k8s-image-swapper/issues/1788) [#1621](https://github.com/estahn/k8s-image-swapper/issues/1621) [#1467](https://github.com/estahn/k8s-image-swapper/issues/1467) [#1643](https://github.com/estahn/k8s-image-swapper/issues/1643) [#1643](https://github.com/estahn/k8s-image-swapper/issues/1643) [#1762](https://github.com/estahn/k8s-image-swapper/issues/1762) [#1771](https://github.com/estahn/k8s-image-swapper/issues/1771) [#1776](https://github.com/estahn/k8s-image-swapper/issues/1776) [#1766](https://github.com/estahn/k8s-image-swapper/issues/1766) [#1782](https://github.com/estahn/k8s-image-swapper/issues/1782) [#1803](https://github.com/estahn/k8s-image-swapper/issues/1803) [#1783](https://github.com/estahn/k8s-image-swapper/issues/1783) [#1387](https://github.com/estahn/k8s-image-swapper/issues/1387) [#1792](https://github.com/estahn/k8s-image-swapper/issues/1792) [#1744](https://github.com/estahn/k8s-image-swapper/issues/1744) [#1748](https://github.com/estahn/k8s-image-swapper/issues/1748) [#1726](https://github.com/estahn/k8s-image-swapper/issues/1726) [#1656](https://github.com/estahn/k8s-image-swapper/issues/1656) [#1779](https://github.com/estahn/k8s-image-swapper/issues/1779) [#1741](https://github.com/estahn/k8s-image-swapper/issues/1741) [#1742](https://github.com/estahn/k8s-image-swapper/issues/1742) [#1745](https://github.com/estahn/k8s-image-swapper/issues/1745) [#1759](https://github.com/estahn/k8s-image-swapper/issues/1759) [#1772](https://github.com/estahn/k8s-image-swapper/issues/1772) [#1819](https://github.com/estahn/k8s-image-swapper/issues/1819) [#1800](https://github.com/estahn/k8s-image-swapper/issues/1800) [#1809](https://github.com/estahn/k8s-image-swapper/issues/1809) [#1804](https://github.com/estahn/k8s-image-swapper/issues/1804) [#1467](https://github.com/estahn/k8s-image-swapper/issues/1467) [#1003](https://github.com/estahn/k8s-image-swapper/issues/1003) [#1813](https://github.com/estahn/k8s-image-swapper/issues/1813) [#1621](https://github.com/estahn/k8s-image-swapper/issues/1621) [#1792](https://github.com/estahn/k8s-image-swapper/issues/1792) [#1788](https://github.com/estahn/k8s-image-swapper/issues/1788) [#1815](https://github.com/estahn/k8s-image-swapper/issues/1815) [#1819](https://github.com/estahn/k8s-image-swapper/issues/1819) [#1707](https://github.com/estahn/k8s-image-swapper/issues/1707) [#1760](https://github.com/estahn/k8s-image-swapper/issues/1760)
* **deps:** Bump github.com/spf13/cobra from 1.6.0 to 1.6.1 ([#384](https://github.com/estahn/k8s-image-swapper/issues/384)) ([ffe3ef6](https://github.com/estahn/k8s-image-swapper/commit/ffe3ef6a3ff0f789234b4627ae472047477518dc)), closes [#1839](https://github.com/estahn/k8s-image-swapper/issues/1839) [#1841](https://github.com/estahn/k8s-image-swapper/issues/1841)
* **deps:** Bump github.com/stretchr/testify from 1.8.0 to 1.8.1 ([#379](https://github.com/estahn/k8s-image-swapper/issues/379)) ([a0e1429](https://github.com/estahn/k8s-image-swapper/commit/a0e1429c3c74ff5c7a69d1949de7f220c04feac0)), closes [#1283](https://github.com/estahn/k8s-image-swapper/issues/1283)
* **deps:** Bump golangci/golangci-lint-action from 3.2.0 to 3.3.0 ([#375](https://github.com/estahn/k8s-image-swapper/issues/375)) ([abcf765](https://github.com/estahn/k8s-image-swapper/commit/abcf765c74573a98f3c6956c8ce6b087f8a6b8d0)), closes [#586](https://github.com/estahn/k8s-image-swapper/issues/586) [#584](https://github.com/estahn/k8s-image-swapper/issues/584) [#582](https://github.com/estahn/k8s-image-swapper/issues/582) [#580](https://github.com/estahn/k8s-image-swapper/issues/580) [#578](https://github.com/estahn/k8s-image-swapper/issues/578) [#576](https://github.com/estahn/k8s-image-swapper/issues/576) [#577](https://github.com/estahn/k8s-image-swapper/issues/577) [#575](https://github.com/estahn/k8s-image-swapper/issues/575)
* **deps:** Bump k8s.io/api from 0.25.1 to 0.25.3 ([#366](https://github.com/estahn/k8s-image-swapper/issues/366)) ([c233527](https://github.com/estahn/k8s-image-swapper/commit/c23352795c55ed3d9897015c0d127163648302b8)), closes [#112808](https://github.com/estahn/k8s-image-swapper/issues/112808) [cheftako/automated-cherry-pick-of-#112689](https://github.com/cheftako/automated-cherry-pick-of-/issues/112689)

## [1.3.1](https://github.com/estahn/k8s-image-swapper/compare/v1.3.0...v1.3.1) (2022-10-01)


### :bug: Bug Fixes

* set verbose level & use structured logging ([#346](https://github.com/estahn/k8s-image-swapper/issues/346)) ([9b21320](https://github.com/estahn/k8s-image-swapper/commit/9b21320a52d3f74ae4a6e8233cc3e310d2f5136b))


### :arrow_up: Dependencies

* **deps:** bump github.com/aws/aws-sdk-go from 1.44.92 to 1.44.95 ([#349](https://github.com/estahn/k8s-image-swapper/issues/349)) ([609e915](https://github.com/estahn/k8s-image-swapper/commit/609e91566628b2c89ee0f3a6f582993cb7df8154)), closes [#4553](https://github.com/estahn/k8s-image-swapper/issues/4553) [#4551](https://github.com/estahn/k8s-image-swapper/issues/4551) [#4550](https://github.com/estahn/k8s-image-swapper/issues/4550)
* **deps:** bump github.com/aws/aws-sdk-go from 1.44.95 to 1.44.100 ([#351](https://github.com/estahn/k8s-image-swapper/issues/351)) ([c4aba7d](https://github.com/estahn/k8s-image-swapper/commit/c4aba7dd91b6128c4b6b70b52a3587d81a1b439f)), closes [#4560](https://github.com/estahn/k8s-image-swapper/issues/4560) [#4559](https://github.com/estahn/k8s-image-swapper/issues/4559) [#4558](https://github.com/estahn/k8s-image-swapper/issues/4558) [#4556](https://github.com/estahn/k8s-image-swapper/issues/4556) [#4555](https://github.com/estahn/k8s-image-swapper/issues/4555)
* **deps:** bump github.com/gruntwork-io/terratest from 0.40.21 to 0.40.22 ([#348](https://github.com/estahn/k8s-image-swapper/issues/348)) ([b3fa94d](https://github.com/estahn/k8s-image-swapper/commit/b3fa94df956a05796d8fd396462d0bb6987c8f11)), closes [#1169](https://github.com/estahn/k8s-image-swapper/issues/1169)
* **deps:** bump k8s.io/api from 0.25.0 to 0.25.1 ([#350](https://github.com/estahn/k8s-image-swapper/issues/350)) ([e1b358a](https://github.com/estahn/k8s-image-swapper/commit/e1b358aa28abacbf4e2c125032871d9db6fab401)), closes [#112161](https://github.com/estahn/k8s-image-swapper/issues/112161) [pohly/automated-cherry-pick-of-#112129](https://github.com/pohly/automated-cherry-pick-of-/issues/112129)
* **deps:** bump k8s.io/apimachinery from 0.25.0 to 0.25.1 ([#352](https://github.com/estahn/k8s-image-swapper/issues/352)) ([046ad1e](https://github.com/estahn/k8s-image-swapper/commit/046ad1e07924a4b4e797e5984262ef09872e5e50)), closes [#112330](https://github.com/estahn/k8s-image-swapper/issues/112330) [enj/automated-cherry-pick-of-#112193](https://github.com/enj/automated-cherry-pick-of-/issues/112193) [#112161](https://github.com/estahn/k8s-image-swapper/issues/112161) [pohly/automated-cherry-pick-of-#112129](https://github.com/pohly/automated-cherry-pick-of-/issues/112129)
* **deps:** bump k8s.io/client-go from 0.25.0 to 0.25.1 ([#353](https://github.com/estahn/k8s-image-swapper/issues/353)) ([4525ad4](https://github.com/estahn/k8s-image-swapper/commit/4525ad4a667fda8e86d4c19d3c57f9d2fe9ab7c3)), closes [#112161](https://github.com/estahn/k8s-image-swapper/issues/112161) [pohly/automated-cherry-pick-of-#112129](https://github.com/pohly/automated-cherry-pick-of-/issues/112129) [#112336](https://github.com/estahn/k8s-image-swapper/issues/112336) [enj/automated-cherry-pick-of-#112017](https://github.com/enj/automated-cherry-pick-of-/issues/112017) [#112055](https://github.com/estahn/k8s-image-swapper/issues/112055) [aanm/automated-cherry-pick-of-#111752](https://github.com/aanm/automated-cherry-pick-of-/issues/111752)

## [1.3.0](https://github.com/estahn/k8s-image-swapper/compare/v1.2.3...v1.3.0) (2022-09-07)


### :tada: Features

* cross account caching with role ([#336](https://github.com/estahn/k8s-image-swapper/issues/336)) ([98d138e](https://github.com/estahn/k8s-image-swapper/commit/98d138ece9dc27acf20266994e25bef4d43c3d7b))


### :arrow_up: Dependencies

* **deps:** bump actions/cache from 3.0.6 to 3.0.8 ([#319](https://github.com/estahn/k8s-image-swapper/issues/319)) ([245ab30](https://github.com/estahn/k8s-image-swapper/commit/245ab30bec7155caaad2ee95689ca71574f69252)), closes [#809](https://github.com/estahn/k8s-image-swapper/issues/809) [#833](https://github.com/estahn/k8s-image-swapper/issues/833) [#810](https://github.com/estahn/k8s-image-swapper/issues/810) [#888](https://github.com/estahn/k8s-image-swapper/issues/888) [#891](https://github.com/estahn/k8s-image-swapper/issues/891) [#899](https://github.com/estahn/k8s-image-swapper/issues/899) [#894](https://github.com/estahn/k8s-image-swapper/issues/894)
* **deps:** bump alpine from 3.16.1 to 3.16.2 ([da05fdd](https://github.com/estahn/k8s-image-swapper/commit/da05fdd19e9b2540a1a57b30aadabd00ea260f9e))
* **deps:** bump github.com/alitto/pond from 1.8.0 to 1.8.1 ([#342](https://github.com/estahn/k8s-image-swapper/issues/342)) ([4e50c28](https://github.com/estahn/k8s-image-swapper/commit/4e50c28818fb7db5f2d9b3431a346036109a8f44)), closes [alitto/pond#33](https://github.com/alitto/pond/issues/33) [#34](https://github.com/estahn/k8s-image-swapper/issues/34) [#32](https://github.com/estahn/k8s-image-swapper/issues/32)
* **deps:** bump github.com/aws/aws-sdk-go from 1.44.70 to 1.44.92 ([0f396c5](https://github.com/estahn/k8s-image-swapper/commit/0f396c57a16e97a5ed01dd310cd7fe808cb0c8b1))
* **deps:** bump github.com/aws/aws-sdk-go from 1.44.70 to 1.44.92 ([#338](https://github.com/estahn/k8s-image-swapper/issues/338)) ([fa795ae](https://github.com/estahn/k8s-image-swapper/commit/fa795aef3e847fb0f1526dca9efc6cd44ddd9fd9)), closes [#4548](https://github.com/estahn/k8s-image-swapper/issues/4548) [#4546](https://github.com/estahn/k8s-image-swapper/issues/4546) [#4545](https://github.com/estahn/k8s-image-swapper/issues/4545) [#4544](https://github.com/estahn/k8s-image-swapper/issues/4544) [#4543](https://github.com/estahn/k8s-image-swapper/issues/4543) [#4542](https://github.com/estahn/k8s-image-swapper/issues/4542) [#4539](https://github.com/estahn/k8s-image-swapper/issues/4539) [#4536](https://github.com/estahn/k8s-image-swapper/issues/4536) [#4534](https://github.com/estahn/k8s-image-swapper/issues/4534) [#4533](https://github.com/estahn/k8s-image-swapper/issues/4533)
* **deps:** bump github.com/go-co-op/gocron from 1.16.2 to 1.17.0 ([#340](https://github.com/estahn/k8s-image-swapper/issues/340)) ([645bef3](https://github.com/estahn/k8s-image-swapper/commit/645bef3b6b2ab2c936b0192dd24fd083f64e2034)), closes [go-co-op/gocron#380](https://github.com/go-co-op/gocron/issues/380) [go-co-op/gocron#381](https://github.com/go-co-op/gocron/issues/381) [go-co-op/gocron#375](https://github.com/go-co-op/gocron/issues/375) [#381](https://github.com/estahn/k8s-image-swapper/issues/381) [#380](https://github.com/estahn/k8s-image-swapper/issues/380) [#375](https://github.com/estahn/k8s-image-swapper/issues/375)
* **deps:** bump github.com/gruntwork-io/terratest from 0.40.19 to 0.40.21 ([#334](https://github.com/estahn/k8s-image-swapper/issues/334)) ([d0f6c39](https://github.com/estahn/k8s-image-swapper/commit/d0f6c39c30c6c47c502b036de3687c73912ecec9)), closes [#1166](https://github.com/estahn/k8s-image-swapper/issues/1166) [#1159](https://github.com/estahn/k8s-image-swapper/issues/1159)
* **deps:** bump github.com/rs/zerolog from 1.27.0 to 1.28.0 ([#339](https://github.com/estahn/k8s-image-swapper/issues/339)) ([7fb4ff5](https://github.com/estahn/k8s-image-swapper/commit/7fb4ff588ca7f0d177cc9f5bb36066367f9ca84d)), closes [#457](https://github.com/estahn/k8s-image-swapper/issues/457) [#416](https://github.com/estahn/k8s-image-swapper/issues/416) [#454](https://github.com/estahn/k8s-image-swapper/issues/454) [#453](https://github.com/estahn/k8s-image-swapper/issues/453) [#383](https://github.com/estahn/k8s-image-swapper/issues/383) [#396](https://github.com/estahn/k8s-image-swapper/issues/396) [#414](https://github.com/estahn/k8s-image-swapper/issues/414) [#415](https://github.com/estahn/k8s-image-swapper/issues/415) [#430](https://github.com/estahn/k8s-image-swapper/issues/430) [#432](https://github.com/estahn/k8s-image-swapper/issues/432)
* **deps:** bump github.com/spf13/viper from 1.12.0 to 1.13.0 ([#341](https://github.com/estahn/k8s-image-swapper/issues/341)) ([9b59bd4](https://github.com/estahn/k8s-image-swapper/commit/9b59bd4f308916d207fcfb5c7f3c70eedda1c615)), closes [spf13/viper#1371](https://github.com/spf13/viper/issues/1371) [spf13/viper#1373](https://github.com/spf13/viper/issues/1373) [spf13/viper#1393](https://github.com/spf13/viper/issues/1393) [spf13/viper#1424](https://github.com/spf13/viper/issues/1424) [spf13/viper#1405](https://github.com/spf13/viper/issues/1405) [spf13/viper#1414](https://github.com/spf13/viper/issues/1414) [spf13/viper#1387](https://github.com/spf13/viper/issues/1387) [spf13/viper#1374](https://github.com/spf13/viper/issues/1374) [spf13/viper#1375](https://github.com/spf13/viper/issues/1375) [spf13/viper#1378](https://github.com/spf13/viper/issues/1378) [spf13/viper#1360](https://github.com/spf13/viper/issues/1360) [spf13/viper#1381](https://github.com/spf13/viper/issues/1381) [spf13/viper#1384](https://github.com/spf13/viper/issues/1384) [spf13/viper#1383](https://github.com/spf13/viper/issues/1383) [spf13/viper#1395](https://github.com/spf13/viper/issues/1395) [spf13/viper#1420](https://github.com/spf13/viper/issues/1420) [spf13/viper#1422](https://github.com/spf13/viper/issues/1422) [spf13/viper#1412](https://github.com/spf13/viper/issues/1412) [spf13/viper#1373](https://github.com/spf13/viper/issues/1373) [spf13/viper#1393](https://github.com/spf13/viper/issues/1393) [spf13/viper#1371](https://github.com/spf13/viper/issues/1371) [spf13/viper#1387](https://github.com/spf13/viper/issues/1387) [spf13/viper#1405](https://github.com/spf13/viper/issues/1405) [spf13/viper#1414](https://github.com/spf13/viper/issues/1414)
* **deps:** bump goreleaser/goreleaser-action from 3.0.0 to 3.1.0 ([#328](https://github.com/estahn/k8s-image-swapper/issues/328)) ([a8d2dd1](https://github.com/estahn/k8s-image-swapper/commit/a8d2dd1916be3b7e686cb2e6814710ab73c5f953)), closes [#369](https://github.com/estahn/k8s-image-swapper/issues/369) [#357](https://github.com/estahn/k8s-image-swapper/issues/357) [#356](https://github.com/estahn/k8s-image-swapper/issues/356) [#360](https://github.com/estahn/k8s-image-swapper/issues/360) [#359](https://github.com/estahn/k8s-image-swapper/issues/359) [#358](https://github.com/estahn/k8s-image-swapper/issues/358) [#367](https://github.com/estahn/k8s-image-swapper/issues/367) [#369](https://github.com/estahn/k8s-image-swapper/issues/369) [#367](https://github.com/estahn/k8s-image-swapper/issues/367) [#358](https://github.com/estahn/k8s-image-swapper/issues/358) [#359](https://github.com/estahn/k8s-image-swapper/issues/359) [#360](https://github.com/estahn/k8s-image-swapper/issues/360) [#357](https://github.com/estahn/k8s-image-swapper/issues/357) [#356](https://github.com/estahn/k8s-image-swapper/issues/356)
* **deps:** bump k8s.io/api from 0.24.3 to 0.25.0 ([#325](https://github.com/estahn/k8s-image-swapper/issues/325)) ([ce10907](https://github.com/estahn/k8s-image-swapper/commit/ce10907f31431c641269032b823beaff4932f224)), closes [#111657](https://github.com/estahn/k8s-image-swapper/issues/111657) [#109090](https://github.com/estahn/k8s-image-swapper/issues/109090) [#111258](https://github.com/estahn/k8s-image-swapper/issues/111258) [#111113](https://github.com/estahn/k8s-image-swapper/issues/111113) [#111696](https://github.com/estahn/k8s-image-swapper/issues/111696) [#108692](https://github.com/estahn/k8s-image-swapper/issues/108692)
* **deps:** bump k8s.io/client-go from 0.24.3 to 0.25.0 ([#324](https://github.com/estahn/k8s-image-swapper/issues/324)) ([f7c889f](https://github.com/estahn/k8s-image-swapper/commit/f7c889f4880f0d543c05f70759e8cbfef5c3d7ac))

## [1.2.3](https://github.com/estahn/k8s-image-swapper/compare/v1.2.2...v1.2.3) (2022-09-01)

## [1.2.2](https://github.com/estahn/k8s-image-swapper/compare/v1.2.1...v1.2.2) (2022-08-01)

## [1.2.1](https://github.com/estahn/k8s-image-swapper/compare/v1.2.0...v1.2.1) (2022-07-26)

# [1.2.0](https://github.com/estahn/k8s-image-swapper/compare/v1.1.0...v1.2.0) (2022-07-03)


### Bug Fixes

* add missing dash ([228749d](https://github.com/estahn/k8s-image-swapper/commit/228749d98e32a7f90608b37b39d74a108f619f37))
* bump alpine to 3.16 due to security reports ([f7d6564](https://github.com/estahn/k8s-image-swapper/commit/f7d6564e1d607fa53a44e73f8b495a859c31aac1))
* docker references with both tag and digest ([5a17075](https://github.com/estahn/k8s-image-swapper/commit/5a170758a58b0244e6001a3aa5911c3be3d076f8)), closes [#48](https://github.com/estahn/k8s-image-swapper/issues/48)
* failed to solve: executor failed running ([af7df18](https://github.com/estahn/k8s-image-swapper/commit/af7df18a02d6455a4ff8ef1495741ad59cbb4856))
* setup buildx and qemu for image-scan ([c435048](https://github.com/estahn/k8s-image-swapper/commit/c43504873af1c5fd9c2551f8b77f3220f491ab6a))
* standard_init_linux.go:228: exec user process caused: exec format error ([b7d0c89](https://github.com/estahn/k8s-image-swapper/commit/b7d0c89d162ed0d71e01620cb074be68b8612ab2))
* **deps:** update module github.com/aws/aws-sdk-go to v1.40.54 ([7f9dbf5](https://github.com/estahn/k8s-image-swapper/commit/7f9dbf5cf5ddae16e252adc8ce21bb4039cd208d))


### Features

* add arm docker build ([be81815](https://github.com/estahn/k8s-image-swapper/commit/be8181590fb899f1515b78fbc02bf02986d72e9c))
* add full arm support to image copying ([6f14156](https://github.com/estahn/k8s-image-swapper/commit/6f14156acb610541d54d16e85171529de39af6ab))

# [1.1.0](https://github.com/estahn/k8s-image-swapper/compare/v1.0.0...v1.1.0) (2021-10-02)


### Bug Fixes

* provide log record for ImageSwapPolicyExists ([179da70](https://github.com/estahn/k8s-image-swapper/commit/179da706fd43c880d71063b786164f9d2cc862e4))
* timeout for ECR client ([26bdc10](https://github.com/estahn/k8s-image-swapper/commit/26bdc10c3eb21b1dfbea9a659e6b650cb25b335e))
* **deps:** update module github.com/alitto/pond to v1.5.1 ([504e2dd](https://github.com/estahn/k8s-image-swapper/commit/504e2dde58abf1312dab523cb43073a5cc7bc1b1))
* **deps:** update module github.com/aws/aws-sdk-go to v1.38.47 ([#70](https://github.com/estahn/k8s-image-swapper/issues/70)) ([4f30053](https://github.com/estahn/k8s-image-swapper/commit/4f300530ac9a6f8250672b272c24168601f42e62))
* **deps:** update module github.com/aws/aws-sdk-go to v1.40.43 ([266ef01](https://github.com/estahn/k8s-image-swapper/commit/266ef01da6d3caad97dac0f4d0a882dbd75502cc))
* **deps:** update module github.com/containers/image/v5 to v5.11.0 ([#61](https://github.com/estahn/k8s-image-swapper/issues/61)) ([11d6d28](https://github.com/estahn/k8s-image-swapper/commit/11d6d2843dbaa392a418e2a57fdab27fb5249077))
* **deps:** update module github.com/containers/image/v5 to v5.16.0 ([5230b91](https://github.com/estahn/k8s-image-swapper/commit/5230b91a7f37e0f4c6d6370d7c1a9231bf13b983))
* **deps:** update module github.com/dgraph-io/ristretto to v0.1.0 ([#82](https://github.com/estahn/k8s-image-swapper/issues/82)) ([dff1cb1](https://github.com/estahn/k8s-image-swapper/commit/dff1cb186ab1301836f978da1ead02b9ea75bb09))
* **deps:** update module github.com/go-co-op/gocron to v1.9.0 ([c0e9f11](https://github.com/estahn/k8s-image-swapper/commit/c0e9f111eb6b07d54732cc85464bab06dbfdf5e6))
* **deps:** update module github.com/rs/zerolog to v1.22.0 ([#76](https://github.com/estahn/k8s-image-swapper/issues/76)) ([c098326](https://github.com/estahn/k8s-image-swapper/commit/c098326273ab31dbd31869c4749164fde7544b67))
* **deps:** update module github.com/rs/zerolog to v1.23.0 ([#84](https://github.com/estahn/k8s-image-swapper/issues/84)) ([607d5bb](https://github.com/estahn/k8s-image-swapper/commit/607d5bb53a1d7396ae5d504ce49508ceac5e26d6))
* **deps:** update module github.com/rs/zerolog to v1.25.0 ([72822f4](https://github.com/estahn/k8s-image-swapper/commit/72822f42c762455a1a6932631e36418dc3b92d2a))
* **deps:** update module github.com/slok/kubewebhook to v2 ([8bd73d4](https://github.com/estahn/k8s-image-swapper/commit/8bd73d47772c0524c552577805d9f01ae365e77f))
* **deps:** update module github.com/spf13/cobra to v1.2.1 ([ea1e787](https://github.com/estahn/k8s-image-swapper/commit/ea1e7874cdaaa09dea34dd1d4a6f02a7ccb6925c))
* **deps:** update module github.com/spf13/viper to v1.8.1 ([8a055a2](https://github.com/estahn/k8s-image-swapper/commit/8a055a28343d8dbe780f74f99a275a311549576d))
* **deps:** update module k8s.io/api to v0.22.1 ([ab6d898](https://github.com/estahn/k8s-image-swapper/commit/ab6d898a2f9faa49b3c4f61f1443eb55bf79d93b))
* **deps:** update module k8s.io/apimachinery to v0.21.1 ([#79](https://github.com/estahn/k8s-image-swapper/issues/79)) ([aeeeffb](https://github.com/estahn/k8s-image-swapper/commit/aeeeffb4e20c50ecb0e3c0cb46654c3c41f62de0))
* **deps:** update module k8s.io/apimachinery to v0.22.2 ([ef72c66](https://github.com/estahn/k8s-image-swapper/commit/ef72c665f00d6d1fb454cd596c98b3a72cd7614c))


### Features

* Support for imagePullSecrets ([#112](https://github.com/estahn/k8s-image-swapper/issues/112)) ([2d8cf77](https://github.com/estahn/k8s-image-swapper/commit/2d8cf777d32053b8af622cb677d86ac21f526ba8)), closes [#92](https://github.com/estahn/k8s-image-swapper/issues/92) [#19](https://github.com/estahn/k8s-image-swapper/issues/19)
* Support for pod.spec.initContainers ([#118](https://github.com/estahn/k8s-image-swapper/issues/118)) ([725ff2c](https://github.com/estahn/k8s-image-swapper/commit/725ff2cdc45a13d1a31c3694231482ee09ab2cbd)), closes [#73](https://github.com/estahn/k8s-image-swapper/issues/73) [#96](https://github.com/estahn/k8s-image-swapper/issues/96)

# [1.1.0-alpha.1](https://github.com/estahn/k8s-image-swapper/compare/v1.0.0...v1.1.0-alpha.1) (2021-09-30)


### Bug Fixes

* provide log record for ImageSwapPolicyExists ([179da70](https://github.com/estahn/k8s-image-swapper/commit/179da706fd43c880d71063b786164f9d2cc862e4))
* timeout for ECR client ([26bdc10](https://github.com/estahn/k8s-image-swapper/commit/26bdc10c3eb21b1dfbea9a659e6b650cb25b335e))
* **deps:** update module github.com/alitto/pond to v1.5.1 ([504e2dd](https://github.com/estahn/k8s-image-swapper/commit/504e2dde58abf1312dab523cb43073a5cc7bc1b1))
* **deps:** update module github.com/aws/aws-sdk-go to v1.38.47 ([#70](https://github.com/estahn/k8s-image-swapper/issues/70)) ([4f30053](https://github.com/estahn/k8s-image-swapper/commit/4f300530ac9a6f8250672b272c24168601f42e62))
* **deps:** update module github.com/aws/aws-sdk-go to v1.40.43 ([266ef01](https://github.com/estahn/k8s-image-swapper/commit/266ef01da6d3caad97dac0f4d0a882dbd75502cc))
* **deps:** update module github.com/containers/image/v5 to v5.11.0 ([#61](https://github.com/estahn/k8s-image-swapper/issues/61)) ([11d6d28](https://github.com/estahn/k8s-image-swapper/commit/11d6d2843dbaa392a418e2a57fdab27fb5249077))
* **deps:** update module github.com/containers/image/v5 to v5.16.0 ([5230b91](https://github.com/estahn/k8s-image-swapper/commit/5230b91a7f37e0f4c6d6370d7c1a9231bf13b983))
* **deps:** update module github.com/dgraph-io/ristretto to v0.1.0 ([#82](https://github.com/estahn/k8s-image-swapper/issues/82)) ([dff1cb1](https://github.com/estahn/k8s-image-swapper/commit/dff1cb186ab1301836f978da1ead02b9ea75bb09))
* **deps:** update module github.com/go-co-op/gocron to v1.9.0 ([c0e9f11](https://github.com/estahn/k8s-image-swapper/commit/c0e9f111eb6b07d54732cc85464bab06dbfdf5e6))
* **deps:** update module github.com/rs/zerolog to v1.22.0 ([#76](https://github.com/estahn/k8s-image-swapper/issues/76)) ([c098326](https://github.com/estahn/k8s-image-swapper/commit/c098326273ab31dbd31869c4749164fde7544b67))
* **deps:** update module github.com/rs/zerolog to v1.23.0 ([#84](https://github.com/estahn/k8s-image-swapper/issues/84)) ([607d5bb](https://github.com/estahn/k8s-image-swapper/commit/607d5bb53a1d7396ae5d504ce49508ceac5e26d6))
* **deps:** update module github.com/rs/zerolog to v1.25.0 ([72822f4](https://github.com/estahn/k8s-image-swapper/commit/72822f42c762455a1a6932631e36418dc3b92d2a))
* **deps:** update module github.com/slok/kubewebhook to v2 ([8bd73d4](https://github.com/estahn/k8s-image-swapper/commit/8bd73d47772c0524c552577805d9f01ae365e77f))
* **deps:** update module github.com/spf13/cobra to v1.2.1 ([ea1e787](https://github.com/estahn/k8s-image-swapper/commit/ea1e7874cdaaa09dea34dd1d4a6f02a7ccb6925c))
* **deps:** update module github.com/spf13/viper to v1.8.1 ([8a055a2](https://github.com/estahn/k8s-image-swapper/commit/8a055a28343d8dbe780f74f99a275a311549576d))
* **deps:** update module k8s.io/api to v0.22.1 ([ab6d898](https://github.com/estahn/k8s-image-swapper/commit/ab6d898a2f9faa49b3c4f61f1443eb55bf79d93b))
* **deps:** update module k8s.io/apimachinery to v0.21.1 ([#79](https://github.com/estahn/k8s-image-swapper/issues/79)) ([aeeeffb](https://github.com/estahn/k8s-image-swapper/commit/aeeeffb4e20c50ecb0e3c0cb46654c3c41f62de0))
* **deps:** update module k8s.io/apimachinery to v0.22.2 ([ef72c66](https://github.com/estahn/k8s-image-swapper/commit/ef72c665f00d6d1fb454cd596c98b3a72cd7614c))


### Features

* Support for imagePullSecrets ([#112](https://github.com/estahn/k8s-image-swapper/issues/112)) ([2d8cf77](https://github.com/estahn/k8s-image-swapper/commit/2d8cf777d32053b8af622cb677d86ac21f526ba8)), closes [#92](https://github.com/estahn/k8s-image-swapper/issues/92) [#19](https://github.com/estahn/k8s-image-swapper/issues/19)

# 1.0.0 (2020-12-25)


### Bug Fixes

* bump skopeo from 0.2.0 to 1.2.0 ([84025aa](https://github.com/estahn/k8s-image-swapper/commit/84025aaf06d287a306fba98f848e272a19ff8aa0))
* hardcoded AWS region ([3cc0d49](https://github.com/estahn/k8s-image-swapper/commit/3cc0d492bc17a6ad022cb2794786079759f7bc41)), closes [#20](https://github.com/estahn/k8s-image-swapper/issues/20) [#17](https://github.com/estahn/k8s-image-swapper/issues/17)
* **chart:** serviceaccount missing annotation tag ([#21](https://github.com/estahn/k8s-image-swapper/issues/21)) ([7164626](https://github.com/estahn/k8s-image-swapper/commit/71646266e54d043f3bba2ee59975e7f9d11f8f13))
* trace for verbose logs and improve context ([58e05dc](https://github.com/estahn/k8s-image-swapper/commit/58e05dc66644de22183e39dcdc85cf8ce139d8db)), closes [#15](https://github.com/estahn/k8s-image-swapper/issues/15)


### Features

* allow filters for container context ([37d0a4d](https://github.com/estahn/k8s-image-swapper/commit/37d0a4d9ac3bd37128c92ede0bff3f4071483b1d)), closes [#32](https://github.com/estahn/k8s-image-swapper/issues/32)
* automatic token renewal before expiry ([a7c45b8](https://github.com/estahn/k8s-image-swapper/commit/a7c45b8b093efa00e7a04f89a57d5909b4ce068a)), closes [#31](https://github.com/estahn/k8s-image-swapper/issues/31)
* helm chart ([00f6b74](https://github.com/estahn/k8s-image-swapper/commit/00f6b7409c1f0ab59ea227f5d3b995d532beb623))
* ImageSwapPolicy defines the mutation strategy used by the webhook. ([9d61659](https://github.com/estahn/k8s-image-swapper/commit/9d616596013d7b1cbb121b0cf137273867bdb19f))
* POC ([fedcb22](https://github.com/estahn/k8s-image-swapper/commit/fedcb22c2fef26a76bd0fd9dacff70d0d952c077))

# [1.0.0-beta.4](https://github.com/estahn/k8s-image-swapper/compare/v1.0.0-beta.3...v1.0.0-beta.4) (2020-12-23)


### Bug Fixes

* bump skopeo from 0.2.0 to 1.2.0 ([09fdb6e](https://github.com/estahn/k8s-image-swapper/commit/09fdb6eb2383c30a45d1a5a7fb3d10a4c6b891e0))

# [1.0.0-beta.3](https://github.com/estahn/k8s-image-swapper/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2020-12-23)


### Features

* ImageSwapPolicy defines the mutation strategy used by the webhook. ([e64bc6d](https://github.com/estahn/k8s-image-swapper/commit/e64bc6d120bea925a06cf06f3b22c8184a24fb35))

# [1.0.0-beta.2](https://github.com/estahn/k8s-image-swapper/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2020-12-22)


### Features

* allow filters for container context ([c7e4c51](https://github.com/estahn/k8s-image-swapper/commit/c7e4c51a5a04ef9ae8689ffe73ff7d1411f43450)), closes [#32](https://github.com/estahn/k8s-image-swapper/issues/32)
* automatic token renewal before expiry ([d557c23](https://github.com/estahn/k8s-image-swapper/commit/d557c23e798f4cae61cd412d99f482ec4d310b9f)), closes [#31](https://github.com/estahn/k8s-image-swapper/issues/31)

# 1.0.0-beta.1 (2020-12-21)


### Bug Fixes

* hardcoded AWS region ([3cc0d49](https://github.com/estahn/k8s-image-swapper/commit/3cc0d492bc17a6ad022cb2794786079759f7bc41)), closes [#20](https://github.com/estahn/k8s-image-swapper/issues/20) [#17](https://github.com/estahn/k8s-image-swapper/issues/17)
* **chart:** serviceaccount missing annotation tag ([#21](https://github.com/estahn/k8s-image-swapper/issues/21)) ([7164626](https://github.com/estahn/k8s-image-swapper/commit/71646266e54d043f3bba2ee59975e7f9d11f8f13))
* trace for verbose logs and improve context ([58e05dc](https://github.com/estahn/k8s-image-swapper/commit/58e05dc66644de22183e39dcdc85cf8ce139d8db)), closes [#15](https://github.com/estahn/k8s-image-swapper/issues/15)


### Features

* helm chart ([00f6b74](https://github.com/estahn/k8s-image-swapper/commit/00f6b7409c1f0ab59ea227f5d3b995d532beb623))
* POC ([fedcb22](https://github.com/estahn/k8s-image-swapper/commit/fedcb22c2fef26a76bd0fd9dacff70d0d952c077))

# 1.0.0-alpha.1 (2020-12-18)


### Bug Fixes

* **chart:** serviceaccount missing annotation tag ([#21](https://github.com/estahn/k8s-image-swapper/issues/21)) ([7164626](https://github.com/estahn/k8s-image-swapper/commit/71646266e54d043f3bba2ee59975e7f9d11f8f13))
* trace for verbose logs and improve context ([58e05dc](https://github.com/estahn/k8s-image-swapper/commit/58e05dc66644de22183e39dcdc85cf8ce139d8db)), closes [#15](https://github.com/estahn/k8s-image-swapper/issues/15)


### Features

* helm chart ([00f6b74](https://github.com/estahn/k8s-image-swapper/commit/00f6b7409c1f0ab59ea227f5d3b995d532beb623))
* POC ([fedcb22](https://github.com/estahn/k8s-image-swapper/commit/fedcb22c2fef26a76bd0fd9dacff70d0d952c077))


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[enrico.stahn@gmail.com](mailto:enrico.stahn@gmail.com).
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].

[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

By participating to this project, you agree to abide our
[code of conduct](/CODE_OF_CONDUCT.md).

## Setup your machine

`k8s-image-swapper` is written in [Go](https://golang.org/).

Prerequisites:

- `make`
- [Go 1.16+](https://golang.org/doc/install)
- [golangci-lint](https://golangci-lint.run/usage/install/#local-installation)
- [Docker](https://www.docker.com/) (or [Podman](https://podman.io/))
- [kind](https://kind.sigs.k8s.io/)
- [pre-commit](https://pre-commit.com/) (optional)
- [ngrok](https://ngrok.com/) (optional)

Clone `k8s-image-swapper` anywhere:

```sh
git clone git@github.com:estahn/k8s-image-swapper.git
```

Install the build and lint dependencies:

```sh
make setup
```

A good way of making sure everything is all right is running the test suite:

```sh
make test
```

## Test your change

You can create a branch for your changes and try to build from the source as you go:

```sh
make test
```

When you are satisfied with the changes, we suggest you run:

```sh
make fmt lint test
```

Which runs all the linters and tests.

## Create a commit

Commit messages should be well formatted, and to make that "standardized", we
are using Conventional Commits.

You can follow the documentation on
[their website](https://www.conventionalcommits.org).

## Submit a pull request

Push your branch to your `k8s-image-swapper` fork and open a pull request against the
main branch.


================================================
FILE: Dockerfile
================================================
#FROM quay.io/skopeo/stable:v1.2.0 AS skopeo
#FROM gcr.io/distroless/base-debian10
#FROM debian:10
#COPY --from=skopeo /usr/bin/skopeo /skopeo

# TODO: Using alpine for now due to easier installation of skopeo
#       Will use distroless after incorporating skopeo into the webhook directly
FROM alpine:3.23.3
RUN ["apk", "add", "--no-cache", "--repository=http://dl-cdn.alpinelinux.org/alpine/edge/community", "skopeo>=1.2.0"]

COPY k8s-image-swapper /

ENTRYPOINT ["/k8s-image-swapper"]

ARG BUILD_DATE
ARG VCS_REF

LABEL maintainer="k8s-image-swapper <https://github.com/estahn/k8s-image-swapper/issues>" \
      org.opencontainers.image.title="k8s-image-swapper" \
      org.opencontainers.image.description="Mirror images into your own registry and swap image references automatically." \
      org.opencontainers.image.url="https://github.com/estahn/k8s-image-swapper" \
      org.opencontainers.image.source="https://github.com/estahn/k8s-image-swapper" \
      org.opencontainers.image.vendor="estahn" \
      org.label-schema.schema-version="1.0" \
      org.label-schema.name="k8s-image-swapper" \
      org.label-schema.description="Mirror images into your own registry and swap image references automatically." \
      org.label-schema.url="https://github.com/estahn/k8s-image-swapper" \
      org.label-schema.vcs-url="git@github.com:estahn/k8s-image-swapper.git" \
      org.label-schema.vendor="estahn" \
      org.opencontainers.image.revision="$VCS_REF" \
      org.opencontainers.image.created="$BUILD_DATE" \
      org.label-schema.vcs-ref="$VCS_REF" \
      org.label-schema.build-date="$BUILD_DATE"


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Enrico Stahn

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
SOURCE_FILES?=./...
TEST_PATTERN?=.
TEST_OPTIONS?=

.PHONY: help $(MAKECMDGOALS)
.DEFAULT_GOAL := help

export GO111MODULE := on
export GOPROXY = https://proxy.golang.org,direct

help: ## List targets & descriptions
	@cat Makefile* | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

setup: ## Install dependencies
	go mod download
	go mod tidy

test: ## Run tests
	LC_ALL=C go test $(TEST_OPTIONS) -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=5m

cover: test ## Run tests and open coverage report
	go tool cover -html=coverage.txt

fmt: ## gofmt and goimports all go files
	gofmt -l -w .
	goimports -l -w .

lint: ## Run linters
	golangci-lint run

e2e: ## Run end-to-end tests
	go test -v -run TestHelmDeployment ./test


================================================
FILE: README.md
================================================
<p align="center">
  <img alt="Raiders of the Lost Ark" src="docs/img/indiana.gif" height="140" />
  <h3 align="center">k8s-image-swapper</h3>
  <p align="center">Mirror images into your own registry and swap image references automatically.</p>
</p>

---

`k8s-image-swapper` is a mutating webhook for Kubernetes, downloading images into your own registry and pointing the images to that new location.
It is an alternative to a [docker pull-through proxy](https://docs.docker.com/registry/recipes/mirror/).

**Amazon ECR** and **Google Container Registry** are currently supported.

## :zap: Benefits

Using `k8s-image-swapper` will improve the overall availability, reliability, durability and resiliency of your
Kubernetes cluster by keeping 3rd-party images mirrored into your own registry.

`k8s-image-swapper` will transparently consolidate all images into a single registry without the need to adjust manifests
therefore reducing the impact of external registry failures, rate limiting, network issues, change or removal of images
while reducing data traffic and therefore cost.

**TL;DR:**

* Protect against:
  * external registry failure ([quay.io outage](https://www.reddit.com/r/devops/comments/f9kiej/quayio_is_experiencing_an_outage/))
  * image pull rate limiting ([docker.io rate limits](https://www.docker.com/blog/scaling-docker-to-serve-millions-more-developers-network-egress/))
  * accidental image changes
  * removal of images
* Use in air-gaped environments without the need to change manifests
* Reduce NAT ingress traffic/cost

## :book: Documentation

A comprehensive guide on getting started and a list of configuration options can be found in the documentation.

[![Documentation](https://img.shields.io/badge/Documentation-2FA4E7?style=for-the-badge&logo=ReadMe&logoColor=white)](https://estahn.github.io/k8s-image-swapper/index.html)

## :question: Community

You have questions, need support and or just want to talk about `k8s-image-swapper`?

Here are ways to get in touch with the community:

[![Slack channel](https://img.shields.io/badge/Slack_Channel-4A154B?style=for-the-badge&logo=slack&logoColor=white)](http://slack.kubernetes.io/)
[![GitHub Discussions](https://img.shields.io/badge/GITHUB_DISCUSSION-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/estahn/k8s-image-swapper/discussions)


## :heart_decoration: Sponsor

Does your company use `k8s-image-swapper`?
Help keep the project bug-free and feature rich by [sponsoring the project](https://github.com/sponsors/estahn).

## :office: Commercial Support

Does your company require individual support or addition of features within a guaranteed timeframe?
Contact me via [email](mailto:enrico.stahn@gmail.com) to discuss.

## :octocat: Badges

[![Release](https://img.shields.io/github/release/estahn/k8s-image-swapper.svg?style=for-the-badge)](https://github.com/estahn/k8s-image-swapper/releases/latest)
[![Artifact Hub](https://img.shields.io/badge/Artifact_Hub-417598?style=for-the-badge&logo=artifacthub&logoColor=white)](https://artifacthub.io/packages/helm/estahn/k8s-image-swapper)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](/LICENSE.md)
[![Codecov branch](https://img.shields.io/codecov/c/github/estahn/k8s-image-swapper/main.svg?style=for-the-badge)](https://codecov.io/gh/estahn/k8s-image-swapper)
[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge)](http://godoc.org/github.com/estahn/k8s-image-swapper)

## :star2: Stargazers over time

[![Stargazers over time](https://starchart.cc/estahn/k8s-image-swapper.svg)](https://starchart.cc/estahn/k8s-image-swapper)


================================================
FILE: cmd/root.go
================================================
/*
Copyright © 2020 Enrico Stahn <enrico.stahn@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/estahn/k8s-image-swapper/pkg/config"
	"github.com/estahn/k8s-image-swapper/pkg/registry"
	"github.com/estahn/k8s-image-swapper/pkg/secrets"
	"github.com/estahn/k8s-image-swapper/pkg/types"
	"github.com/estahn/k8s-image-swapper/pkg/webhook"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	kwhhttp "github.com/slok/kubewebhook/v2/pkg/http"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

var cfgFile string
var cfg *config.Config = &config.Config{}

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "k8s-image-swapper",
	Short: "Mirror images into your own registry and swap image references automatically.",
	Long: `Mirror images into your own registry and swap image references automatically.

A mutating webhook for Kubernetes, pointing the images to a new location.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	Run: func(cmd *cobra.Command, args []string) {
		//promReg := prometheus.NewRegistry()
		//metricsRec := metrics.NewPrometheus(promReg)
		log.Trace().Interface("config", cfg).Msg("config")

		// Create registry clients for source registries
		sourceRegistryClients := []registry.Client{}
		for _, reg := range cfg.Source.Registries {
			sourceRegistryClient, err := registry.NewClient(reg)
			if err != nil {
				log.Err(err).Msgf("error connecting to source registry at %s", reg.Domain())
				os.Exit(1)
			}
			sourceRegistryClients = append(sourceRegistryClients, sourceRegistryClient)
		}

		// Create a registry client for private target registry
		targetRegistryClient, err := registry.NewClient(cfg.Target)
		if err != nil {
			log.Err(err).Msgf("error connecting to target registry at %s", cfg.Target.Domain())
			os.Exit(1)
		}

		imageSwapPolicy, err := types.ParseImageSwapPolicy(cfg.ImageSwapPolicy)
		if err != nil {
			log.Err(err).Str("policy", cfg.ImageSwapPolicy).Msg("parsing image swap policy failed")
		}

		imageCopyPolicy, err := types.ParseImageCopyPolicy(cfg.ImageCopyPolicy)
		if err != nil {
			log.Err(err).Str("policy", cfg.ImageCopyPolicy).Msg("parsing image copy policy failed")
		}

		imageCopyDeadline := config.DefaultImageCopyDeadline
		if cfg.ImageCopyDeadline != 0 {
			imageCopyDeadline = cfg.ImageCopyDeadline
		}

		imagePullSecretProvider := setupImagePullSecretsProvider()

		// Inform secret provider about managed private source registries
		imagePullSecretProvider.SetAuthenticatedRegistries(sourceRegistryClients)

		wh, err := webhook.NewImageSwapperWebhookWithOpts(
			targetRegistryClient,
			webhook.Filters(cfg.Source.Filters),
			webhook.ImagePullSecretsProvider(imagePullSecretProvider),
			webhook.ImageSwapPolicy(imageSwapPolicy),
			webhook.ImageCopyPolicy(imageCopyPolicy),
			webhook.ImageCopyDeadline(imageCopyDeadline),
		)
		if err != nil {
			log.Err(err).Msg("error creating webhook")
			os.Exit(1)
		}

		// Get the handler for our webhook.
		whHandler, err := kwhhttp.HandlerFor(kwhhttp.HandlerConfig{Webhook: wh})
		if err != nil {
			log.Err(err).Msg("error creating webhook handler")
			os.Exit(1)
		}

		handler := http.NewServeMux()
		handler.Handle("/webhook", whHandler)
		handler.Handle("/metrics", promhttp.Handler())
		handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			_, err := w.Write([]byte(`<html>
			 <head><title>k8s-image-webhook</title></head>
			 <body>
			 <h1>k8s-image-webhook</h1>
			 <ul><li><a href='/metrics'>Metrics</a></li><li><a href='/webhook'>Webhook</a></li></ul>
			 </body>
			 </html>`))

			if err != nil {
				log.Error()
			}
		})

		srv := &http.Server{
			Addr: cfg.ListenAddress,
			// Good practice to set timeouts to avoid Slowloris attacks.
			WriteTimeout: time.Second * 15,
			ReadTimeout:  time.Second * 15,
			IdleTimeout:  time.Second * 60,
			Handler:      handler,
		}

		go func() {
			log.Info().Msgf("Listening on %v", cfg.ListenAddress)
			//err = http.ListenAndServeTLS(":8080", cfg.certFile, cfg.keyFile, whHandler)
			if cfg.TLSCertFile != "" && cfg.TLSKeyFile != "" {
				if err := srv.ListenAndServeTLS(cfg.TLSCertFile, cfg.TLSKeyFile); err != nil {
					log.Err(err).Msg("error serving webhook")
					os.Exit(1)
				}
			} else {
				if err := srv.ListenAndServe(); err != nil {
					log.Err(err).Msg("error serving webhook")
					os.Exit(1)
				}
			}
		}()

		c := make(chan os.Signal, 1)
		// We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) or SIGTERM
		// SIGKILL, SIGQUIT will not be caught.
		signal.Notify(c, os.Interrupt, syscall.SIGTERM)

		// Block until we receive our signal.
		<-c

		// Create a deadline to wait for.
		var wait time.Duration
		ctx, cancel := context.WithTimeout(context.Background(), wait)
		defer cancel()
		// Doesn't block if no connections, but will otherwise wait
		// until the timeout deadline.
		if err := srv.Shutdown(ctx); err != nil {
			log.Err(err).Msg("Error during shutdown")
		}
		// Optionally, you could run srv.Shutdown in a goroutine and block on
		// <-ctx.Done() if your application should wait for other services
		// to finalize based on context cancellation.
		log.Info().Msg("Shutting down")
		os.Exit(0)
	},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func init() {
	cobra.OnInitialize(initConfig, initLogger)

	// Here you will define your flags and configuration settings.
	// Cobra supports persistent flags, which, if defined here,
	// will be global for your application.

	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.k8s-image-swapper.yaml)")
	rootCmd.PersistentFlags().StringVar(&cfg.LogLevel, "log-level", "info", "Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]")
	rootCmd.PersistentFlags().StringVar(&cfg.LogFormat, "log-format", "json", "Format of the log messages. Valid levels: [json, console]")

	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	//rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	rootCmd.Flags().StringVar(&cfg.ListenAddress, "listen-address", ":8443", "Address on which to expose the webhook")
	rootCmd.Flags().StringVar(&cfg.TLSCertFile, "tls-cert-file", "", "File containing the TLS certificate")
	rootCmd.Flags().StringVar(&cfg.TLSKeyFile, "tls-key-file", "", "File containing the TLS private key")
	rootCmd.Flags().BoolVar(&cfg.DryRun, "dry-run", true, "If true, print the action taken without taking it")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	// Default to aws target registry type if none are defined
	config.SetViperDefaults(viper.GetViper())

	if cfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cfgFile)
	} else {
		// Find home directory.
		home, err := homedir.Dir()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		// Search config in home directory with name ".k8s-image-swapper" (without extension).
		viper.AddConfigPath(home)
		viper.AddConfigPath(".")
		viper.SetConfigType("yaml")
		viper.SetConfigName(".k8s-image-swapper")
	}

	viper.AutomaticEnv() // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		log.Info().Str("file", viper.ConfigFileUsed()).Msg("using config file")
	}

	if err := viper.Unmarshal(&cfg); err != nil {
		log.Err(err).Msg("failed to unmarshal the config file")
	}

	//validate := validator.New()
	//if err := validate.Struct(cfg); err != nil {
	//	validationErrors := err.(validator.ValidationErrors)
	//	log.Err(validationErrors).Msg("validation errors for config file")
	//}
}

// initLogger configures the log level
func initLogger() {
	if cfg.LogFormat == "console" {
		log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
	}

	lvl, err := zerolog.ParseLevel(cfg.LogLevel)
	if err != nil {
		lvl = zerolog.InfoLevel
		log.Err(err).Msgf("could not set log level to '%v'.", cfg.LogLevel)
	}

	zerolog.SetGlobalLevel(lvl)

	// add file and line number to log if level is trace
	if lvl == zerolog.TraceLevel {
		log.Logger = log.With().Caller().Logger()
	}
}

// setupImagePullSecretsProvider configures the provider handling secrets
func setupImagePullSecretsProvider() secrets.ImagePullSecretsProvider {
	config, err := rest.InClusterConfig()
	if err != nil {
		log.Warn().Err(err).Msg("failed to configure Kubernetes client, will continue without reading secrets")
		return secrets.NewDummyImagePullSecretsProvider()
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Warn().Err(err).Msg("failed to configure Kubernetes client, will continue without reading secrets")
		return secrets.NewDummyImagePullSecretsProvider()
	}

	return secrets.NewKubernetesImagePullSecretsProvider(clientset)
}


================================================
FILE: docs/configuration.md
================================================
# Configuration

The configuration is managed via the config file `.k8s-image-swapper.yaml`.
Some options can be overridden via parameters, e.g. `--dry-run`.

## Dry Run

The option `dryRun` allows to run the webhook without executing the actions, e.g. repository creation,
image download and manifest mutation.

!!! example
    ```yaml
    dryRun: true
    ```

## Log Level & Format

The option `logLevel` & `logFormat` allow to adjust the verbosity and format (e.g. `json`, `console`).

!!! example
    ```yaml
    logLevel: debug
    logFormat: console
    ```

## ImageSwapPolicy

The option `imageSwapPolicy` (default: `exists`) defines the mutation strategy used.

* `always`: Will always swap the image regardless of the image existence in the target registry.
            This can result in pods ending in state ImagePullBack if images fail to be copied to the target registry.
* `exists`: Only swaps the image if it exits in the target registry.
            This can result in pods pulling images from the source registry, e.g. the first pod pulls
            from source registry, subsequent pods pull from target registry.

## ImageCopyPolicy

The option `imageCopyPolicy` (default: `delayed`) defines the image copy strategy used.

* `delayed`: Submits the copy job to a process queue and moves on.
* `immediate`: Submits the copy job to a process queue and waits for it to finish (deadline defined by `imageCopyDeadline`).
* `force`: Attempts to immediately copy the image (deadline defined by `imageCopyDeadline`).
* `none`: Do not copy the image.

## ImageCopyDeadline

The option `imageCopyDeadline` (default: `8s`) defines the duration after which the image copy if aborted.

This option only applies for `immediate` and `force` image copy strategies.


## Source

This section configures details about the image source.

### Registries

The option `source.registries` describes a list of registries to pull images from, using a specific configuration.

#### AWS

By providing configuration on AWS registries you can ask `k8s-image-swapper` to handle the authentication using the same credentials as for the target AWS registry.
This authentication method is the default way to get authorized by a private registry if the targeted Pod does not provide an `imagePullSecret`.

Registries are described with an AWS account ID and region, mostly to construct the ECR domain `[ACCOUNT_ID].dkr.ecr.[REGION].amazonaws.com`.

!!! example
    ```yaml
    source:
      registries:
        - type: aws
          aws:
            accountId: 123456789
            region: ap-southeast-2
        - type: aws
          aws:
            accountId: 234567890
            region: us-east-1
    ```
### Filters

Filters provide control over what pods will be processed.
By default, all pods will be processed.
If a condition matches, the pod will **NOT** be processed.

[JMESPath](https://jmespath.org/) is used as query language and allows flexible rules for most use-cases.

!!! info
    The data structure used for JMESPath is as follows:

    === "Structure"
        ```yaml
        obj:
          <Object Spec>
        container:
          <Container Spec>
        ```

    === "Example"
        ```yaml
        obj:
          metadata:
            name: static-web
            labels:
              role: myrole
          spec:
            containers:
              - name: web
                image: nginx
                ports:
                  - name: web
                    containerPort: 80
                    protocol: TCP
        container:
          name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
        ```

Below you will find a list of common queries and/or ideas:

!!! tip "List of common queries/ideas"
    * Do not process if namespace equals `kube-system` (_Helm chart default_)
      ```yaml
      source:
        filters:
          - jmespath: "obj.metadata.namespace == 'kube-system'"
      ```
    *  Only process if namespace equals `playground`
       ```yaml
       source:
         filters:
           - jmespath: "obj.metadata.namespace != 'playground'"
       ```
    * Only process if namespace ends with `-dev`
      ```yaml
      source:
        filters:
          - jmespath: "ends_with(obj.metadata.namespace,'-dev')"
      ```
    * Do not process AWS ECR images
      ```yaml
      source:
        filters:
          - jmespath: "contains(container.image, '.dkr.ecr.') && contains(container.image, '.amazonaws.com')"
      ```

`k8s-image-swapper` will log the filter data and result in `debug` mode.
This can be used in conjunction with [JMESPath.org](https://jmespath.org/) which
has a live editor that can be used as a playground to experiment with more complex queries.

## Target

This section configures details about the image target.
The option `target` allows to specify which type of registry you set as your target (AWS, GCP...).
At the moment, `aws` and `gcp` are the only supported values.

### AWS

The option `target.aws` holds details about the target registry storing the images.
The AWS Account ID and Region is primarily used to construct the ECR domain `[ACCOUNTID].dkr.ecr.[REGION].amazonaws.com`.

!!! example
    ```yaml
    target:
      type: aws
      aws:
        accountId: 123456789
        region: ap-southeast-2
        prefix: /cache
    ```

#### ECR Options

##### Tags

This provides a way to add custom tags to newly created repositories. This may be useful while looking at AWS costs.
It's a slice of `Key` and `Value`.

!!! example
    ```yaml
    target:
      type: aws
      aws:
        ecrOptions:
          tags:
            - key: cluster
              value: myCluster
    ```

### GCP

The option `target.gcp` holds details about the target registry storing the images.
The GCP location, projectId, and repositoryId are used to constrct the GCP Artifact Registry domain `[LOCATION]-docker.pkg.dev/[PROJECT_ID]/[REPOSITORY_ID]`.

!!! example
    ```yaml
    target:
      type: gcp
      gcp:
        location: us-central1
        projectId: gcp-project-123
        repositoryId: main
    ```


================================================
FILE: docs/faq.md
================================================
# FAQ

### Is pulling from private registries supported?

Yes, `imagePullSecrets` on `Pod` and `ServiceAccount` level in the hooked pod definition are supported.

It is also possible to provide a list of ECRs to which authentication is handled by `k8s-image-swapper` using the same credentials as for the target registry. Please see [Configuration > Source - AWS](configuration.md#Private-registries).

### Are config changes reloaded gracefully?

Not yet, they require a pod rotation.

### What happens if the image is not found in the target registry?

Please see [Configuration > ImageCopyPolicy](configuration.md#imagecopypolicy).

### What level of registry outage does this handle?

If the source image registry is not reachable it will replace the reference with the target registry reference.
If the target registry is down it will do the same. It has no notion of the target registry being up or down.

### What happens if `k8s-image-swapper` is unavailable?

Kubernetes will continue to work as if `k8s-image-swapper` was not installed.
The webhook [failure policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy)
is set to `Ignore`.

!!! tip
    Environments with strict compliance requirements (or air-gapped) may overwrite this with `Fail` to
    avoid falling back to the public images.

### Why are sidecar images not being replaced?

A Kubernetes cluster can have multiple mutating webhooks.
Mutating webhooks execute sequentiatlly and each can change a submitted object.
Changes may be applied after `k8s-image-swapper` was executed, e.g. Istio injecting a sidecar.

```
... -> k8s-image-swapper -> Istio sidecar injection --> ...
```

Kubernetes 1.15+ allows to re-run webhooks if a mutating webhook modifies an object.
The behaviour is controlled by the [Reinvocation policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#reinvocation-policy).

> reinvocationPolicy may be set to `Never` or `IfNeeded`. It defaults to Never.
>
> * `Never`: the webhook must not be called more than once in a single admission evaluation
> * `IfNeeded`: the webhook may be called again as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call.

The reinvocation policy can be set in the helm chart as follows:

!!! example "Helm Chart"
    ```yaml
    webhook:
      reinvocationPolicy: IfNeeded
    ```


================================================
FILE: docs/getting-started.md
================================================
# Getting started

This document will provide guidance for installing `k8s-image-swapper`.

## Prerequisites

`k8s-image-swapper` will automatically create image repositories and mirror images into them.
This requires certain permissions for your target registry (_only AWS ECR and GCP ArtifactRegistry are supported atm_).

Before you get started choose a namespace to install `k8s-image-swapper` in, e.g. `operations` or `k8s-image-swapper`.
Ensure the namespace exists and is configured as your current context[^1].
All examples below will omit the namespace.

### AWS ECR as a target registry

AWS supports a variety of authentication strategies.
`k8s-image-swapper` uses the official Amazon AWS SDK and therefore supports [all available authentication strategies](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html).
Choose from one of the strategies below or an alternative if needed.

#### IAM credentials

1. Create an IAM user (e.g. `k8s-image-swapper`) with permissions[^2] to create ECR repositories and upload container images.
   An IAM policy example can be found in the footnotes[^2].
2. Create a Kubernetes secret (e.g. `k8s-image-swapper-aws`) containing the IAM credentials you just obtained, e.g.

    ```bash
    kubectl create secret generic k8s-image-swapper-aws \
      --from-literal=aws_access_key_id=<...> \
      --from-literal=aws_secret_access_key=<...>
    ```

#### Using ECR registries cross-account

Although ECR allows creating registry policy that allows reposistories creation from different account, there's no way to push anything to these repositories.
ECR resource-level policy can not be applied during creation, and to apply it afterwards we need ecr:SetRepositoryPolicy permission, which foreign account doesn't have.

One way out of this conundrum is to assume the role in target account

```yaml title=".k8s-image-swapper.yml"
target:
  type: aws
  aws:
    accountId: 123456789
    region: ap-southeast-2
    role: arn:aws:iam::123456789012:role/roleName
```
!!! note
    Make sure that target role has proper trust permissions that allow to assume it cross-account

!!! note
    In order te be able to pull images from outside accounts, you will have to apply proper access policy


#### Access policy

You can specify the access policy that will be applied to the created repos in config. Policy should be raw json string.
For example:
```yaml title=".k8s-image-swapper.yml"
target:
  type: aws
  aws:
    accountId: 123456789
    region: ap-southeast-2
    role: arn:aws:iam::123456789012:role/roleName
    ecrOptions:
      accessPolicy: |
        {
          "Statement": [
            {
              "Sid": "AllowCrossAccountPull",
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability"
              ],
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalOrgID": "o-xxxxxxxxxx"
                }
              }
            }
          ],
          "Version": "2008-10-17"
        }
```

#### Lifecycle policy

Similarly to access policy, lifecycle policy can be specified, for example:

```yaml title=".k8s-image-swapper.yml"
target:
  type: aws
  aws:
    accountId: 123456789
    region: ap-southeast-2
    role: arn:aws:iam::123456789012:role/roleName
    ecrOptions:
      lifecyclePolicy: |
        {
          "rules": [
            {
              "rulePriority": 1,
              "description": "Rule 1",
              "selection": {
                "tagStatus": "any",
                "countType": "imageCountMoreThan",
                "countNumber": 1000
              },
              "action": {
                "type": "expire"
              }
            }
          ]
        }
```

#### Service Account

1. Create an Webidentity IAM role (e.g. `k8s-image-swapper`) with the following trust policy, e.g
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${your_aws_account_id}:oidc-provider/${oidc_image_swapper_role_arn}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${oidc_image_swapper_role_arn}:sub": "system:serviceaccount:${k8s_image_swapper_namespace}:${k8s_image_swapper_serviceaccount_name}"
        }
      }
    }
  ]
}
```

2. Create and attach permission policy[^2] to the role from Step 1..

Note: You can see a complete example below in [Terraform](Terraform)

### GCP Artifact Registry as a target registry

To target a GCP Artifact Registry set the `target.type` to `gcp` and provide additional metadata in the configuration.

```yaml title=".k8s-image-swapper.yml"
target:
  type: gcp
  gcp:
    location: us-central1
    projectId: gcp-project-123
    repositoryId: main
```

!!! note
    This is fundamentally different from the AWS ECR implementation since all images will be stored under *one* GCP Artifact Registry repository.
    <figure markdown>
      ![GCP Console - Artifact Registry](img/gcp_artifact_registry.png){ loading=lazy }
    </figure>

#### Create Repository

Create and configure a single GCP Artifact Registry repository to store Docker images for `k8s-image-swapper`.

=== "Terraform"

    ```terraform
    resource "google_artifact_registry_repository" "repo" {
      project       = var.project_id
      location      = var.region
      repository_id = "main"
      description   = "main docker repository"
      format        = "DOCKER"
    }
    ```

#### IAM for GKE / Nodes / Compute

Give the compute service account that the nodes use, permissions to pull images from Artifact Registry.

=== "Terraform"

    ```terraform
    resource "google_project_iam_member" "compute_artifactregistry_reader" {
      project = var.project_id
      role    = "roles/artifactregistry.reader"
      member  = "serviceAccount:${var.compute_sa_email}"
    }
    ```

Allow GKE node pools to access Artifact Registry API via OAuth scope `https://www.googleapis.com/auth/devstorage.read_only`

=== "Terraform"

    ```terraform
    resource "google_container_node_pool" "primary_nodes_v1" {
      project  = var.project_id
      name     = "${google_container_cluster.primary.name}-node-pool-v1"
      location = var.region
      cluster  = google_container_cluster.primary.name
      ...
      node_config {
        oauth_scopes = [
          ...
          "https://www.googleapis.com/auth/devstorage.read_only",
        ]
        ...
      }
      ...
    }
    ```

#### IAM for `k8s-image-swapper`

On GKE, leverage Workload Identity for the `k8s-image-swapper` K8s service account.

1. Enable Workload Identity on the GKE cluster[^3].

    === "Terraform"

        ```terraform
        resource "google_container_cluster" "primary" {
          ...
          workload_identity_config {
            workload_pool = "${var.project_id}.svc.id.goog"
          }
          ...
        }
        ```

2. Setup a Google Service Account (GSA) for `k8s-image-swapper`.

    === "Terraform"

        ```terraform
        resource "google_service_account" "k8s_image_swapper_service_account" {
          project      = var.project_id
          account_id   = k8s-image-swapper
          display_name = "Workload identity for kube-system/k8s-image-swapper"
        }
        ```

3. Setup Workload Identity for the GSA

    !!! note
        This example assumes `k8s-image-swapper` is deployed to the `kube-system` namespace and uses `k8s-image-swapper` as the K8s service account name.

    === "Terraform"

        ```terraform
        resource "google_service_account_iam_member" "k8s_image_swapper_workload_identity_binding" {
          service_account_id = google_service_account.k8s_image_swapper_service_account.name
          role               = "roles/iam.workloadIdentityUser"
          member             = "serviceAccount:${var.project_id}.svc.id.goog[kube-system/k8s-image-swapper]"

          depends_on = [
            google_container_cluster.primary,
          ]
        }
        ```

4. Bind permissions for GSA to access Artifact Registry

    Setup the `roles/artifactregistry.writer` role in order for `k8s-image-swapper` to be able to read/write images to the Artifact Repository.

    === "Terraform"

        ```terraform
        resource "google_project_iam_member" "k8s_image_swapper_service_account_binding" {
          project  = var.project_id
          role     = "roles/artifactregistry.writer"
          member   = "serviceAccount:${google_service_account.k8s_image_swapper_service_account.email}"
        }
        ```

5. (Optional) Bind additional permissions for GSA to read from other GCP Artifact Registries
6. Set Workload Identity annotation on `k8s-iamge-swapper` service account
   ```yaml
   serviceAccount:
     annotations:
       iam.gke.io/gcp-service-account: k8s-image-swapper@gcp-project-123.iam.gserviceaccount.com
   ```

#### Firewall

If running `k8s-image-swapper` on a private GKE cluster you must have a firewall rule enabled to allow the GKE control plane to talk to `k8s-image-swapper` on port `8443`. See the following Terraform example for the firewall configuration.

=== "Terraform"

    ```terraform
    resource "google_compute_firewall" "k8s_image_swapper_webhook" {
      project       = var.project_id
      name          = "gke-${google_container_cluster.primary.name}-k8s-image-swapper-webhook"
      network       = google_compute_network.vpc.name
      direction     = "INGRESS"
      source_ranges = [google_container_cluster.primary.private_cluster_config[0].master_ipv4_cidr_block]
      target_tags   = [google_container_cluster.primary.name]

      allow {
        ports    = ["8443"]
        protocol = "tcp"
      }
    }
    ```

For more details see https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules

## Helm

1. Add the Helm chart repository:
   ```bash
   helm repo add estahn https://estahn.github.io/charts/
   ```
2. Update the local chart information:
   ```bash
   helm repo update
   ```
3. Install `k8s-image-swapper`
   ```
   helm install k8s-image-swapper estahn/k8s-image-swapper \
     --set config.target.aws.accountId=$AWS_ACCOUNT_ID \
     --set config.target.aws.region=$AWS_DEFAULT_REGION \
     --set awsSecretName=k8s-image-swapper-aws
   ```

!!! note
    `awsSecretName` is not required for the Service Account method and instead the service account is annotated:
    ```yaml
    serviceAccount:
      create: true
      annotations:
        eks.amazonaws.com/role-arn: ${oidc_image_swapper_role_arn}
    ```

## Terraform

Full example of helm chart deployment with AWS service account setup in Terraform.


```terraform
data "aws_caller_identity" "current" {
}

variable "cluster_oidc_provider" {
  default = "oidc.eks.ap-southeast-1.amazonaws.com/id/ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
  description = "example oidc endpoint that is created during eks deployment"
}

variable  "cluster_name" {
  default = "test"
  description = "name of the eks cluster being deployed to"
}


variable  "region" {
  default = "ap-southeast-1"
  description = "name of the eks cluster being deployed to"
}

variable "k8s_image_swapper_namespace" {
  default     = "kube-system"
  description = "namespace to install k8s-image-swapper"
}

variable "k8s_image_swapper_name" {
  default     = "k8s-image-swapper"
  description = "name for k8s-image-swapper release and service account"
}

#k8s-image-swapper helm chart
resource "helm_release" "k8s_image_swapper" {
  name       = var.k8s_image_swapper_name
  namespace  = "kube-system"
  repository = "https://estahn.github.io/charts/"
  chart   = "k8s-image-swapper"
  keyring = ""
  version = "1.0.1"
  values = [
    <<YAML
config:
  dryRun: true
  logLevel: debug
  logFormat: console

  source:
    # Filters provide control over what pods will be processed.
    # By default all pods will be processed. If a condition matches, the pod will NOT be processed.
    # For query language details see https://jmespath.org/
    filters:
      - jmespath: "obj.metadata.namespace != 'default'"
      - jmespath: "contains(container.image, '.dkr.ecr.') && contains(container.image, '.amazonaws.com')"
  target:
    type: aws
    aws:
      accountId: "${data.aws_caller_identity.current.account_id}"
      region: ${var.region}

secretReader:
  enabled: true

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Specifies annotations for this service account
  annotations:
    eks.amazonaws.com/role-arn: "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_role.k8s_image_swapper.name}"
YAML
    ,
  ]
}

#iam policy for k8s-image-swapper service account
resource "aws_iam_role_policy" "k8s_image_swapper" {
  name = "${var.cluster_name}-${var.k8s_image_swapper_name}"
  role = aws_iam_role.k8s_image_swapper.id

  policy = <<-EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:DescribeRepositories",
                "ecr:DescribeRegistry"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:BatchGetImage",
                "ecr:CompleteLayerUpload",
                "ecr:CreateRepository",
                "ecr:GetDownloadUrlForLayer",
                "ecr:InitiateLayerUpload",
                "ecr:ListImages",
                "ecr:PutImage",
                "ecr:PutLifecyclePolicy",
                "ecr:UploadLayerPart"
            ],
            "Resource": [
              "arn:aws:ecr:*:${data.aws_caller_identity.current.account_id}:repository/docker.io/*",
              "arn:aws:ecr:*:${data.aws_caller_identity.current.account_id}:repository/quay.io/*"
	    ]
        }
    ]
}
EOF
}

#role for k8s-image-swapper service account
resource "aws_iam_role" "k8s_image_swapper" {
  name               = "${var.cluster_name}-${var.k8s_image_swapper_name}"
  assume_role_policy = <<-EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${replace(var.cluster_oidc_provider, "/https:///", "")}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${replace(var.cluster_oidc_provider, "/https:///", "")}:sub": "system:serviceaccount:${var.k8s_image_swapper_namespace}:${var.k8s_image_swapper_name}"
        }
      }
    }
  ]
}
EOF
}

```

[^1]: Use a tool like [kubectx & kubens](https://github.com/ahmetb/kubectx) for convienience.
[^2]:
    ??? tldr "IAM Policy"
        ```json
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Action": [
                        "ecr:GetAuthorizationToken",
                        "ecr:DescribeRepositories",
                        "ecr:DescribeRegistry",
                        "ecr:TagResource"
                    ],
                    "Resource": "*"
                },
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Action": [
                        "ecr:BatchCheckLayerAvailability"
                        "ecr:BatchGetImage",
                        "ecr:CompleteLayerUpload",
                        "ecr:CreateRepository",
                        "ecr:GetDownloadUrlForLayer",
                        "ecr:InitiateLayerUpload",
                        "ecr:ListImages",
                        "ecr:PutImage",
                        "ecr:PutLifecyclePolicy",
                        "ecr:UploadLayerPart"
                    ],
                    "Resource": "arn:aws:ecr:*:123456789:repository/*"
                }
            ]
        }
        ```

        !!! tip "Further restricting access"
            The resource configuration allows access to all AWS ECR repositories within the account 123456789.
            Restrict this further by repository name or tag.
            `k8s-image-swapper` will create repositories with the source registry as prefix, e.g. `nginx` --> `docker.io/library/nginx:latest`.

[^3]: [Google Kubernetes Engine (GKE) > Documentation > Guides > Use Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
[^4]: [Google Kubernetes Engine (GKE) > Documentation > Guides > Creating a private cluster > Adding firewall rules for specific use cases](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules)


================================================
FILE: docs/index.md
================================================
<p align="center">
  <img alt="Raiders of the Lost Ark" src="img/indiana.gif" height="140" />
  <h3 align="center">k8s-image-swapper</h3>
  <p align="center">Mirror images into your own registry and swap image references automatically.</p>
</p>

`k8s-image-swapper` is a mutating webhook for Kubernetes, downloading images into your own registry and pointing the images to that new location.
It is an alternative to a [docker pull-through proxy](https://docs.docker.com/registry/recipes/mirror/).
The feature set was primarily designed with Amazon ECR in mind but may work with other registries.

## Benefits

Using `k8s-image-swapper` will improve the overall availability, reliability, durability and resiliency of your
Kubernetes cluster by keeping 3rd-party images mirrored into your own registry.

`k8s-image-swapper` will transparently consolidate all images into a single registry without the need to adjust manifests
therefore reducing the impact of external registry failures, rate limiting, network issues, change or removal of images
while reducing data traffic and therefore cost.

**TL;DR:**

* Protect against:
    * external registry failure ([quay.io outage](https://www.reddit.com/r/devops/comments/f9kiej/quayio_is_experiencing_an_outage/))
    * image pull rate limiting ([docker.io rate limits](https://www.docker.com/blog/scaling-docker-to-serve-millions-more-developers-network-egress/))
    * accidental image changes
    * removal of images
* Use in air-gaped environments without the need to change manifests
* Reduce NAT ingress traffic/cost

## How it works

![Explainer](img/k8s-image-swapper_explainer.gif)


================================================
FILE: docs/overrides/main.html
================================================
{% extends "base.html" %}

{% block outdated %}
  You're not viewing the latest version.
  <a href="{{ '../' ~ base_url }}">
    <strong>Click here to go to latest.</strong>
  </a>
{% endblock %}

{% block extrahead %}
<meta name="google-site-verification" content="WZHhaHX7z1JWk0UfBwO6xUK3X_dlGq7TZd9sFBG5xQ8" />
{% endblock %}


================================================
FILE: go.mod
================================================
module github.com/estahn/k8s-image-swapper

go 1.24.0

require (
	cloud.google.com/go/artifactregistry v1.17.1
	github.com/alitto/pond v1.9.2
	github.com/aws/aws-sdk-go v1.55.7
	github.com/containers/image/v5 v5.36.2
	github.com/dgraph-io/ristretto v0.2.0
	github.com/evanphx/json-patch v5.9.11+incompatible
	github.com/go-co-op/gocron v1.37.0
	github.com/gruntwork-io/terratest v0.50.0
	github.com/jmespath/go-jmespath v0.4.0
	github.com/mitchellh/go-homedir v1.1.0
	github.com/prometheus/client_golang v1.23.2
	github.com/rs/zerolog v1.34.0
	github.com/slok/kubewebhook/v2 v2.5.0
	github.com/spf13/cobra v1.10.1
	github.com/spf13/viper v1.21.0
	github.com/stretchr/testify v1.11.1
	google.golang.org/api v0.250.0
	gopkg.in/yaml.v2 v2.4.0 // indirect
	k8s.io/api v0.33.4
	k8s.io/apimachinery v0.33.4
	k8s.io/client-go v0.33.4
	sigs.k8s.io/yaml v1.4.0 // indirect
)

require (
	cloud.google.com/go v0.120.0 // indirect
	cloud.google.com/go/auth v0.16.5 // indirect
	cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
	cloud.google.com/go/compute/metadata v0.9.0 // indirect
	cloud.google.com/go/iam v1.5.2 // indirect
	cloud.google.com/go/longrunning v0.6.7 // indirect
	dario.cat/mergo v1.0.2 // indirect
	filippo.io/edwards25519 v1.1.1 // indirect
	github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
	github.com/BurntSushi/toml v1.5.0 // indirect
	github.com/Microsoft/go-winio v0.6.2 // indirect
	github.com/Microsoft/hcsshim v0.13.0 // indirect
	github.com/agext/levenshtein v1.2.3 // indirect
	github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
	github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect
	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
	github.com/aws/aws-sdk-go-v2/config v1.28.5 // indirect
	github.com/aws/aws-sdk-go-v2/credentials v1.17.46 // indirect
	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect
	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 // indirect
	github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
	github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
	github.com/aws/aws-sdk-go-v2/service/acm v1.30.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.65.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1 // indirect
	github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/iam v1.38.1 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.5 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect
	github.com/aws/aws-sdk-go-v2/service/kms v1.37.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/lambda v1.88.5 // indirect
	github.com/aws/aws-sdk-go-v2/service/rds v1.91.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2 // indirect
	github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 // indirect
	github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/sns v1.33.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1 // indirect
	github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect
	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect
	github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect
	github.com/aws/smithy-go v1.24.2 // indirect
	github.com/beorn7/perks v1.0.1 // indirect
	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
	github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
	github.com/cespare/xxhash/v2 v2.3.0 // indirect
	github.com/containerd/cgroups/v3 v3.0.5 // indirect
	github.com/containerd/errdefs v1.0.0 // indirect
	github.com/containerd/errdefs/pkg v0.3.0 // indirect
	github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
	github.com/containerd/typeurl/v2 v2.2.3 // indirect
	github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
	github.com/containers/ocicrypt v1.2.1 // indirect
	github.com/containers/storage v1.59.1 // indirect
	github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
	github.com/cyphar/filepath-securejoin v0.4.1 // indirect
	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
	github.com/distribution/reference v0.6.0 // indirect
	github.com/docker/distribution v2.8.3+incompatible // indirect
	github.com/docker/docker v28.3.3+incompatible // indirect
	github.com/docker/docker-credential-helpers v0.9.3 // indirect
	github.com/docker/go-connections v0.5.0 // indirect
	github.com/docker/go-units v0.5.0 // indirect
	github.com/dustin/go-humanize v1.0.1 // indirect
	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
	github.com/felixge/httpsnoop v1.0.4 // indirect
	github.com/fsnotify/fsnotify v1.9.0 // indirect
	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
	github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect
	github.com/go-logr/logr v1.4.3 // indirect
	github.com/go-logr/stdr v1.2.2 // indirect
	github.com/go-openapi/jsonpointer v0.21.0 // indirect
	github.com/go-openapi/jsonreference v0.21.0 // indirect
	github.com/go-openapi/swag v0.23.1 // indirect
	github.com/go-sql-driver/mysql v1.8.1 // indirect
	github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
	github.com/gogo/protobuf v1.3.2 // indirect
	github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
	github.com/gonvenience/bunt v1.3.5 // indirect
	github.com/gonvenience/neat v1.3.12 // indirect
	github.com/gonvenience/term v1.0.2 // indirect
	github.com/gonvenience/text v1.0.7 // indirect
	github.com/gonvenience/wrap v1.1.2 // indirect
	github.com/gonvenience/ytbx v1.4.4 // indirect
	github.com/google/gnostic-models v0.6.9 // indirect
	github.com/google/go-cmp v0.7.0 // indirect
	github.com/google/go-containerregistry v0.20.3 // indirect
	github.com/google/go-intervals v0.0.2 // indirect
	github.com/google/s2a-go v0.1.9 // indirect
	github.com/google/uuid v1.6.0 // indirect
	github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
	github.com/googleapis/gax-go/v2 v2.15.0 // indirect
	github.com/gorilla/mux v1.8.1 // indirect
	github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
	github.com/gruntwork-io/go-commons v0.8.0 // indirect
	github.com/hashicorp/errwrap v1.1.0 // indirect
	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
	github.com/hashicorp/go-getter/v2 v2.2.3 // indirect
	github.com/hashicorp/go-multierror v1.1.1 // indirect
	github.com/hashicorp/go-safetemp v1.0.0 // indirect
	github.com/hashicorp/go-version v1.7.0 // indirect
	github.com/hashicorp/hcl/v2 v2.22.0 // indirect
	github.com/hashicorp/terraform-json v0.23.0 // indirect
	github.com/homeport/dyff v1.6.0 // indirect
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
	github.com/jackc/pgpassfile v1.0.0 // indirect
	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
	github.com/jackc/pgx/v5 v5.7.1 // indirect
	github.com/jackc/puddle/v2 v2.2.2 // indirect
	github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
	github.com/josharian/intern v1.0.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/klauspost/compress v1.18.0 // indirect
	github.com/klauspost/pgzip v1.2.6 // indirect
	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
	github.com/mailru/easyjson v0.9.0 // indirect
	github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect
	github.com/mattn/go-colorable v0.1.13 // indirect
	github.com/mattn/go-isatty v0.0.19 // indirect
	github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
	github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
	github.com/mitchellh/go-ps v1.0.0 // indirect
	github.com/mitchellh/go-testing-interface v1.14.1 // indirect
	github.com/mitchellh/go-wordwrap v1.0.1 // indirect
	github.com/mitchellh/hashstructure v1.1.0 // indirect
	github.com/moby/docker-image-spec v1.3.1 // indirect
	github.com/moby/spdystream v0.5.0 // indirect
	github.com/moby/sys/capability v0.4.0 // indirect
	github.com/moby/sys/mountinfo v0.7.2 // indirect
	github.com/moby/sys/user v0.4.0 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
	github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
	github.com/opencontainers/go-digest v1.0.0 // indirect
	github.com/opencontainers/image-spec v1.1.1 // indirect
	github.com/opencontainers/runtime-spec v1.2.1 // indirect
	github.com/opencontainers/selinux v1.12.0 // indirect
	github.com/pelletier/go-toml/v2 v2.2.4 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
	github.com/pquerna/otp v1.4.0 // indirect
	github.com/prometheus/client_model v0.6.2 // indirect
	github.com/prometheus/common v0.66.1 // indirect
	github.com/prometheus/procfs v0.16.1 // indirect
	github.com/robfig/cron/v3 v3.0.1 // indirect
	github.com/russross/blackfriday/v2 v2.1.0 // indirect
	github.com/sagikazarmark/locafero v0.11.0 // indirect
	github.com/sergi/go-diff v1.3.1 // indirect
	github.com/sirupsen/logrus v1.9.3 // indirect
	github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
	github.com/spf13/afero v1.15.0 // indirect
	github.com/spf13/cast v1.10.0 // indirect
	github.com/spf13/pflag v1.0.10 // indirect
	github.com/stretchr/objx v0.5.2 // indirect
	github.com/subosito/gotenv v1.6.0 // indirect
	github.com/sylabs/sif/v2 v2.21.1 // indirect
	github.com/tchap/go-patricia/v2 v2.3.3 // indirect
	github.com/texttheater/golang-levenshtein v1.0.1 // indirect
	github.com/tmccombs/hcl2json v0.6.4 // indirect
	github.com/ulikunitz/xz v0.5.14 // indirect
	github.com/urfave/cli v1.22.16 // indirect
	github.com/vbatts/tar-split v0.12.1 // indirect
	github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect
	github.com/x448/float16 v0.8.4 // indirect
	github.com/zclconf/go-cty v1.15.0 // indirect
	go.opencensus.io v0.24.0 // indirect
	go.opentelemetry.io/auto/sdk v1.2.1 // indirect
	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
	go.opentelemetry.io/otel v1.39.0 // indirect
	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
	go.opentelemetry.io/otel/metric v1.39.0 // indirect
	go.opentelemetry.io/otel/trace v1.39.0 // indirect
	go.opentelemetry.io/proto/otlp v1.7.0 // indirect
	go.uber.org/atomic v1.9.0 // indirect
	go.yaml.in/yaml/v2 v2.4.2 // indirect
	go.yaml.in/yaml/v3 v3.0.4 // indirect
	golang.org/x/crypto v0.46.0 // indirect
	golang.org/x/mod v0.30.0 // indirect
	golang.org/x/net v0.48.0 // indirect
	golang.org/x/oauth2 v0.34.0 // indirect
	golang.org/x/sync v0.19.0 // indirect
	golang.org/x/sys v0.39.0 // indirect
	golang.org/x/term v0.38.0 // indirect
	golang.org/x/text v0.32.0 // indirect
	golang.org/x/time v0.13.0 // indirect
	golang.org/x/tools v0.39.0 // indirect
	gomodules.xyz/jsonpatch/v3 v3.0.1 // indirect
	gomodules.xyz/orderedmap v0.1.0 // indirect
	google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
	google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
	google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
	google.golang.org/grpc v1.79.3 // indirect
	google.golang.org/protobuf v1.36.10 // indirect
	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
	gopkg.in/inf.v0 v0.9.1 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
	k8s.io/klog/v2 v2.130.1 // indirect
	k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
	k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
	sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
	sigs.k8s.io/randfill v1.0.0 // indirect
	sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
)


================================================
FILE: go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
cloud.google.com/go/artifactregistry v1.17.1 h1:A20kj2S2HO9vlyBVyVFHPxArjxkXvLP5LjcdE7NhaPc=
cloud.google.com/go/artifactregistry v1.17.1/go.mod h1:06gLv5QwQPWtaudI2fWO37gfwwRUHwxm3gA8Fe568Hc=
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=
filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA=
github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE=
github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0=
github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o=
github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 h1:hqcxMc2g/MwwnRMod9n6Bd+t+9Nf7d5qRg7RaXKPd6o=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41/go.mod h1:d1eH0VrttvPmrCraU68LOyNdu26zFxQFjrVSb5vdhog=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y=
github.com/aws/aws-sdk-go-v2/service/acm v1.30.6 h1:fDg0RlN30Xf/yYzEUL/WXqhmgFsjVb/I3230oCfyI5w=
github.com/aws/aws-sdk-go-v2/service/acm v1.30.6/go.mod h1:zRR6jE3v/TcbfO8C2P+H0Z+kShiKKVaVyoIl8NQRjyg=
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0 h1:1KzQVZi7OTixxaVJ8fWaJAUBjme+iQ3zBOCZhE4RgxQ=
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0/go.mod h1:I1+/2m+IhnK5qEbhS3CrzjeiVloo9sItE/2K+so0fkU=
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.65.0 h1:3yaFbUbuLfN8n1q01wZtQtHRzUDc/jm0VvniMY0IPE8=
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.65.0/go.mod h1:PobeppEnIjw4pcgjFryNDZCTH7AiqZw0yb5r98Gvf9c=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1 h1:vucMirlM6D+RDU8ncKaSZ/5dGrXNajozVwpmWNPn2gQ=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1/go.mod h1:fceORfs010mNxZbQhfqUjUeHlTwANmIT4mvHamuUaUg=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0 h1:RhSoBFT5/8tTmIseJUXM6INTXTQDF8+0oyxWBnozIms=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0/go.mod h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw=
github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 h1:zg+3FGHA0PBs0KM25qE/rOf2o5zsjNa1g/Qq83+SDI0=
github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6/go.mod h1:ZSq54Z9SIsOTf1Efwgw1msilSs4XVEfVQiP9nYVnKpM=
github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0 h1:7/vgFWplkusJN/m+3QOa+W9FNRqa8ujMPNmdufRaJpg=
github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0/go.mod h1:dPTOvmjJQ1T7Q+2+Xs2KSPrMvx+p0rpyV+HsQVnUK4o=
github.com/aws/aws-sdk-go-v2/service/iam v1.38.1 h1:hfkzDZHBp9jAT4zcd5mtqckpU4E3Ax0LQaEWWk1VgN8=
github.com/aws/aws-sdk-go-v2/service/iam v1.38.1/go.mod h1:u36ahDtZcQHGmVm/r+0L1sfKX4fzLEMdCqiKRKkUMVM=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.5 h1:3Y457U2eGukmjYjeHG6kanZpDzJADa2m0ADqnuePYVQ=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.5/go.mod h1:CfwEHGkTjYZpkQ/5PvcbEtT7AJlG68KkEvmtwU8z3/U=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.6 h1:CZImQdb1QbU9sGgJ9IswhVkxAcjkkD1eQTMA1KHWk+E=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.6/go.mod h1:YJDdlK0zsyxVBxGU48AR/Mi8DMrGdc1E3Yij4fNrONA=
github.com/aws/aws-sdk-go-v2/service/lambda v1.88.5 h1:HWN7xwaV7Zwrn3Jlauio4u4aTMFgRzG2fblHWQeir/k=
github.com/aws/aws-sdk-go-v2/service/lambda v1.88.5/go.mod h1:6HBXRyFFqOw+ALkJ6YGHfrr20/YXYv6X9pcZErXRvCA=
github.com/aws/aws-sdk-go-v2/service/rds v1.91.0 h1:eqHz3Uih+gb0vLE5Cc4Xf733vOxsxDp6GFUUVQU4d7w=
github.com/aws/aws-sdk-go-v2/service/rds v1.91.0/go.mod h1:h2jc7IleH3xHY7y+h8FH7WAZcz3IVLOB6/jXotIQ/qU=
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2 h1:wmt05tPp/CaRZpPV5B4SaJ5TwkHKom07/BzHoLdkY1o=
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2/go.mod h1:d+K9HESMpGb1EU9/UmmpInbGIUcAkwmcY6ZO/A3zZsw=
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo=
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6 h1:1KDMKvOKNrpD667ORbZ/+4OgvUoaok1gg/MLzrHF9fw=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6/go.mod h1:DmtyfCfONhOyVAJ6ZMTrDSFIeyCBlEO93Qkfhxwbxu0=
github.com/aws/aws-sdk-go-v2/service/sns v1.33.6 h1:lEUtRHICiXsd7VRwRjXaY7MApT2X4Ue0Mrwe6XbyBro=
github.com/aws/aws-sdk-go-v2/service/sns v1.33.6/go.mod h1:SODr0Lu3lFdT0SGsGX1TzFTapwveBrT5wztVoYtppm8=
github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1 h1:39WvSrVq9DD6UHkD+fx5x19P5KpRQfNdtgReDVNbelc=
github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1/go.mod h1:3gwPzC9LER/BTQdQZ3r6dUktb1rSjABF1D3Sr6nS7VU=
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0 h1:mADKqoZaodipGgiZfuAjtlcr4IVBtXPZKVjkzUZCCYM=
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0/go.mod h1:l9qF25TzH95FhcIak6e4vt79KE4I7M2Nf59eMUVjj6c=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg=
github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng=
github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containers/image/v5 v5.36.2 h1:GcxYQyAHRF/pLqR4p4RpvKllnNL8mOBn0eZnqJbfTwk=
github.com/containers/image/v5 v5.36.2/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs=
github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY=
github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=
github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8=
github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU=
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/gonvenience/bunt v1.3.5 h1:wSQquifvwEWtzn27k1ngLfeLaStyt0k1b/K6TrlCNAs=
github.com/gonvenience/bunt v1.3.5/go.mod h1:7ApqkVBEWvX04oJ28Q2WeI/BvJM6VtukaJAU/q/pTs8=
github.com/gonvenience/neat v1.3.12 h1:xwIyRbJcG9LgcDYys+HHLH9DqqHeQsUpS5CfBUeskbs=
github.com/gonvenience/neat v1.3.12/go.mod h1:8OljAIgPelN0uPPO94VBqxK+Kz98d6ZFwHDg5o/PfkE=
github.com/gonvenience/term v1.0.2 h1:qKa2RydbWIrabGjR/fegJwpW5m+JvUwFL8mLhHzDXn0=
github.com/gonvenience/term v1.0.2/go.mod h1:wThTR+3MzWtWn7XGVW6qQ65uaVf8GHED98KmwpuEQeo=
github.com/gonvenience/text v1.0.7 h1:YmIqmgTwxnACYCG59DykgMbomwteYyNhAmEUEJtPl14=
github.com/gonvenience/text v1.0.7/go.mod h1:OAjH+mohRszffLY6OjgQcUXiSkbrIavooFpfIt1ZwAs=
github.com/gonvenience/wrap v1.1.2 h1:xPKxNwL1HCguwyM+HlP/1CIuc9LRd7k8RodLwe9YTZA=
github.com/gonvenience/wrap v1.1.2/go.mod h1:GiryBSXoI3BAAhbWD1cZVj7RZmtiu0ERi/6R6eJfslI=
github.com/gonvenience/ytbx v1.4.4 h1:jQopwyaLsVGuwdxSiN4WkXjsEaFNPJ3V4lUj7eyEpzo=
github.com/gonvenience/ytbx v1.4.4/go.mod h1:w37+MKCPcCMY/jpPNmEklD4xKqrOAVBO6kIWW2+uI6M=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro=
github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78=
github.com/gruntwork-io/terratest v0.50.0 h1:AbBJ7IRCpLZ9H4HBrjeoWESITv8nLjN6/f1riMNcAsw=
github.com/gruntwork-io/terratest v0.50.0/go.mod h1:see0lbKvAqz6rvzvN2wyfuFQQG4PWcAb2yHulF6B2q4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk=
github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M=
github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI=
github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c=
github.com/homeport/dyff v1.6.0 h1:AN+ikld0Fy+qx34YE7655b/bpWuxS6cL9k852pE2GUc=
github.com/homeport/dyff v1.6.0/go.mod h1:FlAOFYzeKvxmU5nTrnG+qrlJVWpsFew7pt8L99p5q8k=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg=
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0=
github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRD
Download .txt
gitextract_aug9culg/

├── .github/
│   ├── FUNDING.yml
│   ├── dependabot.yml
│   ├── release-drafter.yml
│   ├── release.yml
│   └── workflows/
│       ├── auto-approve.yml
│       ├── auto-merge.yml
│       ├── awaiting-reply.yml
│       ├── codeql-analysis.yml
│       ├── deploy.yml
│       ├── docs.yml
│       ├── pre-commit.yml
│       ├── release-drafter.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .goreleaser.yml
├── .k8s-image-swapper.yml
├── .pre-commit-config.yaml
├── .releaserc
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── cmd/
│   └── root.go
├── docs/
│   ├── configuration.md
│   ├── faq.md
│   ├── getting-started.md
│   ├── index.md
│   └── overrides/
│       └── main.html
├── go.mod
├── go.sum
├── main.go
├── mkdocs.yml
├── package.json
├── pkg/
│   ├── config/
│   │   ├── config.go
│   │   └── config_test.go
│   ├── registry/
│   │   ├── client.go
│   │   ├── ecr.go
│   │   ├── ecr_test.go
│   │   ├── gar.go
│   │   ├── gar_test.go
│   │   └── inmemory.go
│   ├── secrets/
│   │   ├── dummy.go
│   │   ├── dummy_test.go
│   │   ├── kubernetes.go
│   │   ├── kubernetes_test.go
│   │   └── provider.go
│   ├── types/
│   │   ├── types.go
│   │   └── types_test.go
│   └── webhook/
│       ├── image_copier.go
│       ├── image_copier_test.go
│       ├── image_swapper.go
│       └── image_swapper_test.go
└── test/
    ├── curl.sh
    ├── e2e_test.go
    ├── kind-with-registry.sh
    ├── kind.yaml
    └── requests/
        ├── admissionreview-imagepullsecrets.json
        └── admissionreview-simple.json
Download .txt
SYMBOL INDEX (143 symbols across 21 files)

FILE: cmd/root.go
  function Execute (line 193) | func Execute() {
  function init (line 200) | func init() {
  function initConfig (line 221) | func initConfig() {
  function initLogger (line 262) | func initLogger() {
  function setupImagePullSecretsProvider (line 282) | func setupImagePullSecretsProvider() secrets.ImagePullSecretsProvider {

FILE: main.go
  function main (line 26) | func main() {

FILE: pkg/config/config.go
  constant DefaultImageCopyDeadline (line 34) | DefaultImageCopyDeadline = 8 * time.Second
  type Config (line 36) | type Config struct
  type JMESPathFilter (line 54) | type JMESPathFilter struct
  type Source (line 58) | type Source struct
  type Registry (line 63) | type Registry struct
    method Domain (line 118) | func (r Registry) Domain() string {
  type AWS (line 69) | type AWS struct
    method EcrDomain (line 106) | func (a *AWS) EcrDomain() string {
  type GCP (line 77) | type GCP struct
    method GarDomain (line 114) | func (g *GCP) GarDomain() string {
  type ECROptions (line 83) | type ECROptions struct
  type Tag (line 92) | type Tag struct
  type ImageScanningConfiguration (line 97) | type ImageScanningConfiguration struct
  type EncryptionConfiguration (line 101) | type EncryptionConfiguration struct
  function CheckRegistryConfiguration (line 131) | func CheckRegistryConfiguration(r Registry) error {
  function SetViperDefaults (line 168) | func SetViperDefaults(v *viper.Viper) {

FILE: pkg/config/config_test.go
  function TestConfigParses (line 13) | func TestConfigParses(t *testing.T) {
  function TestEcrDomain (line 235) | func TestEcrDomain(t *testing.T) {

FILE: pkg/registry/client.go
  type Client (line 16) | type Client interface
  type DockerConfig (line 32) | type DockerConfig struct
  type AuthConfig (line 36) | type AuthConfig struct
  function NewClient (line 41) | func NewClient(r config.Registry) (Client, error) {
  function GenerateDockerConfig (line 61) | func GenerateDockerConfig(c Client) ([]byte, error) {

FILE: pkg/registry/ecr.go
  type ECRClient (line 27) | type ECRClient struct
    method Credentials (line 96) | func (e *ECRClient) Credentials() string {
    method CreateRepository (line 100) | func (e *ECRClient) CreateRepository(ctx context.Context, name string)...
    method buildEcrTags (line 174) | func (e *ECRClient) buildEcrTags() []*ecr.Tag {
    method RepositoryExists (line 185) | func (e *ECRClient) RepositoryExists() bool {
    method CopyImage (line 189) | func (e *ECRClient) CopyImage(ctx context.Context, srcRef ctypes.Image...
    method PullImage (line 235) | func (e *ECRClient) PullImage() error {
    method PutImage (line 239) | func (e *ECRClient) PutImage() error {
    method ImageExists (line 243) | func (e *ECRClient) ImageExists(ctx context.Context, imageRef ctypes.I...
    method Endpoint (line 271) | func (e *ECRClient) Endpoint() string {
    method IsOrigin (line 276) | func (e *ECRClient) IsOrigin(imageRef ctypes.ImageReference) bool {
    method requestAuthToken (line 282) | func (e *ECRClient) requestAuthToken() ([]byte, time.Time, error) {
    method scheduleTokenRenewal (line 300) | func (e *ECRClient) scheduleTokenRenewal() error {
  function NewECRClient (line 37) | func NewECRClient(clientConfig config.AWS) (*ECRClient, error) {
  function NewDummyECRClient (line 318) | func NewDummyECRClient(region string, targetAccount string, role string,...
  function NewMockECRClient (line 327) | func NewMockECRClient(ecrClient ecriface.ECRAPI, region string, ecrDomai...

FILE: pkg/registry/ecr_test.go
  function TestDockerConfig (line 13) | func TestDockerConfig(t *testing.T) {
  function TestECRIsOrigin (line 26) | func TestECRIsOrigin(t *testing.T) {

FILE: pkg/registry/gar.go
  type GARAPI (line 25) | type GARAPI interface
  type GARClient (line 27) | type GARClient struct
    method CreateRepository (line 63) | func (e *GARClient) CreateRepository(ctx context.Context, name string)...
    method RepositoryExists (line 67) | func (e *GARClient) RepositoryExists() bool {
    method CopyImage (line 71) | func (e *GARClient) CopyImage(ctx context.Context, srcRef ctypes.Image...
    method PullImage (line 125) | func (e *GARClient) PullImage() error {
    method PutImage (line 129) | func (e *GARClient) PutImage() error {
    method ImageExists (line 133) | func (e *GARClient) ImageExists(ctx context.Context, imageRef ctypes.I...
    method Endpoint (line 161) | func (e *GARClient) Endpoint() string {
    method IsOrigin (line 166) | func (e *GARClient) IsOrigin(imageRef ctypes.ImageReference) bool {
    method requestAuthToken (line 171) | func (e *GARClient) requestAuthToken() ([]byte, time.Time, error) {
    method scheduleTokenRenewal (line 188) | func (e *GARClient) scheduleTokenRenewal() error {
    method Credentials (line 205) | func (e *GARClient) Credentials() string {
    method DockerConfig (line 209) | func (e *GARClient) DockerConfig() ([]byte, error) {
  function NewGARClient (line 35) | func NewGARClient(clientConfig config.GCP) (*GARClient, error) {
  function NewMockGARClient (line 226) | func NewMockGARClient(garClient GARAPI, garDomain string) (*GARClient, e...

FILE: pkg/registry/gar_test.go
  function TestGARIsOrigin (line 11) | func TestGARIsOrigin(t *testing.T) {

FILE: pkg/secrets/dummy.go
  type DummyImagePullSecretsProvider (line 11) | type DummyImagePullSecretsProvider struct
    method SetAuthenticatedRegistries (line 19) | func (p *DummyImagePullSecretsProvider) SetAuthenticatedRegistries(reg...
    method GetImagePullSecrets (line 23) | func (p *DummyImagePullSecretsProvider) GetImagePullSecrets(ctx contex...
  function NewDummyImagePullSecretsProvider (line 15) | func NewDummyImagePullSecretsProvider() ImagePullSecretsProvider {

FILE: pkg/secrets/dummy_test.go
  function TestDummyImagePullSecretsProvider_GetImagePullSecrets (line 12) | func TestDummyImagePullSecretsProvider_GetImagePullSecrets(t *testing.T) {
  function TestNewDummyImagePullSecretsProvider (line 57) | func TestNewDummyImagePullSecretsProvider(t *testing.T) {

FILE: pkg/secrets/kubernetes.go
  type KubernetesImagePullSecretsProvider (line 18) | type KubernetesImagePullSecretsProvider struct
    method SetAuthenticatedRegistries (line 81) | func (p *KubernetesImagePullSecretsProvider) SetAuthenticatedRegistrie...
    method GetImagePullSecrets (line 86) | func (p *KubernetesImagePullSecretsProvider) GetImagePullSecrets(ctx c...
  type ImagePullSecretsResult (line 24) | type ImagePullSecretsResult struct
    method Add (line 52) | func (r *ImagePullSecretsResult) Add(name string, data []byte) {
    method AuthFile (line 58) | func (r *ImagePullSecretsResult) AuthFile() (*os.File, error) {
  function NewImagePullSecretsResult (line 30) | func NewImagePullSecretsResult() *ImagePullSecretsResult {
  function NewImagePullSecretsResultWithDefaults (line 38) | func NewImagePullSecretsResultWithDefaults(defaultImagePullSecrets []reg...
  function NewKubernetesImagePullSecretsProvider (line 74) | func NewKubernetesImagePullSecretsProvider(clientset kubernetes.Interfac...

FILE: pkg/secrets/kubernetes_test.go
  function TestKubernetesCredentialProvider_GetImagePullSecrets (line 47) | func TestKubernetesCredentialProvider_GetImagePullSecrets(t *testing.T) {
  function TestImagePullSecretsResult_WithDefault (line 106) | func TestImagePullSecretsResult_WithDefault(t *testing.T) {
  function TestImagePullSecretsResult_Add (line 134) | func TestImagePullSecretsResult_Add(t *testing.T) {

FILE: pkg/secrets/provider.go
  type ImagePullSecretsProvider (line 10) | type ImagePullSecretsProvider interface

FILE: pkg/types/types.go
  type Registry (line 5) | type Registry
    method String (line 13) | func (p Registry) String() string {
  constant RegistryUnknown (line 8) | RegistryUnknown = iota
  constant RegistryAWS (line 9) | RegistryAWS
  constant RegistryGCP (line 10) | RegistryGCP
  function ParseRegistry (line 17) | func ParseRegistry(p string) (Registry, error) {
  type ImageSwapPolicy (line 27) | type ImageSwapPolicy
    method String (line 34) | func (p ImageSwapPolicy) String() string {
  constant ImageSwapPolicyAlways (line 30) | ImageSwapPolicyAlways = iota
  constant ImageSwapPolicyExists (line 31) | ImageSwapPolicyExists
  function ParseImageSwapPolicy (line 38) | func ParseImageSwapPolicy(p string) (ImageSwapPolicy, error) {
  type ImageCopyPolicy (line 48) | type ImageCopyPolicy
    method String (line 57) | func (p ImageCopyPolicy) String() string {
  constant ImageCopyPolicyDelayed (line 51) | ImageCopyPolicyDelayed = iota
  constant ImageCopyPolicyImmediate (line 52) | ImageCopyPolicyImmediate
  constant ImageCopyPolicyForce (line 53) | ImageCopyPolicyForce
  constant ImageCopyPolicyNone (line 54) | ImageCopyPolicyNone
  function ParseImageCopyPolicy (line 61) | func ParseImageCopyPolicy(p string) (ImageCopyPolicy, error) {

FILE: pkg/types/types_test.go
  function TestParseImageSwapPolicy (line 5) | func TestParseImageSwapPolicy(t *testing.T) {
  function TestParseImageCopyPolicy (line 46) | func TestParseImageCopyPolicy(t *testing.T) {

FILE: pkg/webhook/image_copier.go
  type ImageCopier (line 15) | type ImageCopier struct
    method withDeadline (line 35) | func (ic *ImageCopier) withDeadline() *ImageCopier {
    method start (line 43) | func (ic *ImageCopier) start() {
    method run (line 81) | func (ic *ImageCopier) run(taskFunc func() error) error {
    method taskCheckImage (line 89) | func (ic *ImageCopier) taskCheckImage() error {
    method taskCreateRepository (line 103) | func (ic *ImageCopier) taskCreateRepository() error {
    method taskCopyImage (line 109) | func (ic *ImageCopier) taskCopyImage() error {
  type Task (line 27) | type Task struct

FILE: pkg/webhook/image_copier_test.go
  function TestImageCopier_withDeadline (line 17) | func TestImageCopier_withDeadline(t *testing.T) {
  function TestImageCopier_tasksTimeout (line 50) | func TestImageCopier_tasksTimeout(t *testing.T) {

FILE: pkg/webhook/image_swapper.go
  type Option (line 27) | type Option
  function ImagePullSecretsProvider (line 30) | func ImagePullSecretsProvider(provider secrets.ImagePullSecretsProvider)...
  function Filters (line 37) | func Filters(filters []config.JMESPathFilter) Option {
  function ImageSwapPolicy (line 44) | func ImageSwapPolicy(policy types.ImageSwapPolicy) Option {
  function ImageCopyPolicy (line 51) | func ImageCopyPolicy(policy types.ImageCopyPolicy) Option {
  function ImageCopyDeadline (line 58) | func ImageCopyDeadline(deadline time.Duration) Option {
  function Copier (line 65) | func Copier(pool *pond.WorkerPool) Option {
  type ImageSwapper (line 72) | type ImageSwapper struct
    method Mutate (line 168) | func (p *ImageSwapper) Mutate(ctx context.Context, ar *kwhmodel.Admiss...
    method targetRef (line 306) | func (p *ImageSwapper) targetRef(srcRef ctypes.ImageReference) ctypes....
  function NewImageSwapper (line 89) | func NewImageSwapper(registryClient registry.Client, imagePullSecretProv...
  function NewImageSwapperWithOpts (line 102) | func NewImageSwapperWithOpts(registryClient registry.Client, opts ...Opt...
  function NewImageSwapperWebhookWithOpts (line 123) | func NewImageSwapperWebhookWithOpts(registryClient registry.Client, opts...
  function NewImageSwapperWebhook (line 135) | func NewImageSwapperWebhook(registryClient registry.Client, imagePullSec...
  function imageNamesWithDigestOrTag (line 150) | func imageNamesWithDigestOrTag(imageName string) (string, error) {
  function filterMatch (line 266) | func filterMatch(ctx FilterContext, filters []config.JMESPathFilter) bool {
  type FilterContext (line 318) | type FilterContext struct
  function NewFilterContext (line 326) | func NewFilterContext(request kwhmodel.AdmissionReview, obj metav1.Objec...

FILE: pkg/webhook/image_swapper_test.go
  function TestFilterMatch (line 163) | func TestFilterMatch(t *testing.T) {
  type mockECRClient (line 195) | type mockECRClient struct
    method CreateRepositoryWithContext (line 200) | func (m *mockECRClient) CreateRepositoryWithContext(ctx context.Contex...
  function TestHelperProcess (line 209) | func TestHelperProcess(t *testing.T) {
  function readAdmissionReviewFromFile (line 216) | func readAdmissionReviewFromFile(filename string) (*admissionv1.Admissio...
  function TestImageSwapper_Mutate (line 230) | func TestImageSwapper_Mutate(t *testing.T) {
  function TestImageSwapper_MutateWithImagePullSecrets (line 304) | func TestImageSwapper_MutateWithImagePullSecrets(t *testing.T) {
  function TestImageSwapper_GAR_Mutate (line 396) | func TestImageSwapper_GAR_Mutate(t *testing.T) {

FILE: test/e2e_test.go
  function TestHelmDeployment (line 63) | func TestHelmDeployment(t *testing.T) {
  type sensitiveLogger (line 199) | type sensitiveLogger struct
    method Logf (line 211) | func (l *sensitiveLogger) Logf(t terratesttesting.TestingT, format str...
  function newSensitiveLogger (line 204) | func newSensitiveLogger(logger *logger.Logger, patterns []*regexp.Regexp...
Condensed preview — 62 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (347K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 588,
    "preview": "# These are supported funding model platforms\n\ngithub: [estahn]\npatreon: # Replace with a single Patreon username\nopen_c"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 524,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    target-branch: \"main\"\n    schedule:\n "
  },
  {
    "path": ".github/release-drafter.yml",
    "chars": 1111,
    "preview": "name-template: 'v$RESOLVED_VERSION'\ntag-template: 'v$RESOLVED_VERSION'\ncategories:\n  - title: '🚀 Features'\n    labels:\n "
  },
  {
    "path": ".github/release.yml",
    "chars": 695,
    "preview": "changelog:\n  exclude:\n    labels:\n      - ignore-for-release\n    authors:\n      - octocat\n  categories:\n    - title: 🛠 B"
  },
  {
    "path": ".github/workflows/auto-approve.yml",
    "chars": 301,
    "preview": "name: Auto approve\n\non:\n  pull_request_target\n\njobs:\n  auto-approve:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: h"
  },
  {
    "path": ".github/workflows/auto-merge.yml",
    "chars": 364,
    "preview": "name: Auto-Merge\non: pull_request\n\npermissions:\n  pull-requests: write\n  contents: write\n\njobs:\n  automerge:\n    runs-on"
  },
  {
    "path": ".github/workflows/awaiting-reply.yml",
    "chars": 313,
    "preview": "on:\n  issue_comment:\n    types: [created]\n\njobs:\n  awaiting_reply:\n    runs-on: ubuntu-latest\n    name: Toggle label upo"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 2546,
    "preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 1546,
    "preview": "name: Deploy\n\non:\n  workflow_call:\n    inputs:\n      forRef:\n        required: true\n        type: string\n  workflow_disp"
  },
  {
    "path": ".github/workflows/docs.yml",
    "chars": 816,
    "preview": "#name: Publish docs\n#on:\n#  workflow_dispatch:\n#  push:\n#    branches:\n#      - main\n#    paths:\n#      - 'docs/**'\n#   "
  },
  {
    "path": ".github/workflows/pre-commit.yml",
    "chars": 733,
    "preview": "name: pre-commit\n\non:\n  pull_request:\n  push:\n    branches: [master]\n\njobs:\n  pre-commit:\n    runs-on: ubuntu-latest\n\n  "
  },
  {
    "path": ".github/workflows/release-drafter.yml",
    "chars": 1419,
    "preview": "name: Release Drafter\n\non:\n  workflow_dispatch:\n  push:\n    # branches to consider in the event; optional, defaults to a"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 724,
    "preview": "name: Release\non:\n  workflow_dispatch:\n  # Release patches and secruity updates on a schedule\n  schedule:\n    - cron: \"0"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 3437,
    "preview": "name: Test\non:\n  pull_request:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n      - 'releases/*'\n    paths-ig"
  },
  {
    "path": ".gitignore",
    "chars": 308,
    "preview": "# 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# Ou"
  },
  {
    "path": ".goreleaser.yml",
    "chars": 3349,
    "preview": "env:\n  - GO111MODULE=on\n\ngomod:\n  proxy: true\n\nbuilds:\n  - env:\n      - CGO_ENABLED=0\n    goos:\n      #- windows\n      -"
  },
  {
    "path": ".k8s-image-swapper.yml",
    "chars": 3167,
    "preview": "dryRun: true\n\nlogLevel: trace\nlogFormat: console\n\n# imageSwapPolicy defines the mutation strategy used by the webhook.\n#"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 988,
    "preview": "repos:\n- repo: https://github.com/pre-commit/pre-commit-hooks\n  rev: 38b88246ccc552bffaaf54259d064beeee434539 # v4.0.1\n "
  },
  {
    "path": ".releaserc",
    "chars": 1879,
    "preview": "---\n#verifyConditions: ['@semantic-release/github']\n#prepare: []\n#publish: ['@semantic-release/github']\n#success: ['@sem"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 64442,
    "preview": "## [1.4.0](https://github.com/estahn/k8s-image-swapper/compare/v1.3.3...v1.4.0) (2023-01-01)\n\n\n### :construction_worker:"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5507,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1418,
    "preview": "# Contributing\n\nBy participating to this project, you agree to abide our\n[code of conduct](/CODE_OF_CONDUCT.md).\n\n## Set"
  },
  {
    "path": "Dockerfile",
    "chars": 1620,
    "preview": "#FROM quay.io/skopeo/stable:v1.2.0 AS skopeo\n#FROM gcr.io/distroless/base-debian10\n#FROM debian:10\n#COPY --from=skopeo /"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2020 Enrico Stahn\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "Makefile",
    "chars": 871,
    "preview": "SOURCE_FILES?=./...\nTEST_PATTERN?=.\nTEST_OPTIONS?=\n\n.PHONY: help $(MAKECMDGOALS)\n.DEFAULT_GOAL := help\n\nexport GO111MODU"
  },
  {
    "path": "README.md",
    "chars": 3688,
    "preview": "<p align=\"center\">\n  <img alt=\"Raiders of the Lost Ark\" src=\"docs/img/indiana.gif\" height=\"140\" />\n  <h3 align=\"center\">"
  },
  {
    "path": "cmd/root.go",
    "chars": 10376,
    "preview": "/*\nCopyright © 2020 Enrico Stahn <enrico.stahn@gmail.com>\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "docs/configuration.md",
    "chars": 6168,
    "preview": "# Configuration\n\nThe configuration is managed via the config file `.k8s-image-swapper.yaml`.\nSome options can be overrid"
  },
  {
    "path": "docs/faq.md",
    "chars": 2484,
    "preview": "# FAQ\n\n### Is pulling from private registries supported?\n\nYes, `imagePullSecrets` on `Pod` and `ServiceAccount` level in"
  },
  {
    "path": "docs/getting-started.md",
    "chars": 17067,
    "preview": "# Getting started\n\nThis document will provide guidance for installing `k8s-image-swapper`.\n\n## Prerequisites\n\n`k8s-image"
  },
  {
    "path": "docs/index.md",
    "chars": 1636,
    "preview": "<p align=\"center\">\n  <img alt=\"Raiders of the Lost Ark\" src=\"img/indiana.gif\" height=\"140\" />\n  <h3 align=\"center\">k8s-i"
  },
  {
    "path": "docs/overrides/main.html",
    "chars": 329,
    "preview": "{% extends \"base.html\" %}\n\n{% block outdated %}\n  You're not viewing the latest version.\n  <a href=\"{{ '../' ~ base_url "
  },
  {
    "path": "go.mod",
    "chars": 12689,
    "preview": "module github.com/estahn/k8s-image-swapper\n\ngo 1.24.0\n\nrequire (\n\tcloud.google.com/go/artifactregistry v1.17.1\n\tgithub.c"
  },
  {
    "path": "go.sum",
    "chars": 67578,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.120.0 h1:wc6bg"
  },
  {
    "path": "main.go",
    "chars": 1180,
    "preview": "/*\nCopyright © 2020 Enrico Stahn <enrico.stahn@gmail.com>\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "mkdocs.yml",
    "chars": 3695,
    "preview": "# Project information\nsite_name: k8s-image-swapper\nsite_url: https://estahn.github.io/k8s-image-swapper/\nsite_author: En"
  },
  {
    "path": "package.json",
    "chars": 250,
    "preview": "{\n  \"devDependencies\": {\n    \"@semantic-release/changelog\": \"^6.0.3\",\n    \"@semantic-release/exec\": \"^7.1.0\",\n    \"@sema"
  },
  {
    "path": "pkg/config/config.go",
    "chars": 5492,
    "preview": "/*\nCopyright © 2020 Enrico Stahn <enrico.stahn@gmail.com>\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "pkg/config/config_test.go",
    "chars": 6005,
    "preview": "package config\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/spf13/viper\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// T"
  },
  {
    "path": "pkg/registry/client.go",
    "chars": 1940,
    "preview": "package registry\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/estahn/k8s-image-swapper/"
  },
  {
    "path": "pkg/registry/ecr.go",
    "chars": 9835,
    "preview": "package registry\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os/exec\"\n\t\"time\"\n\n\t\"github.co"
  },
  {
    "path": "pkg/registry/ecr_test.go",
    "chars": 1462,
    "preview": "package registry\n\nimport (\n\t\"encoding/base64\"\n\t\"testing\"\n\n\t\"github.com/containers/image/v5/transports/alltransports\"\n\n\t\""
  },
  {
    "path": "pkg/registry/gar.go",
    "chars": 6055,
    "preview": "package registry\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"ti"
  },
  {
    "path": "pkg/registry/gar_test.go",
    "chars": 953,
    "preview": "package registry\n\nimport (\n\t\"testing\"\n\n\t\"github.com/containers/image/v5/transports/alltransports\"\n\n\t\"github.com/stretchr"
  },
  {
    "path": "pkg/registry/inmemory.go",
    "chars": 17,
    "preview": "package registry\n"
  },
  {
    "path": "pkg/secrets/dummy.go",
    "chars": 743,
    "preview": "package secrets\n\nimport (\n\t\"context\"\n\n\t\"github.com/estahn/k8s-image-swapper/pkg/registry\"\n\tv1 \"k8s.io/api/core/v1\"\n)\n\n//"
  },
  {
    "path": "pkg/secrets/dummy_test.go",
    "chars": 1664,
    "preview": "package secrets\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"testing\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pk"
  },
  {
    "path": "pkg/secrets/kubernetes.go",
    "chars": 3945,
    "preview": "package secrets\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/estahn/k8s-image-swapper/pkg/registry\"\n\tjsonpatch \"githu"
  },
  {
    "path": "pkg/secrets/kubernetes_test.go",
    "chars": 5287,
    "preview": "package secrets\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/estahn/k8s-image-swapper/pkg/con"
  },
  {
    "path": "pkg/secrets/provider.go",
    "chars": 315,
    "preview": "package secrets\n\nimport (\n\t\"context\"\n\n\t\"github.com/estahn/k8s-image-swapper/pkg/registry\"\n\tv1 \"k8s.io/api/core/v1\"\n)\n\nty"
  },
  {
    "path": "pkg/types/types.go",
    "chars": 1848,
    "preview": "package types\n\nimport \"fmt\"\n\ntype Registry int\n\nconst (\n\tRegistryUnknown = iota\n\tRegistryAWS\n\tRegistryGCP\n)\n\nfunc (p Reg"
  },
  {
    "path": "pkg/types/types_test.go",
    "chars": 1914,
    "preview": "package types\n\nimport \"testing\"\n\nfunc TestParseImageSwapPolicy(t *testing.T) {\n\ttype args struct {\n\t\tp string\n\t}\n\ttests "
  },
  {
    "path": "pkg/webhook/image_copier.go",
    "chars": 3838,
    "preview": "package webhook\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"os\"\n\n\t\"github.com/containers/image/v5/docker/reference\"\n\tctypes \"github"
  },
  {
    "path": "pkg/webhook/image_copier_test.go",
    "chars": 3551,
    "preview": "package webhook\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/aws/aws-sdk-go/aws\"\n\t\"github.com/aws/aws-sdk-go/se"
  },
  {
    "path": "pkg/webhook/image_swapper.go",
    "chars": 11234,
    "preview": "package webhook\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/alitto/pond\"\n\t\"github.com/containers/"
  },
  {
    "path": "pkg/webhook/image_swapper_test.go",
    "chars": 14604,
    "preview": "package webhook\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/alitto/pond\"\n\t\"github.com/aws/aws-s"
  },
  {
    "path": "test/curl.sh",
    "chars": 1692,
    "preview": "#!/bin/bash\n\ndata='{\"kind\":\"AdmissionReview\",\"apiVersion\":\"admission.k8s.io/v1\",\"request\":{\"uid\":\"c78e0c58-7389-4838-b4f"
  },
  {
    "path": "test/e2e_test.go",
    "chars": 8790,
    "preview": "//go:build integration\n// +build integration\n\npackage test\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/fil"
  },
  {
    "path": "test/kind-with-registry.sh",
    "chars": 1044,
    "preview": "#!/bin/sh\nset -o errexit\n\n# create registry container unless it already exists\nreg_name='kind-registry'\nreg_port='5000'\n"
  },
  {
    "path": "test/kind.yaml",
    "chars": 898,
    "preview": "---\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n  - |-\n    [plugins.\"io.containerd.grpc.v1"
  },
  {
    "path": "test/requests/admissionreview-imagepullsecrets.json",
    "chars": 2742,
    "preview": "{\n  \"apiVersion\": \"admission.k8s.io/v1\",\n  \"kind\": \"AdmissionReview\",\n  \"request\": {\n    \"dryRun\": false,\n    \"kind\": {\n"
  },
  {
    "path": "test/requests/admissionreview-simple.json",
    "chars": 5112,
    "preview": "{\n  \"apiVersion\": \"admission.k8s.io/v1\",\n  \"kind\": \"AdmissionReview\",\n  \"request\": {\n    \"dryRun\": false,\n    \"kind\": {\n"
  }
]

About this extraction

This page contains the full source code of the estahn/k8s-image-swapper GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 62 files (320.2 KB), approximately 114.6k tokens, and a symbol index with 143 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!