Compare commits

...

34 Commits

Author SHA1 Message Date
Maanav Shah f6164cf702 Merge pull request #511 from drone-plugins/CI-21939-fix
feat: [CI-21939]: reverting the changes in docker version
2026-06-04 11:39:54 +05:30
Chirag S f946dac9ae feat: [CI-21939]: reverting changes in the docker version 2026-06-03 10:22:02 +05:30
Maanav Shah 801ca62c15 Merge pull request #509 from maxknee/mk/update-docker
update docker version
2026-05-20 11:12:47 +05:30
dhiraj.chhawchharia@harness.io 95df76b75d Update pipeline drone-docker-harness 2026-05-05 12:23:39 +05:30
dhiraj.chhawchharia@harness.io d9b3767c94 Update pipeline drone-docker-harness 2026-05-05 12:08:01 +05:30
raghav.gupta@harness.io 1482f4d794 Update pipeline drone-docker-harness 2026-05-05 11:27:32 +05:30
Max Knee 19d0d55c04 update docker version
Signed-off-by: Max Knee <max.knee@nytimes.com>
2026-04-07 13:40:36 -04:00
raghav.gupta@harness.io ce792a8072 Update pipeline drone-docker-harness 2026-04-07 16:40:41 +05:30
raghav.gupta@harness.io 33ffeb9986 Update pipeline drone-docker-harness 2026-04-07 16:40:14 +05:30
raghav.gupta@harness.io 0eaa5cb475 Update pipeline drone-docker-harness 2026-04-07 16:27:37 +05:30
raghav.gupta@harness.io 4277ba8a92 Update pipeline drone-docker-harness 2026-04-07 16:27:02 +05:30
raghav.gupta@harness.io a95059bc84 Update pipeline drone-docker-harness 2026-04-07 16:26:36 +05:30
raghav.gupta@harness.io 3ba3d25d31 Update pipeline drone-docker-harness 2026-04-07 16:25:39 +05:30
raghav.gupta@harness.io a6ed4e0fb0 Update pipeline drone-docker-harness 2026-04-07 14:21:04 +05:30
raghav.gupta@harness.io c5bbcaaff5 Update pipeline drone-docker-harness 2026-04-07 14:15:57 +05:30
raghav.gupta@harness.io b5191aec1c Update pipeline drone-docker-harness 2026-04-07 14:15:18 +05:30
raghav.gupta@harness.io 4eeea21716 Update pipeline drone-docker-harness 2026-04-07 14:12:09 +05:30
raghav.gupta@harness.io cff5ad3593 Update pipeline drone-docker-harness 2026-04-07 11:55:40 +05:30
ebtasam-faridy 3209af48cb Merge pull request #508 from drone-plugins/Remove-EoL-Components
fix: [CI-21707]: Remove EoL Components
2026-04-02 15:36:34 +05:30
Gargithakur01 a58ca41cd7 small-fix 2026-04-01 16:20:05 +05:30
Gargithakur01 59d39ec66a Fix discarded error in drone-acr cert setup
Made-with: Cursor
2026-04-01 16:11:23 +05:30
Gargithakur01 d1a514b832 update-go-version-in-yaml 2026-04-01 15:45:00 +05:30
Gargithakur01 fd52c4bfb0 Update pipeline to use golang:1.25.7
Updated all golang images from 1.24.11 and 1.23.0 to 1.25.7 to match the go.mod requirement (go 1.25.7).

Made-with: Cursor
2026-04-01 12:52:00 +05:30
Gargithakur01 f6f31ef8de Merge branch 'master' into Remove-EoL-Components
Resolved conflicts in cmd/drone-ecr/main.go and go.mod:
- Kept slog logging from our branch instead of logrus
- Integrated AWS SDK v2 dependencies from master
- Updated tagExists call to include ctx parameter from master

