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.
[](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:
[](http://slack.kubernetes.io/)
[](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
[](https://github.com/estahn/k8s-image-swapper/releases/latest)
[](https://artifacthub.io/packages/helm/estahn/k8s-image-swapper)
[](/LICENSE.md)
[](https://codecov.io/gh/estahn/k8s-image-swapper)
[](http://godoc.org/github.com/estahn/k8s-image-swapper)
## :star2: Stargazers over time
[](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>
{ 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

================================================
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
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
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.