Made-with: Cursor
2026-03-31 23:03:23 +05:30
Gargithakur01 254f64fc18 fix: [CI-21707]: Remove EoL Components 2026-03-31 22:37:18 +05:30
chhawchharia 2f6803e300 feat: [CI-21342]: Aws migrated and vulnerabilities fixed (#505)
Made-with: Cursor
2026-03-04 11:42:44 +05:30
ebtasam-faridy f5f11face3 Merge pull request #504 from drone-plugins/ci-18951
feat: [CI-18951]: check for HARNESS prefixed proxy variables
2026-02-23 17:07:20 +05:30
Chirag S e70d271e93 feat: [CI-18951]: added a log when harness fallback is used 2026-02-18 10:56:51 +05:30
Chirag S f32aa46ea8 feat: [CI-18951]: added unit tests and better comments for the changes 2026-02-18 10:40:37 +05:30
Chirag S 5810bf8a5a feat: [CI-18951]: check for HARNESS prefixed proxy variables 2026-02-13 14:47:58 +05:30
Anurag Madnawat 23887402c3 [feat]: [CI-20260]: Make daemon retry count configurable (#503) 2026-02-11 11:04:38 +05:30
ebtasam-faridy e9bba4ffcf Update pipeline drone-docker-harness (#502) 2026-01-28 19:07:35 +05:30
ebtasam-faridy 7b900ae75d Ci 20437 (#499)
* fix: [CI-20437] Golang version update for vulnerability fix

* fix: [CI-20437] Golang version update for vulnerability fix
2026-01-28 14:13:48 +05:30
OP (oppenheimer) aabeaaf7bb feat: [CI-20527]: add push-only mode to skip build and push pre-existing images (#500)
* Add push-only support

* Include support for PLUGIN_NO_PUSH as well
2026-01-26 22:55:18 +05:30
12 changed files with 1113 additions and 274 deletions
+30 -30
View File
@@ -12,7 +12,7 @@ platform:
steps: steps:
- name: vet - name: vet
image: golang:1.23 image: golang:1.24.11
commands: commands:
- go vet ./... - go vet ./...
environment: environment:
@@ -22,7 +22,7 @@ steps:
path: /go path: /go
- name: test - name: test
image: golang:1.23 image: golang:1.24.11
commands: commands:
- go test -cover ./... - go test -cover ./...
environment: environment:
@@ -55,7 +55,7 @@ platform:
steps: steps:
- name: go build - name: go build
image: golang:1.23 image: golang:1.24.11
environment: environment:
CGO_ENABLED: 0 CGO_ENABLED: 0
commands: commands:
@@ -162,7 +162,7 @@ platform:
steps: steps:
- name: go build - name: go build
image: golang:1.23 image: golang:1.24.11
environment: environment:
CGO_ENABLED: 0 CGO_ENABLED: 0
commands: commands:
@@ -264,7 +264,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-docker ./cmd/drone-docker' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-docker ./cmd/drone-docker'
environment: environment:
@@ -275,7 +275,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-docker ./cmd/drone-docker' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-docker ./cmd/drone-docker'
environment: environment:
@@ -285,7 +285,7 @@ steps:
- tag - tag
- name: executable - name: executable
image: golang:1.23 image: golang:1.24.11
commands: commands:
- ./release/linux/amd64/drone-docker --help - ./release/linux/amd64/drone-docker --help
@@ -329,7 +329,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-docker ./cmd/drone-docker' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-docker ./cmd/drone-docker'
environment: environment:
@@ -340,7 +340,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-docker ./cmd/drone-docker' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-docker ./cmd/drone-docker'
environment: environment:
@@ -350,7 +350,7 @@ steps:
- tag - tag
- name: executable - name: executable
image: golang:1.23 image: golang:1.24.11
commands: commands:
- ./release/linux/arm64/drone-docker --help - ./release/linux/arm64/drone-docker --help
@@ -429,7 +429,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-gcr ./cmd/drone-gcr' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-gcr ./cmd/drone-gcr'
environment: environment:
@@ -440,7 +440,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-gcr ./cmd/drone-gcr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-gcr ./cmd/drone-gcr'
environment: environment:
@@ -488,7 +488,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-gcr ./cmd/drone-gcr' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-gcr ./cmd/drone-gcr'
environment: environment:
@@ -499,7 +499,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-gcr ./cmd/drone-gcr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-gcr ./cmd/drone-gcr'
environment: environment:
@@ -582,7 +582,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-gar ./cmd/drone-gar' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-gar ./cmd/drone-gar'
environment: environment:
@@ -593,7 +593,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-gar ./cmd/drone-gar' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-gar ./cmd/drone-gar'
environment: environment:
@@ -641,7 +641,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-gar ./cmd/drone-gar' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-gar ./cmd/drone-gar'
environment: environment:
@@ -652,7 +652,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-gar ./cmd/drone-gar' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-gar ./cmd/drone-gar'
environment: environment:
@@ -734,7 +734,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-ecr ./cmd/drone-ecr' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-ecr ./cmd/drone-ecr'
environment: environment:
@@ -744,7 +744,7 @@ steps:
exclude: exclude:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-ecr ./cmd/drone-ecr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-ecr ./cmd/drone-ecr'
environment: environment:
@@ -792,7 +792,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-ecr ./cmd/drone-ecr' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-ecr ./cmd/drone-ecr'
environment: environment:
@@ -802,7 +802,7 @@ steps:
exclude: exclude:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-ecr ./cmd/drone-ecr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-ecr ./cmd/drone-ecr'
environment: environment:
@@ -885,7 +885,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-heroku ./cmd/drone-heroku' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-heroku ./cmd/drone-heroku'
environment: environment:
@@ -895,7 +895,7 @@ steps:
exclude: exclude:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-heroku ./cmd/drone-heroku' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/drone-heroku ./cmd/drone-heroku'
environment: environment:
@@ -944,7 +944,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-heroku ./cmd/drone-heroku' - 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/drone-heroku ./cmd/drone-heroku'
environment: environment:
@@ -954,7 +954,7 @@ steps:
exclude: exclude:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-heroku ./cmd/drone-heroku' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/drone-heroku ./cmd/drone-heroku'
environment: environment:
@@ -1035,7 +1035,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/amd64/drone-acr ./cmd/drone-acr' - 'go build -v -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/amd64/drone-acr ./cmd/drone-acr'
environment: environment:
@@ -1045,7 +1045,7 @@ steps:
exclude: exclude:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/amd64/drone-acr ./cmd/drone-acr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/amd64/drone-acr ./cmd/drone-acr'
environment: environment:
@@ -1093,7 +1093,7 @@ platform:
steps: steps:
- name: build-push - name: build-push
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm64/drone-acr ./cmd/drone-acr' - 'go build -v -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm64/drone-acr ./cmd/drone-acr'
environment: environment:
@@ -1104,7 +1104,7 @@ steps:
- tag - tag
- name: build-tag - name: build-tag
image: golang:1.23 image: golang:1.24.11
commands: commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm64/drone-acr ./cmd/drone-acr' - 'go build -v -ldflags "-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}" -a -tags netgo -o release/linux/arm64/drone-acr ./cmd/drone-acr'
environment: environment:
+445 -4
View File
@@ -33,7 +33,7 @@ pipeline:
identifier: Run_1 identifier: Run_1
spec: spec:
connectorRef: Plugins_Docker_Hub_Connector connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0 image: golang:1.25.7
shell: Sh shell: Sh
command: go vet ./... command: go vet ./...
- step: - step:
@@ -42,7 +42,7 @@ pipeline:
identifier: Run_2 identifier: Run_2
spec: spec:
connectorRef: Plugins_Docker_Hub_Connector connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0 image: golang:1.25.7
shell: Sh shell: Sh
command: go test -cover ./... command: go test -cover ./...
- parallel: - parallel:
@@ -70,7 +70,7 @@ pipeline:
identifier: Build_Push identifier: Build_Push
spec: spec:
connectorRef: Plugins_Docker_Hub_Connector connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0 image: golang:1.25.7
shell: Sh shell: Sh
command: go build -a -tags netgo -o release/linux/amd64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo> command: go build -a -tags netgo -o release/linux/amd64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables: envVariables:
@@ -157,7 +157,7 @@ pipeline:
identifier: buildpush identifier: buildpush
spec: spec:
connectorRef: Plugins_Docker_Hub_Connector connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0 image: golang:1.25.7
shell: Sh shell: Sh
command: go build -a -tags netgo -o release/linux/arm64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo> command: go build -a -tags netgo -o release/linux/arm64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables: envVariables:
@@ -398,6 +398,412 @@ pipeline:
- acr - acr
buildIntelligence: buildIntelligence:
enabled: false enabled: false
- stage:
name: rf-linux-amd64
identifier: rf_linamd64
description: ""
type: CI
spec:
cloneCodebase: true
caching:
enabled: false
paths: []
platform:
os: Linux
arch: Amd64
runtime:
type: Cloud
spec: {}
execution:
steps:
- step:
type: GitClone
name: Clone RF Dockerfiles
identifier: clone_rf
spec:
connectorRef: RapidFortPlugins
build:
type: branch
spec:
branch: main
cloneDirectory: rf-plugins
- step:
type: Run
name: Build Binary
identifier: build_binary
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.25.7
shell: Sh
command: go build -a -tags netgo -o release/linux/amd64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables:
CGO_ENABLED: "0"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
- step:
type: Plugin
name: RF Build and Push on Tag
identifier: rf_docker_build_push_tag
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: plugins/docker
settings:
username: <+secrets.getValue("harnesssecureusername")>
password: <+secrets.getValue("dockerHarnessSecurePwd")>
repo: harnesssecure/<+matrix.repo>
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.linux.amd64.rf
auto_tag: "true"
auto_tag_suffix: linux-amd64
base_image_username: <+secrets.getValue("harness0HARUsername")>
base_image_password: <+secrets.getValue("harness0HARPAT")>
base_image_registry: harness0.harness.io/oci/docker_artifacts
when:
stageStatus: Success
condition: <+codebase.build.type> == "tag"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
- step:
type: BuildAndPushDockerRegistry
name: RF Build and Push on Branch
identifier: rf_build_push_branch
spec:
connectorRef: harnesssecure
repo: harnesssecure/<+matrix.repo>
tags:
- linux-amd64
caching: false
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.linux.amd64.rf
envVariables:
PLUGIN_BASE_IMAGE_USERNAME: <+secrets.getValue("harness0HARUsername")>
PLUGIN_BASE_IMAGE_PASSWORD: <+secrets.getValue("harness0HARPAT")>
PLUGIN_BASE_IMAGE_REGISTRY: harness0.harness.io/oci/docker_artifacts
when:
stageStatus: Success
condition: <+codebase.build.type> == "branch"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
variables:
- name: CI_ENABLE_BARE_METAL
type: String
description: ""
required: false
value: "false"
- stage:
name: rf-linux-arm64
identifier: rf_linarm64
description: ""
type: CI
spec:
cloneCodebase: true
caching:
enabled: false
paths: []
platform:
os: Linux
arch: Arm64
runtime:
type: Cloud
spec: {}
execution:
steps:
- step:
type: GitClone
name: Clone RF Dockerfiles
identifier: clone_rf
spec:
connectorRef: RapidFortPlugins
build:
type: branch
spec:
branch: main
cloneDirectory: rf-plugins
- step:
type: Run
name: Build Binary
identifier: build_binary
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.25.7
shell: Sh
command: go build -a -tags netgo -o release/linux/arm64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables:
CGO_ENABLED: "0"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
- step:
type: Plugin
name: RF Build and Push on Tag
identifier: rf_docker_build_push_tag
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: plugins/docker
settings:
username: <+secrets.getValue("harnesssecureusername")>
password: <+secrets.getValue("dockerHarnessSecurePwd")>
repo: harnesssecure/<+matrix.repo>
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.linux.arm64.rf
auto_tag: "true"
auto_tag_suffix: linux-arm64
base_image_username: <+secrets.getValue("harness0HARUsername")>
base_image_password: <+secrets.getValue("harness0HARPAT")>
base_image_registry: harness0.harness.io/oci/docker_artifacts
when:
stageStatus: Success
condition: <+codebase.build.type> == "tag"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
- step:
type: BuildAndPushDockerRegistry
name: RF Build and Push on Branch
identifier: rf_build_push_branch
spec:
connectorRef: harnesssecure
repo: harnesssecure/<+matrix.repo>
tags:
- linux-arm64
caching: false
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.linux.arm64.rf
envVariables:
PLUGIN_BASE_IMAGE_USERNAME: <+secrets.getValue("harness0HARUsername")>
PLUGIN_BASE_IMAGE_PASSWORD: <+secrets.getValue("harness0HARPAT")>
PLUGIN_BASE_IMAGE_REGISTRY: harness0.harness.io/oci/docker_artifacts
when:
stageStatus: Success
condition: <+codebase.build.type> == "branch"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
variables:
- name: CI_ENABLE_BARE_METAL
type: String
description: ""
required: false
value: "false"
- stage:
name: win-1809-amd64-rf
identifier: win1809amd64rf
description: ""
type: CI
spec:
cloneCodebase: true
caching:
enabled: true
infrastructure:
type: VM
spec:
type: Pool
spec:
poolName: windows-2019
os: Windows
execution:
steps:
- step:
type: GitClone
name: Clone RF Dockerfiles
identifier: Clone_RF_Dockerfiles
spec:
connectorRef: RapidFortPlugins
cloneDirectory: rf-plugins
build:
type: branch
spec:
branch: main
- step:
type: Run
name: Build Binary
identifier: go_build
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0
shell: Sh
command: |-
# disable cgo
export CGO_ENABLED=0
go build -o release/windows/amd64/drone-<+matrix.repo>.exe ./cmd/drone-<+matrix.repo>
strategy:
matrix:
repo:
- docker
- gcr
- gar
- ecr
- acr
- step:
type: Plugin
name: RF Build and Push on Tag
identifier: RF_Build_and_Push_on_Tag
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: plugins/docker
settings:
username: <+secrets.getValue("harnesssecureusername")>
password: <+secrets.getValue("dockerHarnessSecurePwd")>
repo: harnesssecure/<+matrix.repo>
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.windows.amd64.1809.rf
auto_tag: "true"
auto_tag_suffix: windows-1809-amd64
when:
stageStatus: Success
condition: <+codebase.build.type> == "branch"
strategy:
matrix:
repo:
- docker
- gar
- ecr
- acr
- step:
type: BuildAndPushDockerRegistry
name: RF Build and Push on Branch
identifier: rf_build_push_branch
spec:
connectorRef: harnesssecure
repo: harnesssecure/<+matrix.repo>
tags:
- windows-1809-amd64
caching: false
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.windows.amd64.1809.rf
when:
stageStatus: Success
condition: <+codebase.build.type> == "branch"
strategy:
matrix:
repo:
- docker
- gar
- ecr
- acr
delegateSelectors:
- windows-vm
- stage:
name: win-ltsc2022-amd64-rf
identifier: winamd64rf
description: ""
type: CI
spec:
cloneCodebase: true
caching:
enabled: false
paths: []
platform:
os: Windows
arch: Amd64
runtime:
type: Cloud
spec: {}
execution:
steps:
- step:
type: GitClone
name: Clone RF Dockerfiles
identifier: Clone_RF_Dockerfiles
spec:
connectorRef: RapidFortPlugins
cloneDirectory: rf-plugins
build:
type: branch
spec:
branch: main
- step:
type: Run
name: Build Binary -ltsc2022
identifier: build_amd64ltsc2022
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.23.0
shell: Sh
command: |-
# disable cgo
export CGO_ENABLED=0
go build -o release/windows/amd64/drone-<+matrix.repo>.exe ./cmd/drone-<+matrix.repo>
envVariables:
CGO_ENABLED: "0"
strategy:
matrix:
repo:
- docker
- gcr
- gar
- ecr
- acr
- step:
type: Plugin
name: RF Build and Push on Tag
identifier: RF_Build_and_Push_on_Tag
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: plugins/docker
settings:
username: <+secrets.getValue("harnesssecureusername")>
password: <+secrets.getValue("dockerHarnessSecurePwd")>
repo: harnesssecure/<+matrix.repo>
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.windows.amd64.ltsc2022.rf
auto_tag: "true"
auto_tag_suffix: windows-ltsc2022-amd64
when:
stageStatus: Success
condition: <+codebase.build.type> == "tag"
strategy:
matrix:
repo:
- docker
- gar
- ecr
- acr
- step:
type: BuildAndPushDockerRegistry
name: RF Build and Push on Branch
identifier: rf_build_push_branch
spec:
connectorRef: harnesssecure
repo: harnesssecure/<+matrix.repo>
tags:
- windows-ltsc2022-amd64
caching: false
dockerfile: rf-plugins/drone-docker/docker/<+matrix.repo>/Dockerfile.windows.amd64.ltsc2022.rf
when:
stageStatus: Success
condition: <+codebase.build.type> == "branch"
strategy:
matrix:
repo:
- docker
- gar
- ecr
- acr
buildIntelligence:
enabled: false
- stage: - stage:
name: Manifest and Release name: Manifest and Release
identifier: Manifest identifier: Manifest
@@ -410,6 +816,18 @@ pipeline:
paths: [] paths: []
execution: execution:
steps: steps:
- step:
type: GitClone
name: Clone RF Manifest Templates
identifier: clone_rf_manifest
spec:
connectorRef: RapidFortPlugins
build:
type: branch
spec:
branch: main
cloneDirectory: rf-plugins
contextType: Pipeline
- step: - step:
type: Plugin type: Plugin
name: Manifest name: Manifest
@@ -435,6 +853,29 @@ pipeline:
- ecr - ecr
- heroku - heroku
- acr - acr
- step:
type: Plugin
name: RF Manifest
identifier: rf_manifest
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: plugins/manifest
settings:
username: <+secrets.getValue("harnesssecureusername")>
password: <+secrets.getValue("dockerHarnessSecurePwd")>
auto_tag: "true"
ignore_missing: "true"
spec: rf-plugins/drone-docker/docker/<+matrix.repo>/manifest.tmpl
when:
stageStatus: Success
condition: <+codebase.build.type> == "tag"
strategy:
matrix:
repo:
- docker
- acr
- ecr
- gar
platform: platform:
os: Linux os: Linux
arch: Amd64 arch: Amd64
+12 -2
View File
@@ -17,8 +17,14 @@ import (
"github.com/inhies/go-bytesize" "github.com/inhies/go-bytesize"
) )
// writeCard maintains backward compatibility by using TempTag
func (p Plugin) writeCard() error { func (p Plugin) writeCard() error {
cmd := exec.Command(dockerExe, "inspect", p.Build.TempTag) return p.writeCardForImage(p.Build.TempTag)
}
// writeCardForImage generates card for any image reference
func (p Plugin) writeCardForImage(imageRef string) error {
cmd := exec.Command(dockerExe, "inspect", imageRef)
data, err := cmd.CombinedOutput() data, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return err return err
@@ -38,7 +44,11 @@ func (p Plugin) writeCard() error {
for _, tag := range inspect.RepoTags { for _, tag := range inspect.RepoTags {
sliceTagStruct = append(sliceTagStruct, TagStruct{Tag: tag}) sliceTagStruct = append(sliceTagStruct, TagStruct{Tag: tag})
} }
inspect.ParsedRepoTags = sliceTagStruct[1:] // remove the first tag which is always "hash:latest" if len(sliceTagStruct) > 1 {
inspect.ParsedRepoTags = sliceTagStruct[1:] // remove the first tag which is always "hash:latest"
} else {
inspect.ParsedRepoTags = sliceTagStruct
}
// create the url from repo and registry // create the url from repo and registry
inspect.URL = mapRegistryToURL(p.Daemon.Registry, p.Build.Repo) inspect.URL = mapRegistryToURL(p.Daemon.Registry, p.Build.Repo)
cardData, _ := json.Marshal(inspect) cardData, _ := json.Marshal(inspect)
+41 -38
View File
@@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@@ -16,8 +17,6 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
docker "github.com/drone-plugins/drone-docker" docker "github.com/drone-plugins/drone-docker"
azureutil "github.com/drone-plugins/drone-docker/internal/azure" azureutil "github.com/drone-plugins/drone-docker/internal/azure"
@@ -82,14 +81,15 @@ func main() {
if username == "" && password == "" { if username == "" && password == "" {
// docker login credentials are not provided // docker login credentials are not provided
var err error var err error
username = defaultUsername username = defaultUsername
if idToken != "" && clientId != "" && tenantId != "" { if idToken != "" && clientId != "" && tenantId != "" {
logrus.Debug("Using OIDC authentication flow") slog.Debug("using OIDC authentication flow")
var aadToken string var aadToken string
aadToken, err = azureutil.GetAADAccessTokenViaClientAssertion(context.Background(), tenantId, clientId, idToken, authorityHost) aadToken, err = azureutil.GetAADAccessTokenViaClientAssertion(context.Background(), tenantId, clientId, idToken, authorityHost)
if err != nil { if err != nil {
logrus.Fatal(err) slog.Error("failed to get AAD access token", "error", err)
} os.Exit(1)
}
var p string var p string
p, err = getPublicUrl(aadToken, registry, subscriptionId) p, err = getPublicUrl(aadToken, registry, subscriptionId)
if err == nil { if err == nil {
@@ -97,16 +97,18 @@ func main() {
} else { } else {
fmt.Fprintf(os.Stderr, "failed to get public url with error: %s\n", err) fmt.Fprintf(os.Stderr, "failed to get public url with error: %s\n", err)
} }
password, err = fetchACRToken(tenantId, aadToken, registry) password, err = fetchACRToken(tenantId, aadToken, registry)
if err != nil { if err != nil {
logrus.Fatal(err) slog.Error("failed to fetch ACR token", "error", err)
} os.Exit(1)
} else {
password, publicUrl, err = getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, registry)
if err != nil {
logrus.Fatal(err)
}
} }
} else {
password, publicUrl, err = getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, registry)
if err != nil {
slog.Error("failed to get auth", "error", err)
os.Exit(1)
}
}
} }
// must use the fully qualified repo name. If the // must use the fully qualified repo name. If the
@@ -133,7 +135,8 @@ func main() {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
logrus.Fatal(err) slog.Error("command execution failed", "error", err)
os.Exit(1)
} }
} }
@@ -153,26 +156,26 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
if clientCert != "" { if clientCert != "" {
err := setupACRCert(clientCert, acrCertPath) err := setupACRCert(clientCert, acrCertPath)
if err != nil { if err != nil {
errors.Wrap(err, "failed to push setup cert file") slog.Warn("failed to push setup cert file", "error", err)
} }
} }
// Get AZ env // Get AZ env
if err := os.Setenv(clientIdEnv, clientId); err != nil { if err := os.Setenv(clientIdEnv, clientId); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable client Id") return "", "", fmt.Errorf("failed to set env variable client Id: %w", err)
} }
if err := os.Setenv(clientSecretKeyEnv, clientSecret); err != nil { if err := os.Setenv(clientSecretKeyEnv, clientSecret); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable client secret") return "", "", fmt.Errorf("failed to set env variable client secret: %w", err)
} }
if err := os.Setenv(tenantKeyEnv, tenantId); err != nil { if err := os.Setenv(tenantKeyEnv, tenantId); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable tenant Id") return "", "", fmt.Errorf("failed to set env variable tenant Id: %w", err)
} }
if err := os.Setenv(certPathEnv, acrCertPath); err != nil { if err := os.Setenv(certPathEnv, acrCertPath); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable cert path") return "", "", fmt.Errorf("failed to set env variable cert path: %w", err)
} }
env, err := azidentity.NewEnvironmentCredential(nil) env, err := azidentity.NewEnvironmentCredential(nil)
if err != nil { if err != nil {
return "", "", errors.Wrap(err, "failed to get env credentials from azure") return "", "", fmt.Errorf("failed to get env credentials from azure: %w", err)
} }
os.Unsetenv(clientIdEnv) os.Unsetenv(clientIdEnv)
os.Unsetenv(clientSecretKeyEnv) os.Unsetenv(clientSecretKeyEnv)
@@ -185,7 +188,7 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
} }
aadToken, err := env.GetToken(context.Background(), policy) aadToken, err := env.GetToken(context.Background(), policy)
if err != nil { if err != nil {
return "", "", errors.Wrap(err, "failed to fetch access token") return "", "", fmt.Errorf("failed to fetch access token: %w", err)
} }
// Get public URL for artifacts // Get public URL for artifacts
@@ -198,7 +201,7 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
// Fetch token // Fetch token
ACRToken, err := fetchACRToken(tenantId, aadToken.Token, registry) ACRToken, err := fetchACRToken(tenantId, aadToken.Token, registry)
if err != nil { if err != nil {
return "", "", errors.Wrap(err, "failed to fetch ACR token") return "", "", fmt.Errorf("failed to fetch ACR token: %w", err)
} }
return ACRToken, publicUrl, nil return ACRToken, publicUrl, nil
} }
@@ -213,14 +216,14 @@ func fetchACRToken(tenantId, token, registry string) (string, error) {
} }
jsonResponse, err := http.PostForm(fmt.Sprintf("https://%s/oauth2/exchange", registry), formData) jsonResponse, err := http.PostForm(fmt.Sprintf("https://%s/oauth2/exchange", registry), formData)
if err != nil || jsonResponse == nil { if err != nil || jsonResponse == nil {
return "", errors.Wrap(err, "failed to fetch ACR token") return "", fmt.Errorf("failed to fetch ACR token: %w", err)
} }
// fetch token from response // fetch token from response
var response map[string]interface{} var response map[string]interface{}
err = json.NewDecoder(jsonResponse.Body).Decode(&response) err = json.NewDecoder(jsonResponse.Body).Decode(&response)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to decode oauth exchange response") return "", fmt.Errorf("failed to decode oauth exchange response: %w", err)
} }
// Parse the refresh_token from the response // Parse the refresh_token from the response
@@ -228,19 +231,19 @@ func fetchACRToken(tenantId, token, registry string) (string, error) {
if refreshToken, ok := t.(string); ok { if refreshToken, ok := t.(string); ok {
return refreshToken, nil return refreshToken, nil
} }
return "", errors.New("failed to cast refresh token from acr") return "", fmt.Errorf("failed to cast refresh token from acr")
} }
return "", errors.Wrap(err, "refresh token not found in response of oauth exchange call") return "", fmt.Errorf("refresh token not found in response of oauth exchange call: %w", err)
} }
func setupACRCert(cert, certPath string) error { func setupACRCert(cert, certPath string) error {
decoded, err := base64.StdEncoding.DecodeString(cert) decoded, err := base64.StdEncoding.DecodeString(cert)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to base64 decode ACR certificate") return fmt.Errorf("failed to base64 decode ACR certificate: %w", err)
} }
err = ioutil.WriteFile(certPath, decoded, 0644) err = ioutil.WriteFile(certPath, decoded, 0644)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to write ACR certificate") return fmt.Errorf("failed to write ACR certificate: %w", err)
} }
return nil return nil
} }
@@ -262,24 +265,24 @@ func getPublicUrl(token, registryUrl, subscriptionId string) (string, error) {
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return "", errors.Wrap(err, "failed to create request for getting container registry setting") return "", fmt.Errorf("failed to create request for getting container registry setting: %w", err)
} }
req.Header.Add("Authorization", "Bearer "+token) req.Header.Add("Authorization", "Bearer "+token)
res, err := client.Do(req) res, err := client.Do(req)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return "", errors.Wrap(err, "failed to send request for getting container registry setting") return "", fmt.Errorf("failed to send request for getting container registry setting: %w", err)
} }
defer res.Body.Close() defer res.Body.Close()
var response subscriptionUrlResponse var response subscriptionUrlResponse
err = json.NewDecoder(res.Body).Decode(&response) err = json.NewDecoder(res.Body).Decode(&response)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to send request for getting container registry setting") return "", fmt.Errorf("failed to send request for getting container registry setting: %w", err)
} }
if len(response.Value) == 0 { if len(response.Value) == 0 {
return "", errors.New("no id present for base url") return "", fmt.Errorf("no id present for base url")
} }
return basePublicUrl + encodeParam(response.Value[0].ID), nil return basePublicUrl + encodeParam(response.Value[0].ID), nil
} }
+32 -12
View File
@@ -1,13 +1,13 @@
package main package main
import ( import (
"log/slog"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"github.com/dchest/uniuri" "github.com/dchest/uniuri"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
docker "github.com/drone-plugins/drone-docker" docker "github.com/drone-plugins/drone-docker"
@@ -33,7 +33,7 @@ func main() {
cli.BoolFlag{ cli.BoolFlag{
Name: "dry-run", Name: "dry-run",
Usage: "dry run disables docker push", Usage: "dry run disables docker push",
EnvVar: "PLUGIN_DRY_RUN", EnvVar: "PLUGIN_DRY_RUN, PLUGIN_NO_PUSH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "remote.url", Name: "remote.url",
@@ -112,6 +112,12 @@ func main() {
Usage: "don't start the docker daemon", Usage: "don't start the docker daemon",
EnvVar: "PLUGIN_DAEMON_OFF", EnvVar: "PLUGIN_DAEMON_OFF",
}, },
cli.IntFlag{
Name: "daemon.retry-count",
Usage: "number of retry attempts to reach docker daemon",
Value: 15,
EnvVar: "PLUGIN_DAEMON_RETRY_COUNT",
},
cli.StringFlag{ cli.StringFlag{
Name: "dockerfile", Name: "dockerfile",
Usage: "build dockerfile", Usage: "build dockerfile",
@@ -339,10 +345,21 @@ func main() {
Usage: "additional cosign parameters (e.g., annotations, flags)", Usage: "additional cosign parameters (e.g., annotations, flags)",
EnvVar: "PLUGIN_COSIGN_PARAMS", EnvVar: "PLUGIN_COSIGN_PARAMS",
}, },
cli.BoolFlag{
Name: "push-only",
Usage: "skip build and only push images",
EnvVar: "PLUGIN_PUSH_ONLY",
},
cli.StringFlag{
Name: "source-image",
Usage: "source image to tag and push (format: repo:tag)",
EnvVar: "PLUGIN_SOURCE_IMAGE",
},
} }
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
logrus.Fatal(err) slog.Error("application error", "error", err)
os.Exit(1)
} }
} }
@@ -409,6 +426,7 @@ func run(c *cli.Context) error {
DNSSearch: c.StringSlice("daemon.dns-search"), DNSSearch: c.StringSlice("daemon.dns-search"),
MTU: c.String("daemon.mtu"), MTU: c.String("daemon.mtu"),
Experimental: c.Bool("daemon.experimental"), Experimental: c.Bool("daemon.experimental"),
RetryCount: c.Int("daemon.retry-count"),
RegistryType: registryType, RegistryType: registryType,
}, },
BaseImageRegistry: c.String("docker.baseimageregistry"), BaseImageRegistry: c.String("docker.baseimageregistry"),
@@ -419,6 +437,8 @@ func run(c *cli.Context) error {
Password: c.String("cosign.password"), Password: c.String("cosign.password"),
Params: c.String("cosign.params"), Params: c.String("cosign.params"),
}, },
PushOnly: c.Bool("push-only"),
SourceImage: c.String("source-image"),
} }
if c.Bool("tags.auto") { if c.Bool("tags.auto") {
@@ -429,16 +449,16 @@ func run(c *cli.Context) error {
tag, err := docker.DefaultTagSuffix( tag, err := docker.DefaultTagSuffix(
c.String("commit.ref"), c.String("commit.ref"),
c.String("tags.suffix"), c.String("tags.suffix"),
) )
if err != nil { if err != nil {
logrus.Printf("cannot build docker image for %s, invalid semantic version", c.String("commit.ref")) slog.Error("cannot build docker image, invalid semantic version", "commit_ref", c.String("commit.ref"), "error", err)
return err return err
}
plugin.Build.Tags = tag
} else {
logrus.Printf("skipping automated docker build for %s", c.String("commit.ref"))
return nil
} }
plugin.Build.Tags = tag
} else {
slog.Info("skipping automated docker build", "commit_ref", c.String("commit.ref"))
return nil
}
} }
return plugin.Exec() return plugin.Exec()
+101 -99
View File
@@ -1,35 +1,31 @@
package main package main
import ( import (
"context"
"encoding/base64" "encoding/base64"
"errors"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"log/slog"
"os" "os"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/ecr"
ecrtypes "github.com/aws/aws-sdk-go-v2/service/ecr/types"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecr"
docker "github.com/drone-plugins/drone-docker" docker "github.com/drone-plugins/drone-docker"
) )
type ecrAPI interface {
DescribeImages(*ecr.DescribeImagesInput) (*ecr.DescribeImagesOutput, error)
}
const defaultRegion = "us-east-1" const defaultRegion = "us-east-1"
func main() { func main() {
// Load env-file if it exists first
if env := os.Getenv("PLUGIN_ENV_FILE"); env != "" { if env := os.Getenv("PLUGIN_ENV_FILE"); env != "" {
godotenv.Load(env) godotenv.Load(env)
} }
@@ -50,7 +46,6 @@ func main() {
skipPushIfTagExists = parseBoolOrDefault(false, getenv("PLUGIN_SKIP_PUSH_IF_TAG_EXISTS")) skipPushIfTagExists = parseBoolOrDefault(false, getenv("PLUGIN_SKIP_PUSH_IF_TAG_EXISTS"))
) )
// set the region
if region == "" { if region == "" {
region = defaultRegion region = defaultRegion
} }
@@ -62,13 +57,15 @@ func main() {
os.Setenv("AWS_SECRET_ACCESS_KEY", secret) os.Setenv("AWS_SECRET_ACCESS_KEY", secret)
} }
sess, err := session.NewSession(&aws.Config{Region: &region}) ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region))
if err != nil { if err != nil {
log.Fatal(fmt.Sprintf("error creating aws session: %v", err)) log.Fatal(fmt.Sprintf("error creating aws config: %v", err))
} }
svc := getECRClient(sess, assumeRole, externalId, idToken) svc := getECRClient(cfg, assumeRole, externalId, idToken)
username, password, defaultRegistry, err := getAuthInfo(svc) username, password, defaultRegistry, err := getAuthInfo(ctx, svc)
if registry == "" { if registry == "" {
registry = defaultRegistry registry = defaultRegistry
@@ -83,32 +80,32 @@ func main() {
} }
if create { if create {
err = ensureRepoExists(svc, trimHostname(repo, registry), scanOnPush) err = ensureRepoExists(ctx, svc, trimHostname(repo, registry), scanOnPush)
if err != nil { if err != nil {
log.Fatal(fmt.Sprintf("error creating ECR repo: %v", err)) log.Fatal(fmt.Sprintf("error creating ECR repo: %v", err))
} }
err = updateImageScannningConfig(svc, trimHostname(repo, registry), scanOnPush) err = updateImageScanningConfig(ctx, svc, trimHostname(repo, registry), scanOnPush)
if err != nil { if err != nil {
log.Fatal(fmt.Sprintf("error updating scan on push for ECR repo: %v", err)) log.Fatal(fmt.Sprintf("error updating scan on push for ECR repo: %v", err))
} }
} }
if lifecyclePolicy != "" { if lifecyclePolicy != "" {
p, err := ioutil.ReadFile(lifecyclePolicy) p, err := os.ReadFile(lifecyclePolicy)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err := uploadLifeCyclePolicy(svc, string(p), trimHostname(repo, registry)); err != nil { if err := uploadLifeCyclePolicy(ctx, svc, string(p), trimHostname(repo, registry)); err != nil {
log.Fatal(fmt.Sprintf("error uploading ECR lifecycle policy: %v", err)) log.Fatal(fmt.Sprintf("error uploading ECR lifecycle policy: %v", err))
} }
} }
if repositoryPolicy != "" { if repositoryPolicy != "" {
p, err := ioutil.ReadFile(repositoryPolicy) p, err := os.ReadFile(repositoryPolicy)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err := uploadRepositoryPolicy(svc, string(p), trimHostname(repo, registry)); err != nil { if err := uploadRepositoryPolicy(ctx, svc, string(p), trimHostname(repo, registry)); err != nil {
log.Fatal(fmt.Sprintf("error uploading ECR repository policy. %v", err)) log.Fatal(fmt.Sprintf("error uploading ECR repository policy. %v", err))
} }
} }
@@ -119,7 +116,6 @@ func main() {
os.Setenv("DOCKER_PASSWORD", password) os.Setenv("DOCKER_PASSWORD", password)
os.Setenv("PLUGIN_REGISTRY_TYPE", "ECR") os.Setenv("PLUGIN_REGISTRY_TYPE", "ECR")
// Skip if tag already exits for both mutable and immutable repos
if skipPushIfTagExists { if skipPushIfTagExists {
tagInput := getenv("PLUGIN_TAG", "PLUGIN_TAGS") tagInput := getenv("PLUGIN_TAG", "PLUGIN_TAGS")
var tags []string var tags []string
@@ -134,25 +130,26 @@ func main() {
} }
} }
repositoryName := trimHostname(repo, registry) repositoryName := trimHostname(repo, registry)
for _, t := range tags { for _, t := range tags {
exists, err := tagExists(svc, repositoryName, t) exists, err := tagExists(ctx, svc, repositoryName, t)
if err != nil { if err != nil {
logrus.Fatalf("Error checking if image exists for tag %s: %v", t, err) slog.Error("error checking if image exists for tag", "tag", t, "error", err)
} os.Exit(1)
if exists { }
logrus.Infof("%s:%s: Image tag exists. Skipping push.", repo, t) if exists {
os.Exit(0) slog.Info("image tag exists, skipping push", "repo", repo, "tag", t)
} os.Exit(0)
} }
} }
}
// invoke the base docker plugin binary
cmd := exec.Command(docker.GetDroneDockerExecCmd()) cmd := exec.Command(docker.GetDroneDockerExecCmd())
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
if err = cmd.Run(); err != nil { if err = cmd.Run(); err != nil {
logrus.Fatal(err) slog.Error("command execution failed", "error", err)
os.Exit(1)
} }
} }
@@ -162,57 +159,63 @@ func trimHostname(repo, registry string) string {
return repo return repo
} }
func ensureRepoExists(svc *ecr.ECR, name string, scanOnPush bool) (err error) { func ensureRepoExists(ctx context.Context, svc *ecr.Client, name string, scanOnPush bool) error {
input := &ecr.CreateRepositoryInput{} _, err := svc.CreateRepository(ctx, &ecr.CreateRepositoryInput{
input.SetRepositoryName(name) RepositoryName: aws.String(name),
input.SetImageScanningConfiguration(&ecr.ImageScanningConfiguration{ScanOnPush: &scanOnPush}) ImageScanningConfiguration: &ecrtypes.ImageScanningConfiguration{
_, err = svc.CreateRepository(input) ScanOnPush: scanOnPush,
},
})
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ecr.ErrCodeRepositoryAlreadyExistsException { var rae *ecrtypes.RepositoryAlreadyExistsException
// eat it, we skip checking for existing to save two requests if errors.As(err, &rae) {
err = nil return nil
} }
return err
} }
return nil
return
} }
func updateImageScannningConfig(svc *ecr.ECR, name string, scanOnPush bool) (err error) { func updateImageScanningConfig(ctx context.Context, svc *ecr.Client, name string, scanOnPush bool) error {
input := &ecr.PutImageScanningConfigurationInput{} _, err := svc.PutImageScanningConfiguration(ctx, &ecr.PutImageScanningConfigurationInput{
input.SetRepositoryName(name) RepositoryName: aws.String(name),
input.SetImageScanningConfiguration(&ecr.ImageScanningConfiguration{ScanOnPush: &scanOnPush}) ImageScanningConfiguration: &ecrtypes.ImageScanningConfiguration{
_, err = svc.PutImageScanningConfiguration(input) ScanOnPush: scanOnPush,
},
})
return err return err
} }
func uploadLifeCyclePolicy(svc *ecr.ECR, lifecyclePolicy string, name string) (err error) { func uploadLifeCyclePolicy(ctx context.Context, svc *ecr.Client, lifecyclePolicy string, name string) error {
input := &ecr.PutLifecyclePolicyInput{} _, err := svc.PutLifecyclePolicy(ctx, &ecr.PutLifecyclePolicyInput{
input.SetLifecyclePolicyText(lifecyclePolicy) LifecyclePolicyText: aws.String(lifecyclePolicy),
input.SetRepositoryName(name) RepositoryName: aws.String(name),
_, err = svc.PutLifecyclePolicy(input) })
return err return err
} }
func uploadRepositoryPolicy(svc *ecr.ECR, repositoryPolicy string, name string) (err error) { func uploadRepositoryPolicy(ctx context.Context, svc *ecr.Client, repositoryPolicy string, name string) error {
input := &ecr.SetRepositoryPolicyInput{} _, err := svc.SetRepositoryPolicy(ctx, &ecr.SetRepositoryPolicyInput{
input.SetPolicyText(repositoryPolicy) PolicyText: aws.String(repositoryPolicy),
input.SetRepositoryName(name) RepositoryName: aws.String(name),
_, err = svc.SetRepositoryPolicy(input) })
return err return err
} }
func getAuthInfo(svc *ecr.ECR) (username, password, registry string, err error) { func getAuthInfo(ctx context.Context, svc *ecr.Client) (username, password, registry string, err error) {
var result *ecr.GetAuthorizationTokenOutput var result *ecr.GetAuthorizationTokenOutput
var decoded []byte var decoded []byte
result, err = svc.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{}) result, err = svc.GetAuthorizationToken(ctx, &ecr.GetAuthorizationTokenInput{})
if err != nil { if err != nil {
return return
} }
if len(result.AuthorizationData) == 0 {
err = fmt.Errorf("no authorization data returned from ECR")
return
}
auth := result.AuthorizationData[0] auth := result.AuthorizationData[0]
token := *auth.AuthorizationToken token := *auth.AuthorizationToken
decoded, err = base64.StdEncoding.DecodeString(token) decoded, err = base64.StdEncoding.DecodeString(token)
@@ -221,7 +224,11 @@ func getAuthInfo(svc *ecr.ECR) (username, password, registry string, err error)
} }
registry = strings.TrimPrefix(*auth.ProxyEndpoint, "https://") registry = strings.TrimPrefix(*auth.ProxyEndpoint, "https://")
creds := strings.Split(string(decoded), ":") creds := strings.SplitN(string(decoded), ":", 2)
if len(creds) < 2 {
err = fmt.Errorf("invalid ECR authorization token format")
return
}
username = creds[0] username = creds[0]
password = creds[1] password = creds[1]
return return
@@ -233,7 +240,6 @@ func parseBoolOrDefault(defaultValue bool, s string) (result bool) {
if err != nil { if err != nil {
result = defaultValue result = defaultValue
} }
return return
} }
@@ -247,55 +253,51 @@ func getenv(key ...string) (s string) {
return return
} }
func getECRClient(sess *session.Session, role string, externalId string, idToken string) *ecr.ECR { func getECRClient(cfg aws.Config, role string, externalId string, idToken string) *ecr.Client {
if role == "" { if role == "" {
return ecr.New(sess) return ecr.NewFromConfig(cfg)
} }
stsSvc := sts.NewFromConfig(cfg)
if idToken != "" { if idToken != "" {
tempFile, err := os.CreateTemp("/tmp", "idToken-*.jwt") provider := stscreds.NewWebIdentityRoleProvider(stsSvc, role, identityToken(idToken))
if err != nil { cfg.Credentials = aws.NewCredentialsCache(provider)
log.Fatalf("Failed to create temporary file: %v", err) return ecr.NewFromConfig(cfg)
} }
defer tempFile.Close()
if err := os.Chmod(tempFile.Name(), 0600); err != nil { var provider *stscreds.AssumeRoleProvider
log.Fatalf("Failed to set file permissions: %v", err) if externalId != "" {
} provider = stscreds.NewAssumeRoleProvider(stsSvc, role, func(o *stscreds.AssumeRoleOptions) {
o.ExternalID = &externalId
if _, err := tempFile.WriteString(idToken); err != nil {
log.Fatalf("Failed to write ID token to temporary file: %v", err)
}
// Create credentials using the path to the ID token file
creds := stscreds.NewWebIdentityCredentials(sess, role, "", tempFile.Name())
return ecr.New(sess, &aws.Config{Credentials: creds})
} else if externalId != "" {
return ecr.New(sess, &aws.Config{
Credentials: stscreds.NewCredentials(sess, role, func(p *stscreds.AssumeRoleProvider) {
p.ExternalID = &externalId
}),
}) })
} else { } else {
return ecr.New(sess, &aws.Config{ provider = stscreds.NewAssumeRoleProvider(stsSvc, role)
Credentials: stscreds.NewCredentials(sess, role),
})
} }
cfg.Credentials = aws.NewCredentialsCache(provider)
return ecr.NewFromConfig(cfg)
} }
func tagExists(svc ecrAPI, repository, tag string) (bool, error) { func tagExists(ctx context.Context, svc *ecr.Client, repository, tag string) (bool, error) {
input := &ecr.DescribeImagesInput{ input := &ecr.DescribeImagesInput{
RepositoryName: aws.String(repository), RepositoryName: aws.String(repository),
ImageIds: []*ecr.ImageIdentifier{ ImageIds: []ecrtypes.ImageIdentifier{
{ImageTag: aws.String(tag)}, {ImageTag: aws.String(tag)},
}, },
} }
output, err := svc.DescribeImages(input) output, err := svc.DescribeImages(ctx, input)
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "ImageNotFoundException" { var inf *ecrtypes.ImageNotFoundException
if errors.As(err, &inf) {
return false, nil return false, nil
} }
return false, err return false, err
} }
return len(output.ImageDetails) > 0, nil return len(output.ImageDetails) > 0, nil
} }
type identityToken string
func (t identityToken) GetIdentityToken() ([]byte, error) {
return []byte(t), nil
}
+7 -4
View File
@@ -5,6 +5,7 @@ import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"log" "log"
"log/slog"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@@ -15,7 +16,6 @@ import (
"github.com/drone-plugins/drone-docker/internal/gcp" "github.com/drone-plugins/drone-docker/internal/gcp"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
) )
@@ -58,11 +58,13 @@ func loadConfig() Config {
if idToken != "" && projectId != "" && poolId != "" && providerId != "" && serviceAccountEmail != "" { if idToken != "" && projectId != "" && poolId != "" && providerId != "" && serviceAccountEmail != "" {
federalToken, err := gcp.GetFederalToken(idToken, projectId, poolId, providerId) federalToken, err := gcp.GetFederalToken(idToken, projectId, poolId, providerId)
if err != nil { if err != nil {
logrus.Fatalf("Error (getFederalToken): %s", err) slog.Error("getFederalToken error", "error", err)
os.Exit(1)
} }
accessToken, err := gcp.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail) accessToken, err := gcp.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail)
if err != nil { if err != nil {
logrus.Fatalf("Error (getGoogleCloudAccessToken): %s", err) slog.Error("getGoogleCloudAccessToken error", "error", err)
os.Exit(1)
} }
config.AccessToken = accessToken config.AccessToken = accessToken
} else { } else {
@@ -110,7 +112,8 @@ func main() {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
logrus.Fatal(err) slog.Error("command execution failed", "error", err)
os.Exit(1)
} }
} }
+7 -4
View File
@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"log" "log"
"log/slog"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@@ -14,7 +15,6 @@ import (
"github.com/drone-plugins/drone-docker/internal/gcp" "github.com/drone-plugins/drone-docker/internal/gcp"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
) )
@@ -48,11 +48,13 @@ func loadConfig() Config {
if idToken != "" && projectId != "" && poolId != "" && providerId != "" && serviceAccountEmail != "" { if idToken != "" && projectId != "" && poolId != "" && providerId != "" && serviceAccountEmail != "" {
federalToken, err := gcp.GetFederalToken(idToken, projectId, poolId, providerId) federalToken, err := gcp.GetFederalToken(idToken, projectId, poolId, providerId)
if err != nil { if err != nil {
logrus.Fatalf("Error (getFederalToken): %s", err) slog.Error("getFederalToken error", "error", err)
os.Exit(1)
} }
accessToken, err := gcp.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail) accessToken, err := gcp.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail)
if err != nil { if err != nil {
logrus.Fatalf("Error (getGoogleCloudAccessToken): %s", err) slog.Error("getGoogleCloudAccessToken error", "error", err)
os.Exit(1)
} }
config.AccessToken = accessToken config.AccessToken = accessToken
} else { } else {
@@ -103,7 +105,8 @@ func main() {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
logrus.Fatal(err) slog.Error("command execution failed", "error", err)
os.Exit(1)
} }
} }
+215 -8
View File
@@ -30,6 +30,7 @@ type (
MTU string // Docker daemon mtu setting MTU string // Docker daemon mtu setting
IPv6 bool // Docker daemon IPv6 networking IPv6 bool // Docker daemon IPv6 networking
Experimental bool // Docker daemon enable experimental mode Experimental bool // Docker daemon enable experimental mode
RetryCount int // Number of retry attempts to reach Docker daemon
RegistryType drone.RegistryType // Docker registry type RegistryType drone.RegistryType // Docker registry type
} }
@@ -96,6 +97,8 @@ type (
BaseImageRegistry string // Docker registry to pull base image BaseImageRegistry string // Docker registry to pull base image
BaseImageUsername string // Docker registry username to pull base image BaseImageUsername string // Docker registry username to pull base image
BaseImagePassword string // Docker registry password to pull base image BaseImagePassword string // Docker registry password to pull base image
PushOnly bool // Push only mode, skips build process
SourceImage string // Source image to push (optional)
} }
Card []struct { Card []struct {
@@ -135,14 +138,18 @@ func (p Plugin) Exec() error {
// poll the docker daemon until it is started. This ensures the daemon is // poll the docker daemon until it is started. This ensures the daemon is
// ready to accept connections before we proceed. // ready to accept connections before we proceed.
maxRetries := p.Daemon.RetryCount
if maxRetries <= 0 {
maxRetries = 15 // default value
}
for i := 0; ; i++ { for i := 0; ; i++ {
cmd := commandInfo() cmd := commandInfo()
err := cmd.Run() err := cmd.Run()
if err == nil { if err == nil {
break break
} }
if i == 15 { if i == maxRetries {
fmt.Println("Unable to reach Docker Daemon after 15 attempts.") fmt.Printf("Unable to reach Docker Daemon after %d attempts.\n", maxRetries)
break break
} }
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
@@ -201,7 +208,8 @@ func (p Plugin) Exec() error {
fmt.Println(out) fmt.Println(out)
return fmt.Errorf("Error authenticating base connector: exit status 1") return fmt.Errorf("Error authenticating base connector: exit status 1")
} }
} else { } else if !p.PushOnly {
// Skip base image connector warning in push-only mode (not pulling anything)
fmt.Println("\033[33mTo ensure consistent and reliable pipeline execution, we recommend setting up a Base Image Connector.\033[0m\n" + fmt.Println("\033[33mTo ensure consistent and reliable pipeline execution, we recommend setting up a Base Image Connector.\033[0m\n" +
"\033[33mWhile optional at this time, configuring it helps prevent failures caused by Docker Hub's rate limits.\033[0m") "\033[33mWhile optional at this time, configuring it helps prevent failures caused by Docker Hub's rate limits.\033[0m")
} }
@@ -229,6 +237,16 @@ func (p Plugin) Exec() error {
} }
} }
// Enforce mutual exclusivity: push-only and dry-run cannot be used together
if p.PushOnly && p.Dryrun {
return fmt.Errorf("conflict: push-only and dry-run cannot be used together")
}
// Handle push-only mode if requested
if p.PushOnly {
return p.pushOnly()
}
if p.Build.Squash && !p.Daemon.Experimental { if p.Build.Squash && !p.Daemon.Experimental {
fmt.Println("Squash build flag is only available when Docker deamon is started with experimental flag. Ignoring...") fmt.Println("Squash build flag is only available when Docker deamon is started with experimental flag. Ignoring...")
p.Build.Squash = false p.Build.Squash = false
@@ -579,7 +597,8 @@ func addProxyValue(build *Build, key string) {
// helper function to get a proxy value from the environment. // helper function to get a proxy value from the environment.
// //
// assumes that the upper and lower case versions of are the same. // Checks in order: lowercase key, uppercase key, then HARNESS_<UPPERCASE_KEY>.
// Assumes that the upper and lower case versions are the same value.
func getProxyValue(key string) string { func getProxyValue(key string) string {
value := os.Getenv(key) value := os.Getenv(key)
@@ -587,15 +606,26 @@ func getProxyValue(key string) string {
return value return value
} }
return os.Getenv(strings.ToUpper(key)) value = os.Getenv(strings.ToUpper(key))
if len(value) > 0 {
return value
}
harnessValue := os.Getenv("HARNESS_" + strings.ToUpper(key))
if len(harnessValue) > 0 {
fmt.Printf("Using HARNESS_%s as proxy value for %s\n", strings.ToUpper(key), key)
}
return harnessValue
} }
// helper function that looks to see if a proxy value was set in the build args. // helper function that looks to see if a proxy value was set in the build args.
func hasProxyBuildArg(build *Build, key string) bool { func hasProxyBuildArg(build *Build, key string) bool {
keyUpper := strings.ToUpper(key) keyUpper := strings.ToUpper(key)
harnessKey := "HARNESS_" + keyUpper
for _, s := range build.Args { for _, s := range build.Args {
if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) { if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) || strings.HasPrefix(s, harnessKey) {
return true return true
} }
} }
@@ -604,9 +634,10 @@ func hasProxyBuildArg(build *Build, key string) bool {
} }
func hasProxyBuildArgNew(build *Build, key string) bool { func hasProxyBuildArgNew(build *Build, key string) bool {
keyUpper := strings.ToUpper(key) keyUpper := strings.ToUpper(key)
harnessKey := "HARNESS_" + keyUpper
for _, s := range build.ArgsNew { for _, s := range build.ArgsNew {
if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) { if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) || strings.HasPrefix(s, harnessKey) {
return true return true
} }
} }
@@ -742,6 +773,22 @@ func getDigest(buildName string) (string, error) {
return "", errors.New("unable to fetch digest") return "", errors.New("unable to fetch digest")
} }
// imageExists checks if an image exists in local daemon
func imageExists(tag string) bool {
cmd := exec.Command(dockerExe, "image", "inspect", tag)
return cmd.Run() == nil
}
// getDigestAfterPush gets digest from a pushed image
func getDigestAfterPush(tag string) (string, error) {
cmd := exec.Command(dockerExe, "inspect", "--format", "{{ index (split (index .RepoDigests 0) \"@\") 1 }}", tag)
output, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("failed to get digest for %s: %w", tag, err)
}
return strings.TrimSpace(string(output)), nil
}
// shouldSignWithCosign determines if cosign signing should be performed // shouldSignWithCosign determines if cosign signing should be performed
func (p Plugin) shouldSignWithCosign() bool { func (p Plugin) shouldSignWithCosign() bool {
return p.Cosign.PrivateKey != "" return p.Cosign.PrivateKey != ""
@@ -837,7 +884,7 @@ func executeCosignCommand(cmd *exec.Cmd) {
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
fmt.Printf("🚀 Executing: %s %s\n", cmd.Path, strings.Join(cmd.Args[1:], " ")) fmt.Printf("🚀 Executing: %s %s\n", cmd.Path, strings.Join(cmd.Args[1:], " "))
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
fmt.Printf("⚠️ WARNING: Image signing failed: %s\n", err) fmt.Printf("⚠️ WARNING: Image signing failed: %s\n", err)
fmt.Printf(" Image was pushed successfully but could not be signed\n") fmt.Printf(" Image was pushed successfully but could not be signed\n")
@@ -845,4 +892,164 @@ func executeCosignCommand(cmd *exec.Cmd) {
} }
} }
// pushOnly handles pushing images without building them
func (p Plugin) pushOnly() error {
// Check if source image is specified
sourceImageName := p.SourceImage
var sourceTags []string
if sourceImageName == "" {
// If no source image specified, use the repo and first tag
fmt.Println("source_image not provided, using repo and tag value")
sourceImageName = p.Build.Repo
sourceTags = p.Build.Tags
} else {
// If source image is specified, check if it has a tag
lastColonIndex := strings.LastIndex(sourceImageName, ":")
if lastColonIndex > 0 && lastColonIndex < len(sourceImageName) {
// Check if there's a slash after the last colon (indicating it's a port, not a tag)
// For example: registry:5000/image (has slash after colon - port not tag)
// vs image:tag (no slash after colon - it's a tag)
if strings.LastIndex(sourceImageName, "/") > lastColonIndex {
// The last colon is part of the registry:port, not a tag separator
sourceTags = []string{"latest"}
} else {
// The last colon separates the tag
tag := sourceImageName[lastColonIndex+1:]
sourceImageName = sourceImageName[:lastColonIndex]
if tag == "" {
fmt.Printf("No tag specified in source image (or empty tag). Using 'latest' as the default tag.\n")
tag = "latest"
}
sourceTags = []string{tag}
}
} else {
// Default to "latest" if no tag specified
sourceTags = []string{"latest"}
}
fmt.Printf("Using source image: %s with tag(s): %s\n", sourceImageName, strings.Join(sourceTags, ", "))
}
// For each source tag and target tag combination
var digest string
var firstPushedImage string
for _, sourceTag := range sourceTags {
sourceFullImageName := fmt.Sprintf("%s:%s", sourceImageName, sourceTag)
// Check if the source image exists in local daemon
if !imageExists(sourceFullImageName) {
fmt.Printf("Warning: Source image %s not found\n", sourceFullImageName)
// Continue to the next source tag if available, otherwise return error
if len(sourceTags) > 1 {
continue
}
return fmt.Errorf("source image %s not found, cannot push", sourceFullImageName)
}
// For each target tag, tag and push
for _, targetTag := range p.Build.Tags {
targetFullImageName := fmt.Sprintf("%s:%s", p.Build.Repo, targetTag)
// Skip if source and target are identical
if sourceFullImageName == targetFullImageName {
fmt.Printf("Source and target image names are identical: %s\n", sourceFullImageName)
} else {
// Tag the source image with the target name
fmt.Printf("Tagging %s as %s\n", sourceFullImageName, targetFullImageName)
tagCmd := exec.Command(dockerExe, "tag", sourceFullImageName, targetFullImageName)
tagCmd.Stdout = os.Stdout
tagCmd.Stderr = os.Stderr
trace(tagCmd)
if err := tagCmd.Run(); err != nil {
return fmt.Errorf("failed to tag image %s as %s: %w", sourceFullImageName, targetFullImageName, err)
}
}
}
}
// Push all target images
for _, tag := range p.Build.Tags {
fullImageName := fmt.Sprintf("%s:%s", p.Build.Repo, tag)
// Check if image exists in local daemon
if !imageExists(fullImageName) {
return fmt.Errorf("image %s not found, cannot push", fullImageName)
}
// Push image
fmt.Println("Pushing image:", fullImageName)
pushCmd := commandPush(p.Build, tag)
pushCmd.Stdout = os.Stdout
pushCmd.Stderr = os.Stderr
trace(pushCmd)
if err := pushCmd.Run(); err != nil {
return fmt.Errorf("failed to push image %s: %w", fullImageName, err)
}
// Track the first pushed image for card generation
if firstPushedImage == "" {
firstPushedImage = fullImageName
}
// Get the digest after push (we only need one)
if digest == "" {
d, err := getDigestAfterPush(fullImageName)
if err == nil {
digest = d
} else {
fmt.Printf("Warning: Could not get digest for %s: %v\n", fullImageName, err)
}
}
}
// Output the adaptive card
if firstPushedImage != "" {
if err := p.writeCardForImage(firstPushedImage); err != nil {
fmt.Printf("Could not create adaptive card. %s\n", err)
}
}
// Write to artifact file
if p.ArtifactFile != "" && digest != "" {
if err := drone.WritePluginArtifactFile(
p.Daemon.RegistryType,
p.ArtifactFile,
p.Daemon.Registry,
p.Build.Repo,
digest,
p.Build.Tags,
); err != nil {
fmt.Printf("Failed to write plugin artifact file at path: %s with error: %s\n",
p.ArtifactFile, err)
}
}
// Handle cosign signing after push
if p.shouldSignWithCosign() {
// Set up environment variables for cosign
os.Setenv("COSIGN_YES", "true")
if digest != "" {
fmt.Printf("🔐 Found image digest: %s\n", digest)
// Sign with digest reference
imageRef := fmt.Sprintf("%s@%s", p.Build.Repo, digest)
cosignCmd := createCosignCommand(imageRef, p.Cosign)
executeCosignCommand(cosignCmd)
} else {
fmt.Printf("⚠️ WARNING: Could not get image digest for cosign signing\n")
fmt.Printf(" Falling back to tag-based signing\n")
// Fall back to tag-based signing for each tag
for _, tag := range p.Build.Tags {
imageRef := fmt.Sprintf("%s:%s", p.Build.Repo, tag)
cosignCmd := createCosignCommand(imageRef, p.Cosign)
executeCosignCommand(cosignCmd)
}
}
}
return nil
}
+88
View File
@@ -1,6 +1,7 @@
package docker package docker
import ( import (
"os"
"os/exec" "os/exec"
"reflect" "reflect"
"strings" "strings"
@@ -179,3 +180,90 @@ func TestCommandBuild(t *testing.T) {
}) })
} }
} }
func TestGetProxyValue(t *testing.T) {
tests := []struct {
name string
key string
envVars map[string]string
expected string
}{
{
name: "lowercase env var set",
key: "http_proxy",
envVars: map[string]string{"http_proxy": "http://proxy:8080"},
expected: "http://proxy:8080",
},
{
name: "uppercase env var set",
key: "http_proxy",
envVars: map[string]string{"HTTP_PROXY": "http://proxy:8080"},
expected: "http://proxy:8080",
},
{
name: "HARNESS prefixed env var set",
key: "http_proxy",
envVars: map[string]string{"HARNESS_HTTP_PROXY": "http://harness-proxy:8080"},
expected: "http://harness-proxy:8080",
},
{
name: "standard takes precedence over HARNESS",
key: "http_proxy",
envVars: map[string]string{
"HTTP_PROXY": "http://standard:8080",
"HARNESS_HTTP_PROXY": "http://harness:8080",
},
expected: "http://standard:8080",
},
{
name: "lowercase takes precedence over uppercase",
key: "no_proxy",
envVars: map[string]string{
"no_proxy": "localhost,127.0.0.1",
"NO_PROXY": "*.example.com",
"HARNESS_NO_PROXY": "*.local",
},
expected: "localhost,127.0.0.1",
},
{
name: "lowercase takes precedence over HARNESS",
key: "https_proxy",
envVars: map[string]string{
"https_proxy": "https://standard:8080",
"HARNESS_HTTPS_PROXY": "https://harness:8080",
},
expected: "https://standard:8080",
},
{
name: "no env var set",
key: "http_proxy",
envVars: map[string]string{},
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Clean env
lowercaseKey := tt.key
uppercaseKey := strings.ToUpper(tt.key)
harnessKey := "HARNESS_" + strings.ToUpper(tt.key)
os.Unsetenv(lowercaseKey)
os.Unsetenv(uppercaseKey)
os.Unsetenv(harnessKey)
// Set test environment variables
for k, v := range tt.envVars {
os.Setenv(k, v)
defer os.Unsetenv(k)
}
// Execute and verify
result := getProxyValue(tt.key)
if result != tt.expected {
t.Errorf("getProxyValue(%q) = %q, want %q", tt.key, result, tt.expected)
}
})
}
}
+41 -21
View File
@@ -3,51 +3,71 @@ module github.com/drone-plugins/drone-docker
require ( require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2
github.com/aws/aws-sdk-go v1.26.7 github.com/aws/aws-sdk-go-v2 v1.41.2
github.com/aws/aws-sdk-go-v2/config v1.32.10
github.com/aws/aws-sdk-go-v2/credentials v1.19.10
github.com/aws/aws-sdk-go-v2/service/ecr v1.55.3
github.com/aws/aws-sdk-go-v2/service/sts v1.41.7
github.com/coreos/go-semver v0.3.0 github.com/coreos/go-semver v0.3.0
github.com/dchest/uniuri v1.2.0 github.com/dchest/uniuri v1.2.0
github.com/drone-plugins/drone-plugin-lib v0.4.1 github.com/drone-plugins/drone-plugin-lib v0.4.1
github.com/drone/drone-go v1.7.1 github.com/drone/drone-go v1.7.1
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.11.1
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.10.0
github.com/urfave/cli v1.22.2 github.com/urfave/cli v1.22.2
golang.org/x/oauth2 v0.27.0 golang.org/x/oauth2 v0.34.0
google.golang.org/api v0.146.0 google.golang.org/api v0.187.0
) )
require ( require (
cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/auth v0.6.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect
github.com/aws/smithy-go v1.24.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/googleapis/gax-go/v2 v2.12.5 // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.36.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
golang.org/x/net v0.37.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
golang.org/x/sys v0.31.0 // indirect go.opentelemetry.io/otel v1.39.0 // indirect
golang.org/x/text v0.23.0 // indirect go.opentelemetry.io/otel/metric v1.39.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect
google.golang.org/grpc v1.59.0 // indirect golang.org/x/crypto v0.46.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // 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/yaml.v2 v2.2.8 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )
go 1.23.0 go 1.25.7
toolchain go1.23.7
+94 -52
View File
@@ -1,6 +1,10 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/auth v0.6.1 h1:T0Zw1XM5c1GlpN2HYr2s+m3vr1p2wy+8VN+Z1FKxW38=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/auth v0.6.1/go.mod h1:eFHG7zDzbXHKmjJddFG/rBlcGp6t25SwRUiEQSlO4x4=
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY= github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1 h1:DSDNVxqkoXJiko6x8a90zidoYqnYYa6c1MTzDKzKkTo= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1 h1:DSDNVxqkoXJiko6x8a90zidoYqnYYa6c1MTzDKzKkTo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1/go.mod h1:zGqV2R4Cr/k8Uye5w+dgQ06WJtEcbQG/8J7BB6hnCr4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1/go.mod h1:zGqV2R4Cr/k8Uye5w+dgQ06WJtEcbQG/8J7BB6hnCr4=
@@ -15,8 +19,36 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mo
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4=
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aws/aws-sdk-go v1.26.7 h1:ObjEnmzvSdYy8KVd3me7v/UMyCn81inLy2SyoIPoBkg= github.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls=
github.com/aws/aws-sdk-go v1.26.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4=
github.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI=
github.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw=
github.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8=
github.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/service/ecr v1.55.3 h1:RtGctYMmkTerGClvdY6bHXdtly4FeYw9wz/NPz62LF8=
github.com/aws/aws-sdk-go-v2/service/ecr v1.55.3/go.mod h1:vBfBu24Ka3/5UZtepbTV0gnc9VPLT8ok+0oDDaYAzn4=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.11/go.mod h1:0DO9B5EUJQlIDif+XJRWCljZRKsAFKh3gpFz7UnDtOo=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 h1:edCcNp9eGIUDUCrzoCu1jWAXLGFIizeqkdkKgRlJwWc=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15/go.mod h1:lyRQKED9xWfgkYC/wmmYfv7iVIM68Z5OQ88ZdcV1QbU=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 h1:NITQpgo9A5NrDZ57uOWj+abvXSb83BbyggcUBVksN7c=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.7/go.mod h1:sks5UWBhEuWYDPdwlnRFn1w7xWdH29Jcpe+/PJQefEs=
github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0=
github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 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 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -42,6 +74,13 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
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.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.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
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/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -58,31 +97,27 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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.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.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.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.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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 h1:X3Xxno5Ji8idrNiUoFc7QyXpqhSYlDRYQmc7mlpMBzU= github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 h1:X3Xxno5Ji8idrNiUoFc7QyXpqhSYlDRYQmc7mlpMBzU=
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs= github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
@@ -95,38 +130,47 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -137,54 +181,54 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.146.0 h1:9aBYT4vQXt9dhCuLNfwfd3zpwu8atg0yPkjBymwSrOM= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
google.golang.org/api v0.146.0/go.mod h1:OARJqIfoYjXJj4C1AiBSXYZt03qsoz8FQYU6fBEfrHM= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.187.0 h1:Mxs7VATVC2v7CY+7Xwm4ndkX71hpElcvx0D1Ji/p1eo=
google.golang.org/api v0.187.0/go.mod h1:KIHlTc4x7N7gKKuVsdmfBXN13yEEWXWFURWY6SBp2gk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a h1:fwgW9j3vHirt4ObdHoYNwuO24BEZjSzbh+zPaNWoiY8= google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls=
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -194,10 +238,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=