mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-25 12:08:46 +01:00
Compare commits
317 Commits
bump-major
...
appsetdocs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37efa1880b | ||
|
|
83257a9e73 | ||
|
|
cae840bb13 | ||
|
|
8d12e352f4 | ||
|
|
d54ae98b20 | ||
|
|
12928cbdcc | ||
|
|
9c443b6501 | ||
|
|
a45f715763 | ||
|
|
335b65baf8 | ||
|
|
f27515783a | ||
|
|
2afcb6f107 | ||
|
|
05a9171b42 | ||
|
|
ac50d8e1c1 | ||
|
|
f775e7bf28 | ||
|
|
fa0b5f56ab | ||
|
|
43e5941042 | ||
|
|
2168221092 | ||
|
|
64569e61a1 | ||
|
|
cca7485917 | ||
|
|
74b35322a2 | ||
|
|
0ed7c5618f | ||
|
|
42219fd7b7 | ||
|
|
111cf2ce9f | ||
|
|
d301b40c6b | ||
|
|
e3bd56972d | ||
|
|
922d080ae5 | ||
|
|
bd1018af5e | ||
|
|
76dbaaa3e0 | ||
|
|
376e8d5260 | ||
|
|
627da11384 | ||
|
|
75cb7fc42d | ||
|
|
a8f646e430 | ||
|
|
4202168c44 | ||
|
|
e3b333a860 | ||
|
|
cb135fdd0d | ||
|
|
3c3410cf5d | ||
|
|
5e9fc55783 | ||
|
|
9d66e89d14 | ||
|
|
14a09be652 | ||
|
|
fbd7f29056 | ||
|
|
2cefcc5a36 | ||
|
|
683e4e0d95 | ||
|
|
8d1aeb58a2 | ||
|
|
4c27f73559 | ||
|
|
dc3286730a | ||
|
|
62ec9fef36 | ||
|
|
a8b76f2951 | ||
|
|
8a752a56d6 | ||
|
|
4f179a192d | ||
|
|
270b352cbd | ||
|
|
2d994038be | ||
|
|
753f7b6e72 | ||
|
|
6959e54f06 | ||
|
|
7327093b66 | ||
|
|
74582e9965 | ||
|
|
29c69b3601 | ||
|
|
546383a8e5 | ||
|
|
0444fcdf37 | ||
|
|
527ef92c30 | ||
|
|
2731c3f18d | ||
|
|
9783c5ea24 | ||
|
|
db82e23ebb | ||
|
|
04a1608643 | ||
|
|
6b002a5106 | ||
|
|
5223ce546a | ||
|
|
95a43e0416 | ||
|
|
c6b00007f2 | ||
|
|
eb6732ec9e | ||
|
|
0b0c737af0 | ||
|
|
c0b278738c | ||
|
|
029927b25e | ||
|
|
f2490fccdd | ||
|
|
898a126f10 | ||
|
|
bfb04ddf3e | ||
|
|
416b7d0c32 | ||
|
|
561cbef5cc | ||
|
|
2bcaa19894 | ||
|
|
228b86d3b5 | ||
|
|
f542ae5158 | ||
|
|
c71dd1a9e6 | ||
|
|
f2c5093013 | ||
|
|
21ea59d600 | ||
|
|
e2e6faa3b5 | ||
|
|
42fa72d499 | ||
|
|
6f9389c2ea | ||
|
|
98cd061ac9 | ||
|
|
b9131c1802 | ||
|
|
e6f94f227c | ||
|
|
74244323f8 | ||
|
|
e38c7ae00f | ||
|
|
261137df9d | ||
|
|
c47152d017 | ||
|
|
7c7dda0e93 | ||
|
|
806c5f6b6d | ||
|
|
795bda5dd8 | ||
|
|
499f74dc27 | ||
|
|
c4183aad76 | ||
|
|
3f74b24c0a | ||
|
|
1905d127a5 | ||
|
|
07da3d41da | ||
|
|
cbef55e566 | ||
|
|
c6757573ae | ||
|
|
2b1220c600 | ||
|
|
edbce2a524 | ||
|
|
55f8a434d0 | ||
|
|
8a97c1d138 | ||
|
|
35009a7d1c | ||
|
|
94b34f88ec | ||
|
|
ce819128f9 | ||
|
|
e6e9255216 | ||
|
|
c09e6fa6ad | ||
|
|
3baca9b696 | ||
|
|
961147d387 | ||
|
|
686964daaa | ||
|
|
b88ad57986 | ||
|
|
975e966e26 | ||
|
|
49a4b7f14f | ||
|
|
644af54a7c | ||
|
|
c897e944db | ||
|
|
94d3899038 | ||
|
|
1823d8fcd2 | ||
|
|
402802b089 | ||
|
|
e784c47667 | ||
|
|
e44ae96c07 | ||
|
|
be293fe9ed | ||
|
|
e18b4d7ac8 | ||
|
|
f32f69f7d2 | ||
|
|
846503bb0e | ||
|
|
f63f5f954e | ||
|
|
8044d68492 | ||
|
|
33ad0a7ba7 | ||
|
|
0dddb9e6c8 | ||
|
|
562fa065c6 | ||
|
|
ecee599640 | ||
|
|
38b0fd5cd4 | ||
|
|
87671f55c5 | ||
|
|
1f1c33983b | ||
|
|
ee83eea784 | ||
|
|
9e6b28b8a2 | ||
|
|
84b49c84ca | ||
|
|
6c64d5ff55 | ||
|
|
7b1ed5218a | ||
|
|
079341c65c | ||
|
|
9f81cd4798 | ||
|
|
37aaeb3dd9 | ||
|
|
7870200461 | ||
|
|
167e122eba | ||
|
|
a1431bef4c | ||
|
|
073ccf7c35 | ||
|
|
feb7097fc9 | ||
|
|
976a8498d4 | ||
|
|
36d563a3c2 | ||
|
|
944f9f7b68 | ||
|
|
f78c7ee2ba | ||
|
|
c1b2f78f46 | ||
|
|
38c2b34da0 | ||
|
|
2e1db11ad9 | ||
|
|
ab05f35507 | ||
|
|
b3bf182a65 | ||
|
|
563ccb20c7 | ||
|
|
ca9da799d8 | ||
|
|
50fb7bcd21 | ||
|
|
eb6dd46e19 | ||
|
|
e14d6b7bf9 | ||
|
|
6daaac5924 | ||
|
|
65664ce5f3 | ||
|
|
8a447d9ae0 | ||
|
|
951d9d3f17 | ||
|
|
967126860c | ||
|
|
d19b02dcd0 | ||
|
|
d183d9c614 | ||
|
|
b600c5ec7d | ||
|
|
8e91ce9b2b | ||
|
|
8507a87bfa | ||
|
|
4e2902d972 | ||
|
|
928fd19593 | ||
|
|
5b79c34c72 | ||
|
|
0973409273 | ||
|
|
922dd771e3 | ||
|
|
4a1d0f3af5 | ||
|
|
d1574c204f | ||
|
|
4dcabb933e | ||
|
|
fa747f987c | ||
|
|
71c7700f2e | ||
|
|
7efd2fe2eb | ||
|
|
43822815f7 | ||
|
|
911a9c6776 | ||
|
|
73c3935031 | ||
|
|
4641e802a4 | ||
|
|
4b087089fb | ||
|
|
7d0c10e0d2 | ||
|
|
9843bfbdf8 | ||
|
|
5d147a3ae6 | ||
|
|
68d60cd092 | ||
|
|
99cd3c7650 | ||
|
|
622847bcb5 | ||
|
|
ad09b9c744 | ||
|
|
47bec8b438 | ||
|
|
95b8a4ab0b | ||
|
|
c32afb4ee2 | ||
|
|
c9c40684b7 | ||
|
|
9a3cfcb71d | ||
|
|
1b1735f5f0 | ||
|
|
854c62fc70 | ||
|
|
b4753d8d00 | ||
|
|
1d47e1c7eb | ||
|
|
88e43cb730 | ||
|
|
045a027753 | ||
|
|
b4a63aeba8 | ||
|
|
b17c5e4e2a | ||
|
|
7edaef54d4 | ||
|
|
85c6d267ba | ||
|
|
40d86e7b18 | ||
|
|
6f5537bdf1 | ||
|
|
e4311d8309 | ||
|
|
e147247aaf | ||
|
|
b9f49df757 | ||
|
|
eb8f05a9fd | ||
|
|
4e08b8dee6 | ||
|
|
7333c75327 | ||
|
|
5e5ec1b021 | ||
|
|
e8a3f7aa33 | ||
|
|
ecb9dbac42 | ||
|
|
1698370363 | ||
|
|
e3bcc48bf2 | ||
|
|
544aea18c3 | ||
|
|
75def4f2df | ||
|
|
c7e02eefdd | ||
|
|
bd9923fd75 | ||
|
|
bcf2143dfe | ||
|
|
770664411a | ||
|
|
cdb7995693 | ||
|
|
3593f24491 | ||
|
|
24893ad5e9 | ||
|
|
bf082c26c2 | ||
|
|
8f285a5dd4 | ||
|
|
35a174b956 | ||
|
|
85684a8919 | ||
|
|
27915da5b0 | ||
|
|
2cfaab335f | ||
|
|
f9ffb6ae35 | ||
|
|
91cb693164 | ||
|
|
5ef4faa8a4 | ||
|
|
f258c450b8 | ||
|
|
eed70eed6e | ||
|
|
55aab6efb6 | ||
|
|
9b91454968 | ||
|
|
9429275a91 | ||
|
|
ed3cc48847 | ||
|
|
87539aa558 | ||
|
|
c687247ce8 | ||
|
|
6f38327647 | ||
|
|
e3caebae56 | ||
|
|
7ba7fc028e | ||
|
|
1a56ea7417 | ||
|
|
9fd6beea7f | ||
|
|
3a29a745a3 | ||
|
|
606bd5b043 | ||
|
|
89c4817213 | ||
|
|
c93924b3cc | ||
|
|
f3509d2f8a | ||
|
|
3e09f946f4 | ||
|
|
d765aabc1f | ||
|
|
070287cecc | ||
|
|
d4d671316f | ||
|
|
dbf9393365 | ||
|
|
780285b86e | ||
|
|
11b866578f | ||
|
|
9b17495bc2 | ||
|
|
f548fd7a24 | ||
|
|
1ce0123fa5 | ||
|
|
3f0a1552e6 | ||
|
|
742d45a1f5 | ||
|
|
219444313a | ||
|
|
901139795d | ||
|
|
37a7231bd3 | ||
|
|
9a02f9bc2e | ||
|
|
e852142fb9 | ||
|
|
922c9e9ccc | ||
|
|
72962014b5 | ||
|
|
d23e6ac79b | ||
|
|
9a51757049 | ||
|
|
c3600d240a | ||
|
|
b77d9d9f5f | ||
|
|
2f579404f6 | ||
|
|
5d84eb4ff3 | ||
|
|
d3dda53cf6 | ||
|
|
613d06d0b1 | ||
|
|
ced84418d3 | ||
|
|
bd37458896 | ||
|
|
f6a84a470d | ||
|
|
dbdc1e737a | ||
|
|
fdf9a305b3 | ||
|
|
5207508871 | ||
|
|
2d10d4e785 | ||
|
|
4d9835927d | ||
|
|
1645d576fd | ||
|
|
77ff8f0dd4 | ||
|
|
b8508f2916 | ||
|
|
6d27928965 | ||
|
|
6c45721730 | ||
|
|
2a497ef1fd | ||
|
|
871ed62000 | ||
|
|
1a9f22625d | ||
|
|
06bd2ad10f | ||
|
|
05c76253f0 | ||
|
|
fe8bab0406 | ||
|
|
77ad48aa09 | ||
|
|
4fee6b51e0 | ||
|
|
a807c0eb69 | ||
|
|
947a7b84d7 | ||
|
|
53bc19b5f2 | ||
|
|
b04a7c101d | ||
|
|
50c49ec8f9 | ||
|
|
f39b425fac | ||
|
|
cce74a33e1 | ||
|
|
c739478b8b |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -5,9 +5,14 @@ docs/operator-manual/resource_actions_builtin.md linguist-generated=true
|
||||
docs/operator-manual/server-commands/argocd-*.md linguist-generated=true
|
||||
docs/user-guide/commands/argocd_*.md linguist-generated=true
|
||||
manifests/core-install.yaml linguist-generated=true
|
||||
manifests/core-install-with-hydrator.yaml linguist-generated=true
|
||||
manifests/crds/*-crd.yaml linguist-generated=true
|
||||
manifests/ha/install.yaml linguist-generated=true
|
||||
manifests/ha/install-with-hydrator.yaml linguist-generated=true
|
||||
manifests/ha/namespace-install.yaml linguist-generated=true
|
||||
manifests/ha/namespace-install-with-hydrator.yaml linguist-generated=true
|
||||
manifests/install.yaml linguist-generated=true
|
||||
manifests/install-with-hydrator.yaml linguist-generated=true
|
||||
manifests/namespace-install.yaml linguist-generated=true
|
||||
manifests/namespace-install-with-hydrator.yaml linguist-generated=true
|
||||
pkg/apis/api-rules/violation_exceptions.list linguist-generated=true
|
||||
|
||||
45
.github/workflows/bump-major-version.yaml
vendored
45
.github/workflows/bump-major-version.yaml
vendored
@@ -26,9 +26,52 @@ jobs:
|
||||
CURRENT_VERSION=$(grep 'module github.com/argoproj/argo-cd' go.mod | awk '{print $2}' | sed 's/.*\/v//')
|
||||
echo "TARGET_VERSION=$((CURRENT_VERSION + 1))" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Copy source code to GOPATH
|
||||
run: |
|
||||
mkdir -p ~/go/src/github.com/argoproj
|
||||
cp -a ../argo-cd ~/go/src/github.com/argoproj
|
||||
|
||||
- name: Run script to bump the version
|
||||
run: |
|
||||
hack/bump-major-version.sh
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Add ~/go/bin to PATH
|
||||
run: |
|
||||
echo "/home/runner/go/bin" >> $GITHUB_PATH
|
||||
- name: Add /usr/local/bin to PATH
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Download & vendor dependencies
|
||||
run: |
|
||||
# We need to vendor go modules for codegen yet
|
||||
go mod download
|
||||
go mod vendor -v
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
|
||||
- name: Install toolchain for codegen
|
||||
run: |
|
||||
make install-codegen-tools-local
|
||||
make install-go-tools-local
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
|
||||
# We install kustomize in the dist directory
|
||||
- name: Add dist to PATH
|
||||
run: |
|
||||
echo "/home/runner/work/argo-cd/argo-cd/dist" >> $GITHUB_PATH
|
||||
- name: Run codegen
|
||||
run: |
|
||||
set -x
|
||||
export GOPATH=$(go env GOPATH)
|
||||
make codegen-local
|
||||
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
|
||||
|
||||
- name: Copy changes back
|
||||
run: |
|
||||
# Copy the contents back, but skip the .git directory
|
||||
rsync -a --exclude=.git /home/runner/go/src/github.com/argoproj/argo-cd/ ../argo-cd
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
|
||||
@@ -43,4 +86,4 @@ jobs:
|
||||
- [ ] Add an upgrade guide to the docs for this version
|
||||
branch: bump-major-version
|
||||
branch-suffix: random
|
||||
signoff: true
|
||||
signoff: true
|
||||
41
.github/workflows/ci-build.yaml
vendored
41
.github/workflows/ci-build.yaml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
env:
|
||||
# Golang version to use across CI steps
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.23.3'
|
||||
GOLANG_VERSION: '1.24.1'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
files_yaml: |
|
||||
backend:
|
||||
- '!ui/**'
|
||||
- '!**.md'
|
||||
- '!**.md'
|
||||
- '!**/*.md'
|
||||
- '!docs/**'
|
||||
frontend:
|
||||
@@ -94,8 +94,8 @@ jobs:
|
||||
|
||||
lint-go:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
name: Lint Go code
|
||||
if: ${{ needs.changes.outputs.backend == 'true' }}
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -112,7 +112,7 @@ jobs:
|
||||
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
|
||||
with:
|
||||
# renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
|
||||
version: v1.63.4
|
||||
version: v1.64.7
|
||||
args: --verbose
|
||||
|
||||
test-go:
|
||||
@@ -402,30 +402,31 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# latest: true means that this version mush upload the coverage report to codecov.io
|
||||
# We designate the latest version because we only collect code coverage for that version.
|
||||
k3s:
|
||||
- version: v1.31.0
|
||||
# We designate the latest version because we only collect code coverage for that version.
|
||||
- version: v1.32.1
|
||||
latest: true
|
||||
- version: v1.31.0
|
||||
latest: false
|
||||
- version: v1.30.4
|
||||
latest: false
|
||||
- version: v1.29.8
|
||||
latest: false
|
||||
- version: v1.28.13
|
||||
latest: false
|
||||
needs:
|
||||
- build-go
|
||||
- changes
|
||||
env:
|
||||
GOPATH: /home/runner/go
|
||||
ARGOCD_FAKE_IN_CLUSTER: "true"
|
||||
ARGOCD_SSH_DATA_PATH: "/tmp/argo-e2e/app/config/ssh"
|
||||
ARGOCD_TLS_DATA_PATH: "/tmp/argo-e2e/app/config/tls"
|
||||
ARGOCD_E2E_SSH_KNOWN_HOSTS: "../fixture/certs/ssh_known_hosts"
|
||||
ARGOCD_E2E_K3S: "true"
|
||||
ARGOCD_IN_CI: "true"
|
||||
ARGOCD_E2E_APISERVER_PORT: "8088"
|
||||
ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external,argocd-e2e-external-2"
|
||||
ARGOCD_SERVER: "127.0.0.1:8088"
|
||||
ARGOCD_FAKE_IN_CLUSTER: 'true'
|
||||
ARGOCD_SSH_DATA_PATH: '/tmp/argo-e2e/app/config/ssh'
|
||||
ARGOCD_TLS_DATA_PATH: '/tmp/argo-e2e/app/config/tls'
|
||||
ARGOCD_E2E_SSH_KNOWN_HOSTS: '../fixture/certs/ssh_known_hosts'
|
||||
ARGOCD_E2E_K3S: 'true'
|
||||
ARGOCD_IN_CI: 'true'
|
||||
ARGOCD_E2E_APISERVER_PORT: '8088'
|
||||
ARGOCD_APPLICATION_NAMESPACES: 'argocd-e2e-external,argocd-e2e-external-2'
|
||||
ARGOCD_SERVER: '127.0.0.1:8088'
|
||||
GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }}
|
||||
steps:
|
||||
@@ -486,7 +487,7 @@ jobs:
|
||||
run: |
|
||||
docker pull ghcr.io/dexidp/dex:v2.41.1
|
||||
docker pull argoproj/argo-cd-ci-builder:v1.0.0
|
||||
docker pull redis:7.0.15-alpine
|
||||
docker pull redis:7.2.7-alpine
|
||||
- name: Create target directory for binaries in the build-process
|
||||
run: |
|
||||
mkdir -p dist
|
||||
@@ -549,4 +550,4 @@ jobs:
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
15
.github/workflows/image.yaml
vendored
15
.github/workflows/image.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types: [ labeled, unlabeled, opened, synchronize, reopened ]
|
||||
types: [labeled, unlabeled, opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -46,14 +46,14 @@ jobs:
|
||||
needs: [set-vars]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name != 'push' }}
|
||||
uses: ./.github/workflows/image-reuse.yaml
|
||||
with:
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.23.3
|
||||
go-version: 1.24.1
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: false
|
||||
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
needs: [set-vars]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }}
|
||||
uses: ./.github/workflows/image-reuse.yaml
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.23.3
|
||||
go-version: 1.24.1
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: true
|
||||
secrets:
|
||||
@@ -101,8 +101,8 @@ jobs:
|
||||
- build-and-publish
|
||||
- set-vars
|
||||
permissions:
|
||||
contents: write # for git to push upgrade commit if not already deployed
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
contents: write # for git to push upgrade commit if not already deployed
|
||||
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
|
||||
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }}
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@@ -116,4 +116,3 @@ jobs:
|
||||
git config --global user.name 'CI'
|
||||
git diff --exit-code && echo 'Already deployed' || (git commit -am 'Upgrade argocd to ${{ needs.set-vars.outputs.image-tag }}' && git push)
|
||||
working-directory: argoproj-deployments/argocd
|
||||
|
||||
|
||||
4
.github/workflows/pr-title-check.yml
vendored
4
.github/workflows/pr-title-check.yml
vendored
@@ -12,8 +12,8 @@ permissions: {}
|
||||
# workflow being trigger a number of times. This limits it
|
||||
# to one run per PR.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
|
||||
48
.github/workflows/release.yaml
vendored
48
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ permissions: {}
|
||||
|
||||
env:
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.23.3' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
GOLANG_VERSION: '1.24.1' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
|
||||
jobs:
|
||||
argocd-image:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.23.3
|
||||
go-version: 1.24.1
|
||||
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
|
||||
push: true
|
||||
secrets:
|
||||
@@ -33,20 +33,20 @@ jobs:
|
||||
quay_password: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
|
||||
argocd-image-provenance:
|
||||
needs: [argocd-image]
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues)
|
||||
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
||||
with:
|
||||
image: quay.io/argoproj/argocd
|
||||
digest: ${{ needs.argocd-image.outputs.image-digest }}
|
||||
secrets:
|
||||
registry-username: ${{ secrets.RELEASE_QUAY_USERNAME }}
|
||||
registry-password: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
needs: [argocd-image]
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues)
|
||||
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
|
||||
with:
|
||||
image: quay.io/argoproj/argocd
|
||||
digest: ${{ needs.argocd-image.outputs.image-digest }}
|
||||
secrets:
|
||||
registry-username: ${{ secrets.RELEASE_QUAY_USERNAME }}
|
||||
registry-password: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
|
||||
goreleaser:
|
||||
needs:
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
- name: Generate subject for provenance
|
||||
id: hash
|
||||
env:
|
||||
ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
|
||||
ARTIFACTS: '${{ steps.run-goreleaser.outputs.artifacts }}'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -128,8 +128,8 @@ jobs:
|
||||
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
|
||||
with:
|
||||
base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
|
||||
provenance-name: "argocd-cli.intoto.jsonl"
|
||||
base64-subjects: '${{ needs.goreleaser.outputs.hashes }}'
|
||||
provenance-name: 'argocd-cli.intoto.jsonl'
|
||||
upload-assets: true
|
||||
|
||||
generate-sbom:
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
SIGS_BOM_VERSION: v0.2.1
|
||||
# comma delimited list of project relative folders to inspect for package
|
||||
# managers (gomod, yarn, npm).
|
||||
PROJECT_FOLDERS: ".,./ui"
|
||||
PROJECT_FOLDERS: '.,./ui'
|
||||
# full qualified name of the docker image to be inspected
|
||||
DOCKER_IMAGE: quay.io/argoproj/argocd:${{ github.ref_name }}
|
||||
run: |
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload SBOM
|
||||
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -212,8 +212,8 @@ jobs:
|
||||
# Must be referenced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
|
||||
with:
|
||||
base64-subjects: "${{ needs.generate-sbom.outputs.hashes }}"
|
||||
provenance-name: "argocd-sbom.intoto.jsonl"
|
||||
base64-subjects: '${{ needs.generate-sbom.outputs.hashes }}'
|
||||
provenance-name: 'argocd-sbom.intoto.jsonl'
|
||||
upload-assets: true
|
||||
|
||||
post-release:
|
||||
@@ -296,7 +296,7 @@ jobs:
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
|
||||
with:
|
||||
commit-message: Bump version in master
|
||||
title: "chore: Bump version in master"
|
||||
title: 'chore: Bump version in master'
|
||||
body: All images built from master should indicate which version we are on track for.
|
||||
signoff: true
|
||||
branch: update-version
|
||||
|
||||
2
.gitpod.Dockerfile
vendored
2
.gitpod.Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
FROM gitpod/workspace-full@sha256:bec45ebdcc9b9c5ec28d5c61c16bf599200aa0d2dc1e69e2ed8ab0a424bae6db
|
||||
FROM gitpod/workspace-full@sha256:a47a68ee7f9da10cd889ccce4661bc73f2c0d5a98d3d087e8bdfc0230b27964c
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ linters:
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
# Disabled because of https://github.com/argoproj/argo-cd/issues/21705
|
||||
# - nolintlint
|
||||
- perfsprint
|
||||
- revive
|
||||
- staticcheck
|
||||
@@ -28,18 +30,15 @@ linters:
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- whitespace
|
||||
- usetesting
|
||||
- whitespace
|
||||
linters-settings:
|
||||
gocritic:
|
||||
disabled-checks:
|
||||
- appendAssign
|
||||
- assignOp # Keep it disabled for readability
|
||||
- badCond
|
||||
- commentFormatting
|
||||
- assignOp # Keep it disabled for readability
|
||||
- exitAfterDefer
|
||||
- ifElseChain
|
||||
- mapKey
|
||||
- singleCaseSwitch
|
||||
- typeSwitchVar
|
||||
goimports:
|
||||
local-prefixes: github.com/argoproj/argo-cd/v3
|
||||
@@ -52,13 +51,13 @@ linters-settings:
|
||||
- github.com/imdario/mergo:
|
||||
recommendations:
|
||||
- dario.cat/mergo
|
||||
reason: "`github.com/imdario/mergo` has been renamed."
|
||||
reason: '`github.com/imdario/mergo` has been renamed.'
|
||||
- github.com/pkg/errors:
|
||||
recommendations:
|
||||
- errors
|
||||
importas:
|
||||
alias:
|
||||
- alias: jwtgo
|
||||
- alias: jwtgo
|
||||
pkg: github.com/golang-jwt/jwt/v5
|
||||
- alias: appsv1
|
||||
pkg: k8s.io/api/apps/v1
|
||||
@@ -66,14 +65,18 @@ linters-settings:
|
||||
pkg: k8s.io/api/core/v1
|
||||
- alias: rbacv1
|
||||
pkg: k8s.io/api/rbac/v1
|
||||
- alias: apierrors
|
||||
- alias: apierrors
|
||||
pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
- alias: metav1
|
||||
- alias: apiextensionsv1
|
||||
pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
|
||||
- alias: metav1
|
||||
pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
- alias: informersv1
|
||||
pkg: k8s.io/client-go/informers/core/v1
|
||||
- alias: stderrors
|
||||
pkg: errors
|
||||
nolintlint:
|
||||
require-specific: true
|
||||
perfsprint:
|
||||
# Optimizes even if it requires an int or uint type cast.
|
||||
int-conversion: true
|
||||
@@ -86,81 +89,68 @@ linters-settings:
|
||||
# Optimizes into strings concatenation.
|
||||
strconcat: true
|
||||
revive:
|
||||
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
|
||||
rules:
|
||||
# Blank import should be only in a main or test package, or have a comment justifying it.
|
||||
- name: bool-literal-in-expr
|
||||
- name: blank-imports
|
||||
disabled: true
|
||||
# context.Context() should be the first parameter of a function when provided as argument.
|
||||
- name: context-as-argument
|
||||
disabled: true
|
||||
# Basic types should not be used as a key in `context.WithValue`
|
||||
arguments:
|
||||
- allowTypesBefore: '*testing.T,testing.TB'
|
||||
- name: context-keys-type
|
||||
disabled: true
|
||||
# Importing with `.` makes the programs much harder to understand
|
||||
- name: dot-imports
|
||||
disabled: true
|
||||
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports
|
||||
- name: duplicated-imports
|
||||
disabled: false
|
||||
# Empty blocks make code less readable and could be a symptom of a bug or unfinished refactoring.
|
||||
- name: early-return
|
||||
arguments:
|
||||
- 'preserveScope'
|
||||
- name: empty-block
|
||||
disabled: true
|
||||
# for better readability, variables of type `error` must be named with the prefix `err`.
|
||||
- name: error-naming
|
||||
disabled: true
|
||||
# for better readability, the errors should be last in the list of returned values by a function.
|
||||
- name: error-return
|
||||
disabled: false
|
||||
# for better readability, error messages should not be capitalized or end with punctuation or a newline.
|
||||
- name: error-strings
|
||||
disabled: true
|
||||
# report when replacing `errors.New(fmt.Sprintf())` with `fmt.Errorf()` is possible
|
||||
- name: errorf
|
||||
disabled: false
|
||||
# incrementing an integer variable by 1 is recommended to be done using the `++` operator
|
||||
- name: identical-branches
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
disabled: false
|
||||
# highlights redundant else-blocks that can be eliminated from the code
|
||||
- name: indent-error-flow
|
||||
disabled: true
|
||||
# This rule suggests a shorter way of writing ranges that do not use the second value.
|
||||
arguments:
|
||||
- 'preserveScope'
|
||||
- name: modifies-parameter
|
||||
- name: optimize-operands-order
|
||||
- name: range
|
||||
disabled: false
|
||||
# receiver names in a method should reflect the struct name (p for Person, for example)
|
||||
- name: receiver-naming
|
||||
disabled: true
|
||||
# redefining built in names (true, false, append, make) can lead to bugs very difficult to detect.
|
||||
- name: redefines-builtin-id
|
||||
disabled: true
|
||||
- name: redundant-import-alias
|
||||
disabled: false
|
||||
# redundant else-blocks that can be eliminated from the code.
|
||||
- name: superfluous-else
|
||||
disabled: false
|
||||
# prevent confusing name for variables when using `time` package
|
||||
arguments:
|
||||
- 'preserveScope'
|
||||
- name: time-equal
|
||||
- name: time-naming
|
||||
disabled: true
|
||||
# warns when an exported function or method returns a value of an un-exported type.
|
||||
- name: unexported-return
|
||||
disabled: true
|
||||
# spots and proposes to remove unreachable code. also helps to spot errors
|
||||
- name: unnecessary-stmt
|
||||
- name: unreachable-code
|
||||
disabled: false
|
||||
# Functions or methods with unused parameters can be a symptom of an unfinished refactoring or a bug.
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
# Since Go 1.18, interface{} has an alias: any. This rule proposes to replace instances of interface{} with any.
|
||||
- name: use-any
|
||||
disabled: false
|
||||
# report when a variable declaration can be simplified
|
||||
- name: useless-break
|
||||
- name: var-declaration
|
||||
disabled: false
|
||||
# warns when initialism, variable or package naming conventions are not followed.
|
||||
- name: var-naming
|
||||
disabled: true
|
||||
arguments:
|
||||
- ["ID"]
|
||||
- ["VM"]
|
||||
- - skipPackageNameChecks: true
|
||||
upperCaseConst: true
|
||||
testifylint:
|
||||
enable-all: true
|
||||
disable:
|
||||
- go-require
|
||||
usetesting:
|
||||
os-mkdir-temp: false
|
||||
run:
|
||||
timeout: 50m
|
||||
|
||||
@@ -79,6 +79,8 @@ release:
|
||||
|
||||
All Argo CD container images are signed by cosign. A Provenance is generated for container images and CLI binaries which meet the SLSA Level 3 specifications. See the [documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/signed-release-assets) on how to verify.
|
||||
|
||||
## Release Notes Blog Post
|
||||
For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/argo-cd-v2-14-release-candidate-57a664791e2a)
|
||||
|
||||
## Upgrading
|
||||
|
||||
|
||||
@@ -66,6 +66,9 @@ packages:
|
||||
github.com/argoproj/argo-cd/v3/util/notification/argocd:
|
||||
interfaces:
|
||||
Service:
|
||||
github.com/argoproj/argo-cd/v3/util/workloadidentity:
|
||||
interfaces:
|
||||
TokenProvider:
|
||||
# These mocks are not currently used, but they are part of the public API of this package.
|
||||
github.com/argoproj/argo-cd/v3/pkg/apiclient/session:
|
||||
interfaces:
|
||||
@@ -74,3 +77,6 @@ packages:
|
||||
github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster:
|
||||
interfaces:
|
||||
ClusterServiceServer:
|
||||
github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1:
|
||||
interfaces:
|
||||
AppProjectInterface:
|
||||
|
||||
@@ -2,6 +2,7 @@ version: 2
|
||||
formats: all
|
||||
mkdocs:
|
||||
fail_on_warning: false
|
||||
configuration: mkdocs.yml
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15
|
||||
ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6734ab
|
||||
####################################################################################################
|
||||
# Builder image
|
||||
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
|
||||
# Also used as the image in CI jobs so needs all dependencies
|
||||
####################################################################################################
|
||||
FROM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS builder
|
||||
FROM docker.io/library/golang:1.24.1@sha256:c5adecdb7b3f8c5ca3c88648a861882849cc8b02fed68ece31e25de88ad13418 AS builder
|
||||
|
||||
RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list
|
||||
|
||||
@@ -101,7 +101,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
|
||||
####################################################################################################
|
||||
# Argo CD Build stage which performs the actual build of Argo CD binaries
|
||||
####################################################################################################
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS argocd-build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.1@sha256:c5adecdb7b3f8c5ca3c88648a861882849cc8b02fed68ece31e25de88ad13418 AS argocd-build
|
||||
|
||||
WORKDIR /go/src/github.com/argoproj/argo-cd
|
||||
|
||||
|
||||
9
Makefile
9
Makefile
@@ -355,11 +355,6 @@ mod-vendor: test-tools-image
|
||||
mod-vendor-local: mod-download-local
|
||||
go mod vendor
|
||||
|
||||
# Deprecated - replace by install-tools-local
|
||||
.PHONY: install-lint-tools
|
||||
install-lint-tools:
|
||||
./hack/install.sh lint-tools
|
||||
|
||||
# Run linter on the code
|
||||
.PHONY: lint
|
||||
lint: test-tools-image
|
||||
@@ -435,7 +430,7 @@ test-e2e:
|
||||
test-e2e-local: cli-local
|
||||
# NO_PROXY ensures all tests don't go out through a proxy if one is configured on the test system
|
||||
export GO111MODULE=off
|
||||
DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results"
|
||||
DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_CONFIG_DIR=$(HOME)/.config/argocd-e2e ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v -args -test.gocoverdir="$(PWD)/test-results"
|
||||
|
||||
# Spawns a shell in the test server container for debugging purposes
|
||||
debug-test-server: test-tools-image
|
||||
@@ -599,6 +594,7 @@ install-codegen-tools-local:
|
||||
.PHONY: install-go-tools-local
|
||||
install-go-tools-local:
|
||||
./hack/install.sh codegen-go-tools
|
||||
./hack/install.sh lint-tools
|
||||
|
||||
.PHONY: dep-ui
|
||||
dep-ui: test-tools-image
|
||||
@@ -679,7 +675,6 @@ help:
|
||||
@echo 'debug:'
|
||||
@echo ' list -- list all make targets'
|
||||
@echo ' install-tools-local -- install all the tools below'
|
||||
@echo ' install-lint-tools(-local)'
|
||||
@echo
|
||||
@echo 'codegen:'
|
||||
@echo ' codegen(-local) -- if using -local, run the following targets first'
|
||||
|
||||
8
USERS.md
8
USERS.md
@@ -30,7 +30,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Ant Group](https://www.antgroup.com/)
|
||||
1. [AppDirect](https://www.appdirect.com)
|
||||
1. [Arctiq Inc.](https://www.arctiq.ca)
|
||||
2. [Arturia](https://www.arturia.com)
|
||||
1. [Arturia](https://www.arturia.com)
|
||||
1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/)
|
||||
1. [Augury](https://www.augury.com/)
|
||||
1. [Autodesk](https://www.autodesk.com)
|
||||
@@ -147,6 +147,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Hazelcast](https://hazelcast.com/)
|
||||
1. [Healy](https://www.healyworld.net)
|
||||
1. [Helio](https://helio.exchange)
|
||||
1. [hetao101](https://www.hetao101.com/)
|
||||
1. [Hetki](https://hetki.ai)
|
||||
1. [hipages](https://hipages.com.au/)
|
||||
1. [Hiya](https://hiya.com)
|
||||
@@ -192,10 +193,10 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Lian Chu Securities](https://lczq.com)
|
||||
1. [Liatrio](https://www.liatrio.com)
|
||||
1. [Lightricks](https://www.lightricks.com/)
|
||||
1. [LINE](https://linecorp.com/en/)
|
||||
1. [Loom](https://www.loom.com/)
|
||||
1. [Lucid Motors](https://www.lucidmotors.com/)
|
||||
1. [Lytt](https://www.lytt.co/)
|
||||
1. [LY Corporation](https://www.lycorp.co.jp/en/)
|
||||
1. [Magic Leap](https://www.magicleap.com/)
|
||||
1. [Majid Al Futtaim](https://www.majidalfuttaim.com/)
|
||||
1. [Major League Baseball](https://mlb.com)
|
||||
@@ -376,6 +377,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Vinted](https://vinted.com/)
|
||||
1. [Virtuo](https://www.govirtuo.com/)
|
||||
1. [VISITS Technologies](https://visits.world/en)
|
||||
1. [Viya](https://viya.me)
|
||||
1. [Volvo Cars](https://www.volvocars.com/)
|
||||
1. [Voyager Digital](https://www.investvoyager.com/)
|
||||
1. [VSHN - The DevOps Company](https://vshn.ch/)
|
||||
@@ -390,6 +392,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [WooliesX](https://wooliesx.com.au/)
|
||||
1. [Woolworths Group](https://www.woolworthsgroup.com.au/)
|
||||
1. [WSpot](https://www.wspot.com.br/)
|
||||
1. [X3M ads](https://x3mads.com)
|
||||
1. [Yieldlab](https://www.yieldlab.de/)
|
||||
1. [Youverify](https://youverify.co/)
|
||||
1. [Yubo](https://www.yubo.live/)
|
||||
@@ -397,3 +400,4 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Zimpler](https://www.zimpler.com/)
|
||||
1. [ZipRecuiter](https://www.ziprecruiter.com/)
|
||||
1. [ZOZO](https://corp.zozo.com/)
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
||||
// desiredApplications is the main list of all expected Applications from all generators in this appset.
|
||||
desiredApplications, applicationSetReason, err := template.GenerateApplications(logCtx, applicationSetInfo, r.Generators, r.Renderer, r.Client)
|
||||
if err != nil {
|
||||
logCtx.Errorf("unable to generate applications: %v", err)
|
||||
_ = r.setApplicationSetStatusCondition(ctx,
|
||||
&applicationSetInfo,
|
||||
argov1alpha1.ApplicationSetCondition{
|
||||
@@ -164,7 +165,8 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
||||
Status: argov1alpha1.ApplicationSetConditionStatusTrue,
|
||||
}, parametersGenerated,
|
||||
)
|
||||
return ctrl.Result{RequeueAfter: ReconcileRequeueOnValidationError}, err
|
||||
// In order for the controller SDK to respect RequeueAfter, the error must be nil
|
||||
return ctrl.Result{RequeueAfter: ReconcileRequeueOnValidationError}, nil
|
||||
}
|
||||
|
||||
parametersGenerated = true
|
||||
@@ -479,12 +481,11 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con
|
||||
errorsByIndex := map[int]error{}
|
||||
namesSet := map[string]bool{}
|
||||
for i, app := range desiredApplications {
|
||||
if !namesSet[app.Name] {
|
||||
namesSet[app.Name] = true
|
||||
} else {
|
||||
if namesSet[app.Name] {
|
||||
errorsByIndex[i] = fmt.Errorf("ApplicationSet %s contains applications with duplicate name: %s", applicationSetInfo.Name, app.Name)
|
||||
continue
|
||||
}
|
||||
namesSet[app.Name] = true
|
||||
|
||||
appProject := &argov1alpha1.AppProject{}
|
||||
err := r.Client.Get(ctx, types.NamespacedName{Name: app.Spec.Project, Namespace: r.ArgoCDNamespace}, appProject)
|
||||
@@ -496,7 +497,7 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := argoutil.ValidateDestination(ctx, &app.Spec.Destination, r.ArgoDB); err != nil {
|
||||
if _, err = argoutil.GetDestinationCluster(ctx, app.Spec.Destination, r.ArgoDB); err != nil {
|
||||
errorsByIndex[i] = fmt.Errorf("application destination spec is invalid: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
@@ -525,11 +526,9 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argov1
|
||||
}
|
||||
|
||||
func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate {
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(e event.CreateEvent) bool {
|
||||
return utils.IsNamespaceAllowed(namespaces, e.Object.GetNamespace())
|
||||
},
|
||||
}
|
||||
return predicate.NewPredicateFuncs(func(object client.Object) bool {
|
||||
return utils.IsNamespaceAllowed(namespaces, object.GetNamespace())
|
||||
})
|
||||
}
|
||||
|
||||
func appControllerIndexer(rawObj client.Object) []string {
|
||||
@@ -553,12 +552,13 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg
|
||||
return fmt.Errorf("error setting up with manager: %w", err)
|
||||
}
|
||||
|
||||
ownsHandler := getOwnsHandlerPredicates(enableProgressiveSyncs)
|
||||
appOwnsHandler := getApplicationOwnsHandler(enableProgressiveSyncs)
|
||||
appSetOwnsHandler := getApplicationSetOwnsHandler()
|
||||
|
||||
return ctrl.NewControllerManagedBy(mgr).WithOptions(controller.Options{
|
||||
MaxConcurrentReconciles: maxConcurrentReconciliations,
|
||||
}).For(&argov1alpha1.ApplicationSet{}).
|
||||
Owns(&argov1alpha1.Application{}, builder.WithPredicates(ownsHandler)).
|
||||
}).For(&argov1alpha1.ApplicationSet{}, builder.WithPredicates(appSetOwnsHandler)).
|
||||
Owns(&argov1alpha1.Application{}, builder.WithPredicates(appOwnsHandler)).
|
||||
WithEventFilter(ignoreNotAllowedNamespaces(r.ApplicationSetNamespaces)).
|
||||
Watches(
|
||||
&corev1.Secret{},
|
||||
@@ -566,7 +566,6 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg
|
||||
Client: mgr.GetClient(),
|
||||
Log: log.WithField("type", "createSecretEventHandler"),
|
||||
}).
|
||||
// TODO: also watch Applications and respond on changes if we own them.
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
@@ -721,9 +720,6 @@ func (r *ApplicationSetReconciler) getCurrentApplications(ctx context.Context, a
|
||||
// deleteInCluster will delete Applications that are currently on the cluster, but not in appList.
|
||||
// The function must be called after all generators had been called and generated applications
|
||||
func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error {
|
||||
// settingsMgr := settings.NewSettingsManager(context.TODO(), r.KubeClientset, applicationSet.Namespace)
|
||||
// argoDB := db.NewDB(applicationSet.Namespace, settingsMgr, r.KubeClientset)
|
||||
// clusterList, err := argoDB.ListClusters(ctx)
|
||||
clusterList, err := utils.ListClusters(ctx, r.KubeClientset, r.ArgoCDNamespace)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing clusters: %w", err)
|
||||
@@ -774,7 +770,7 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx *
|
||||
}
|
||||
|
||||
// removeFinalizerOnInvalidDestination removes the Argo CD resources finalizer if the application contains an invalid target (eg missing cluster)
|
||||
func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, app *argov1alpha1.Application, clusterList *argov1alpha1.ClusterList, appLog *log.Entry) error {
|
||||
func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, app *argov1alpha1.Application, clusterList []utils.ClusterSpecifier, appLog *log.Entry) error {
|
||||
// Only check if the finalizers need to be removed IF there are finalizers to remove
|
||||
if len(app.Finalizers) == 0 {
|
||||
return nil
|
||||
@@ -783,21 +779,18 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte
|
||||
var validDestination bool
|
||||
|
||||
// Detect if the destination is invalid (name doesn't correspond to a matching cluster)
|
||||
if err := argoutil.ValidateDestination(ctx, &app.Spec.Destination, r.ArgoDB); err != nil {
|
||||
if destCluster, err := argoutil.GetDestinationCluster(ctx, app.Spec.Destination, r.ArgoDB); err != nil {
|
||||
appLog.Warnf("The destination cluster for %s couldn't be found: %v", app.Name, err)
|
||||
validDestination = false
|
||||
} else {
|
||||
// Detect if the destination's server field does not match an existing cluster
|
||||
|
||||
matchingCluster := false
|
||||
for _, cluster := range clusterList.Items {
|
||||
// Server fields must match. Note that ValidateDestination ensures that the server field is set, if applicable.
|
||||
if app.Spec.Destination.Server != cluster.Server {
|
||||
for _, cluster := range clusterList {
|
||||
if destCluster.Server != cluster.Server {
|
||||
continue
|
||||
}
|
||||
|
||||
// The name must match, if it is not empty
|
||||
if app.Spec.Destination.Name != "" && cluster.Name != app.Spec.Destination.Name {
|
||||
if destCluster.Name != cluster.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -982,17 +975,16 @@ func (r *ApplicationSetReconciler) buildAppSyncMap(applicationSet argov1alpha1.A
|
||||
}
|
||||
|
||||
appStatus := applicationSet.Status.ApplicationStatus[idx]
|
||||
|
||||
if app, ok := appMap[appName]; ok {
|
||||
syncEnabled = appSyncEnabledForNextStep(&applicationSet, app, appStatus)
|
||||
if !syncEnabled {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
app, ok := appMap[appName]
|
||||
if !ok {
|
||||
// application name not found in the list of applications managed by this ApplicationSet, maybe because it's being deleted
|
||||
syncEnabled = false
|
||||
break
|
||||
}
|
||||
syncEnabled = appSyncEnabledForNextStep(&applicationSet, app, appStatus)
|
||||
if !syncEnabled {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,19 +1054,20 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
|
||||
Message: "No Application status found, defaulting status to Waiting.",
|
||||
Status: "Waiting",
|
||||
Step: strconv.Itoa(getAppStep(app.Name, appStepMap)),
|
||||
TargetRevisions: app.Status.GetRevisions(),
|
||||
}
|
||||
} else {
|
||||
// we have an existing AppStatus
|
||||
currentAppStatus = applicationSet.Status.ApplicationStatus[idx]
|
||||
|
||||
// upgrade any existing AppStatus that might have been set by an older argo-cd version
|
||||
// note: currentAppStatus.TargetRevisions may be set to empty list earlier during migrations,
|
||||
// to prevent other usage of r.Client.Status().Update to fail before reaching here.
|
||||
if len(currentAppStatus.TargetRevisions) == 0 {
|
||||
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
|
||||
if !reflect.DeepEqual(currentAppStatus.TargetRevisions, app.Status.GetRevisions()) {
|
||||
currentAppStatus.Message = "Application has pending changes, setting status to Waiting."
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(currentAppStatus.TargetRevisions, app.Status.GetRevisions()) {
|
||||
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
|
||||
currentAppStatus.Status = "Waiting"
|
||||
currentAppStatus.LastTransitionTime = &now
|
||||
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
|
||||
}
|
||||
|
||||
appOutdated := false
|
||||
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
|
||||
@@ -1087,25 +1080,15 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
|
||||
currentAppStatus.Status = "Waiting"
|
||||
currentAppStatus.Message = "Application has pending changes, setting status to Waiting."
|
||||
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
|
||||
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
|
||||
}
|
||||
|
||||
if currentAppStatus.Status == "Pending" {
|
||||
if operationPhaseString == "Succeeded" {
|
||||
revisions := []string{}
|
||||
if len(app.Status.OperationState.SyncResult.Revisions) > 0 {
|
||||
revisions = app.Status.OperationState.SyncResult.Revisions
|
||||
} else if app.Status.OperationState.SyncResult.Revision != "" {
|
||||
revisions = append(revisions, app.Status.OperationState.SyncResult.Revision)
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(currentAppStatus.TargetRevisions, revisions) {
|
||||
logCtx.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name)
|
||||
currentAppStatus.LastTransitionTime = &now
|
||||
currentAppStatus.Status = "Progressing"
|
||||
currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing."
|
||||
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
|
||||
}
|
||||
if !appOutdated && operationPhaseString == "Succeeded" {
|
||||
logCtx.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name)
|
||||
currentAppStatus.LastTransitionTime = &now
|
||||
currentAppStatus.Status = "Progressing"
|
||||
currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing."
|
||||
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
|
||||
} else if operationPhaseString == "Running" || healthStatusString == "Progressing" {
|
||||
logCtx.Infof("Application %v has entered Progressing status, updating its ApplicationSet status to Progressing", app.Name)
|
||||
currentAppStatus.LastTransitionTime = &now
|
||||
@@ -1467,7 +1450,7 @@ func syncApplication(application argov1alpha1.Application, prune bool) argov1alp
|
||||
return application
|
||||
}
|
||||
|
||||
func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
|
||||
func getApplicationOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs {
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(e event.CreateEvent) bool {
|
||||
// if we are the owner and there is a create event, we most likely created it and do not need to
|
||||
@@ -1504,8 +1487,8 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
|
||||
if !isApp {
|
||||
return false
|
||||
}
|
||||
requeue := shouldRequeueApplicationSet(appOld, appNew, enableProgressiveSyncs)
|
||||
logCtx.WithField("requeue", requeue).Debugf("requeue: %t caused by application %s", requeue, appNew.Name)
|
||||
requeue := shouldRequeueForApplication(appOld, appNew, enableProgressiveSyncs)
|
||||
logCtx.WithField("requeue", requeue).Debugf("requeue caused by application %s", appNew.Name)
|
||||
return requeue
|
||||
},
|
||||
GenericFunc: func(e event.GenericEvent) bool {
|
||||
@@ -1522,13 +1505,13 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
|
||||
}
|
||||
}
|
||||
|
||||
// shouldRequeueApplicationSet determines when we want to requeue an ApplicationSet for reconciling based on an owned
|
||||
// shouldRequeueForApplication determines when we want to requeue an ApplicationSet for reconciling based on an owned
|
||||
// application change
|
||||
// The applicationset controller owns a subset of the Application CR.
|
||||
// We do not need to re-reconcile if parts of the application change outside the applicationset's control.
|
||||
// An example being, Application.ApplicationStatus.ReconciledAt which gets updated by the application controller.
|
||||
// Additionally, Application.ObjectMeta.ResourceVersion and Application.ObjectMeta.Generation which are set by K8s.
|
||||
func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov1alpha1.Application, enableProgressiveSyncs bool) bool {
|
||||
func shouldRequeueForApplication(appOld *argov1alpha1.Application, appNew *argov1alpha1.Application, enableProgressiveSyncs bool) bool {
|
||||
if appOld == nil || appNew == nil {
|
||||
return false
|
||||
}
|
||||
@@ -1561,4 +1544,81 @@ func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov
|
||||
return false
|
||||
}
|
||||
|
||||
func getApplicationSetOwnsHandler() predicate.Funcs {
|
||||
return predicate.Funcs{
|
||||
CreateFunc: func(e event.CreateEvent) bool {
|
||||
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
|
||||
if !isApp {
|
||||
return false
|
||||
}
|
||||
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received create event")
|
||||
// Always queue a new applicationset
|
||||
return true
|
||||
},
|
||||
DeleteFunc: func(e event.DeleteEvent) bool {
|
||||
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
|
||||
if !isApp {
|
||||
return false
|
||||
}
|
||||
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received delete event")
|
||||
// Always queue for the deletion of an applicationset
|
||||
return true
|
||||
},
|
||||
UpdateFunc: func(e event.UpdateEvent) bool {
|
||||
appSetOld, isAppSet := e.ObjectOld.(*argov1alpha1.ApplicationSet)
|
||||
if !isAppSet {
|
||||
return false
|
||||
}
|
||||
appSetNew, isAppSet := e.ObjectNew.(*argov1alpha1.ApplicationSet)
|
||||
if !isAppSet {
|
||||
return false
|
||||
}
|
||||
requeue := shouldRequeueForApplicationSet(appSetOld, appSetNew)
|
||||
log.WithField("applicationset", appSetNew.QualifiedName()).
|
||||
WithField("requeue", requeue).Debugln("received update event")
|
||||
return requeue
|
||||
},
|
||||
GenericFunc: func(e event.GenericEvent) bool {
|
||||
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
|
||||
if !isApp {
|
||||
return false
|
||||
}
|
||||
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received generic event")
|
||||
// Always queue for the generic of an applicationset
|
||||
return true
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// shouldRequeueForApplicationSet determines when we need to requeue an applicationset
|
||||
func shouldRequeueForApplicationSet(appSetOld, appSetNew *argov1alpha1.ApplicationSet) bool {
|
||||
if appSetOld == nil || appSetNew == nil {
|
||||
return false
|
||||
}
|
||||
// only compare the applicationset spec, annotations, labels and finalizers, specifically avoiding
|
||||
// the status field. status is owned by the applicationset controller,
|
||||
// and we do not need to requeue when it does bookkeeping
|
||||
// NB: the ApplicationDestination comes from the ApplicationSpec being embedded
|
||||
// in the ApplicationSetTemplate from the generators
|
||||
if !cmp.Equal(appSetOld.Spec, appSetNew.Spec, cmpopts.EquateEmpty(), cmpopts.EquateComparable(argov1alpha1.ApplicationDestination{})) ||
|
||||
!cmp.Equal(appSetOld.ObjectMeta.GetLabels(), appSetNew.ObjectMeta.GetLabels(), cmpopts.EquateEmpty()) ||
|
||||
!cmp.Equal(appSetOld.ObjectMeta.GetFinalizers(), appSetNew.ObjectMeta.GetFinalizers(), cmpopts.EquateEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Requeue only when the refresh annotation is newly added to the ApplicationSet.
|
||||
// Changes to other annotations made simultaneously might be missed, but such cases are rare.
|
||||
if !cmp.Equal(appSetOld.ObjectMeta.GetAnnotations(), appSetNew.ObjectMeta.GetAnnotations(), cmpopts.EquateEmpty()) {
|
||||
_, oldHasRefreshAnnotation := appSetOld.Annotations[common.AnnotationApplicationSetRefresh]
|
||||
_, newHasRefreshAnnotation := appSetNew.Annotations[common.AnnotationApplicationSetRefresh]
|
||||
|
||||
if oldHasRefreshAnnotation && !newHasRefreshAnnotation {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var _ handler.EventHandler = &clusterSecretEventHandler{}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
argocommon "github.com/argoproj/argo-cd/v3/common"
|
||||
@@ -550,7 +549,7 @@ func TestClusterEventHandler(t *testing.T) {
|
||||
|
||||
mockAddRateLimitingInterface := mockAddRateLimitingInterface{}
|
||||
|
||||
handler.queueRelatedAppGenerators(context.Background(), &mockAddRateLimitingInterface, &test.secret)
|
||||
handler.queueRelatedAppGenerators(t.Context(), &mockAddRateLimitingInterface, &test.secret)
|
||||
|
||||
assert.ElementsMatch(t, mockAddRateLimitingInterface.addedItems, test.expectedRequests)
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -24,7 +23,7 @@ import (
|
||||
|
||||
func TestRequeueAfter(t *testing.T) {
|
||||
mockServer := &mocks.Repos{}
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
scheme := runtime.NewScheme()
|
||||
err := argov1alpha1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
@@ -60,7 +59,7 @@ func TestRequeueAfter(t *testing.T) {
|
||||
scmConfig := generators.NewSCMConfig("", []string{""}, true, nil, true)
|
||||
terminalGenerators := map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
"Clusters": generators.NewClusterGenerator(k8sClient, ctx, appClientset, "argocd"),
|
||||
"Clusters": generators.NewClusterGenerator(ctx, k8sClient, appClientset, "argocd"),
|
||||
"Git": generators.NewGitGenerator(mockServer, "namespace"),
|
||||
"SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), scmConfig),
|
||||
"ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, fakeDynClient, appClientset, "argocd"),
|
||||
@@ -90,7 +89,7 @@ func TestRequeueAfter(t *testing.T) {
|
||||
}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics()
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
|
||||
@@ -33,7 +33,7 @@ type ClusterGenerator struct {
|
||||
|
||||
var render = &utils.Render{}
|
||||
|
||||
func NewClusterGenerator(c client.Client, ctx context.Context, clientset kubernetes.Interface, namespace string) Generator {
|
||||
func NewClusterGenerator(ctx context.Context, c client.Client, clientset kubernetes.Interface, namespace string) Generator {
|
||||
settingsManager := settings.NewSettingsManager(ctx, clientset, namespace)
|
||||
|
||||
g := &ClusterGenerator{
|
||||
@@ -70,7 +70,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
// - Since local clusters do not have secrets, they do not have labels to match against
|
||||
ignoreLocalClusters := len(appSetGenerator.Clusters.Selector.MatchExpressions) > 0 || len(appSetGenerator.Clusters.Selector.MatchLabels) > 0
|
||||
|
||||
// ListCluster from Argo CD's util/db package will include the local cluster in the list of clusters
|
||||
// ListCluster will include the local cluster in the list of clusters
|
||||
clustersFromArgoCD, err := utils.ListClusters(g.ctx, g.clientset, g.namespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing clusters: %w", err)
|
||||
@@ -93,7 +93,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
logCtx.Debugf("Using flat mode = %t for cluster generator", isFlatMode)
|
||||
clustersParams := make([]map[string]any, 0)
|
||||
|
||||
for _, cluster := range clustersFromArgoCD.Items {
|
||||
for _, cluster := range clustersFromArgoCD {
|
||||
// If there is a secret for this cluster, then it's a non-local cluster, so it will be
|
||||
// handled by the next step.
|
||||
if secretForCluster, exists := clusterSecrets[cluster.Name]; exists {
|
||||
|
||||
@@ -315,7 +315,7 @@ func TestGenerateParams(t *testing.T) {
|
||||
testCase.clientError,
|
||||
}
|
||||
|
||||
clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace")
|
||||
clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace")
|
||||
|
||||
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -853,7 +853,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) {
|
||||
testCase.clientError,
|
||||
}
|
||||
|
||||
clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace")
|
||||
clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace")
|
||||
|
||||
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
||||
@@ -165,63 +165,59 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A
|
||||
}
|
||||
log.Infof("Number of decisions found: %v", len(clusterDecisions))
|
||||
|
||||
// Read this outside the loop to improve performance
|
||||
argoClusters := clustersFromArgoCD.Items
|
||||
|
||||
if len(clusterDecisions) > 0 {
|
||||
for _, cluster := range clusterDecisions {
|
||||
// generated instance of cluster params
|
||||
params := map[string]any{}
|
||||
|
||||
log.Infof("cluster: %v", cluster)
|
||||
matchValue := cluster.(map[string]any)[matchKey]
|
||||
if matchValue == nil || matchValue.(string) == "" {
|
||||
log.Warningf("matchKey=%v not found in \"%v\" list: %v\n", matchKey, statusListKey, cluster.(map[string]any))
|
||||
continue
|
||||
}
|
||||
|
||||
strMatchValue := matchValue.(string)
|
||||
log.WithField(matchKey, strMatchValue).Debug("validate against ArgoCD")
|
||||
|
||||
found := false
|
||||
|
||||
for _, argoCluster := range argoClusters {
|
||||
if argoCluster.Name == strMatchValue {
|
||||
log.WithField(matchKey, argoCluster.Name).Info("matched cluster in ArgoCD")
|
||||
params["name"] = argoCluster.Name
|
||||
params["server"] = argoCluster.Server
|
||||
|
||||
found = true
|
||||
break // Stop looking
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.WithField(matchKey, strMatchValue).Warning("unmatched cluster in ArgoCD")
|
||||
continue
|
||||
}
|
||||
|
||||
for key, value := range cluster.(map[string]any) {
|
||||
params[key] = value.(string)
|
||||
}
|
||||
|
||||
for key, value := range appSetGenerator.ClusterDecisionResource.Values {
|
||||
if appSet.Spec.GoTemplate {
|
||||
if params["values"] == nil {
|
||||
params["values"] = map[string]string{}
|
||||
}
|
||||
params["values"].(map[string]string)[key] = value
|
||||
} else {
|
||||
params["values."+key] = value
|
||||
}
|
||||
}
|
||||
|
||||
res = append(res, params)
|
||||
}
|
||||
} else {
|
||||
if len(clusterDecisions) == 0 {
|
||||
log.Warningf("clusterDecisionResource status.%s missing", statusListKey)
|
||||
return nil, nil
|
||||
}
|
||||
for _, cluster := range clusterDecisions {
|
||||
// generated instance of cluster params
|
||||
params := map[string]any{}
|
||||
|
||||
log.Infof("cluster: %v", cluster)
|
||||
matchValue := cluster.(map[string]any)[matchKey]
|
||||
if matchValue == nil || matchValue.(string) == "" {
|
||||
log.Warningf("matchKey=%v not found in \"%v\" list: %v\n", matchKey, statusListKey, cluster.(map[string]any))
|
||||
continue
|
||||
}
|
||||
|
||||
strMatchValue := matchValue.(string)
|
||||
log.WithField(matchKey, strMatchValue).Debug("validate against ArgoCD")
|
||||
|
||||
found := false
|
||||
|
||||
for _, argoCluster := range clustersFromArgoCD {
|
||||
if argoCluster.Name == strMatchValue {
|
||||
log.WithField(matchKey, argoCluster.Name).Info("matched cluster in ArgoCD")
|
||||
params["name"] = argoCluster.Name
|
||||
params["server"] = argoCluster.Server
|
||||
|
||||
found = true
|
||||
break // Stop looking
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.WithField(matchKey, strMatchValue).Warning("unmatched cluster in ArgoCD")
|
||||
continue
|
||||
}
|
||||
|
||||
for key, value := range cluster.(map[string]any) {
|
||||
params[key] = value.(string)
|
||||
}
|
||||
|
||||
for key, value := range appSetGenerator.ClusterDecisionResource.Values {
|
||||
if appSet.Spec.GoTemplate {
|
||||
if params["values"] == nil {
|
||||
params["values"] = map[string]string{}
|
||||
}
|
||||
params["values"].(map[string]string)[key] = value
|
||||
} else {
|
||||
params["values."+key] = value
|
||||
}
|
||||
}
|
||||
|
||||
res = append(res, params)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
@@ -20,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
resourceApiVersion = "mallard.io/v1"
|
||||
resourceAPIVersion = "mallard.io/v1"
|
||||
resourceKind = "ducks"
|
||||
resourceName = "quak"
|
||||
)
|
||||
@@ -79,7 +78,7 @@ func TestGenerateParamsForDuckType(t *testing.T) {
|
||||
|
||||
duckType := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -101,7 +100,7 @@ func TestGenerateParamsForDuckType(t *testing.T) {
|
||||
|
||||
duckTypeProdOnly := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -120,7 +119,7 @@ func TestGenerateParamsForDuckType(t *testing.T) {
|
||||
|
||||
duckTypeEmpty := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -137,7 +136,7 @@ func TestGenerateParamsForDuckType(t *testing.T) {
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": resourceKind,
|
||||
"statusListKey": "decisions",
|
||||
"matchKey": "clusterName",
|
||||
@@ -293,7 +292,7 @@ func TestGenerateParamsForDuckType(t *testing.T) {
|
||||
|
||||
fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, testCase.resource)
|
||||
|
||||
duckTypeGenerator := NewDuckTypeGenerator(context.Background(), fakeDynClient, appClientset, "namespace")
|
||||
duckTypeGenerator := NewDuckTypeGenerator(t.Context(), fakeDynClient, appClientset, "namespace")
|
||||
|
||||
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -375,7 +374,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) {
|
||||
|
||||
duckType := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -397,7 +396,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) {
|
||||
|
||||
duckTypeProdOnly := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -416,7 +415,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) {
|
||||
|
||||
duckTypeEmpty := &unstructured.Unstructured{
|
||||
Object: map[string]any{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": "Duck",
|
||||
"metadata": map[string]any{
|
||||
"name": resourceName,
|
||||
@@ -433,7 +432,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) {
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"apiVersion": resourceApiVersion,
|
||||
"apiVersion": resourceAPIVersion,
|
||||
"kind": resourceKind,
|
||||
"statusListKey": "decisions",
|
||||
"matchKey": "clusterName",
|
||||
@@ -589,7 +588,7 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) {
|
||||
|
||||
fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, testCase.resource)
|
||||
|
||||
duckTypeGenerator := NewDuckTypeGenerator(context.Background(), fakeDynClient, appClientset, "namespace")
|
||||
duckTypeGenerator := NewDuckTypeGenerator(t.Context(), fakeDynClient, appClientset, "namespace")
|
||||
|
||||
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
||||
@@ -159,16 +159,3 @@ func InterpolateGenerator(requestedGenerator *argoprojiov1alpha1.ApplicationSetG
|
||||
|
||||
return *interpolatedGenerator, nil
|
||||
}
|
||||
|
||||
// Fixes https://github.com/argoproj/argo-cd/issues/11982 while ensuring backwards compatibility.
|
||||
// This is only a short-term solution and should be removed in a future major version.
|
||||
func dropDisabledNestedSelectors(generators []argoprojiov1alpha1.ApplicationSetNestedGenerator) bool {
|
||||
var foundSelector bool
|
||||
for i := range generators {
|
||||
if generators[i].Selector != nil {
|
||||
foundSelector = true
|
||||
generators[i].Selector = nil
|
||||
}
|
||||
}
|
||||
return foundSelector
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ func getMockClusterGenerator() Generator {
|
||||
appClientset := kubefake.NewSimpleClientset(runtimeClusters...)
|
||||
|
||||
fakeClient := fake.NewClientBuilder().WithObjects(clusters...).Build()
|
||||
return NewClusterGenerator(fakeClient, context.Background(), appClientset, "namespace")
|
||||
return NewClusterGenerator(context.Background(), fakeClient, appClientset, "namespace")
|
||||
}
|
||||
|
||||
func getMockGitGenerator() Generator {
|
||||
|
||||
@@ -81,13 +81,18 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic
|
||||
verifyCommit = len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled()
|
||||
}
|
||||
|
||||
// If the project field is templated, we cannot resolve the project name, so we pass an empty string to the repo-server.
|
||||
// This means only "globally-scoped" repo credentials can be used for such appsets.
|
||||
project := resolveProjectName(appSet.Spec.Template.Spec.Project)
|
||||
|
||||
var err error
|
||||
var res []map[string]any
|
||||
if len(appSetGenerator.Git.Directories) != 0 {
|
||||
res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions)
|
||||
} else if len(appSetGenerator.Git.Files) != 0 {
|
||||
res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions)
|
||||
} else {
|
||||
switch {
|
||||
case len(appSetGenerator.Git.Directories) != 0:
|
||||
res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, project, appSet.Spec.GoTemplateOptions)
|
||||
case len(appSetGenerator.Git.Files) != 0:
|
||||
res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, verifyCommit, appSet.Spec.GoTemplate, project, appSet.Spec.GoTemplateOptions)
|
||||
default:
|
||||
return nil, EmptyAppSetGeneratorError
|
||||
}
|
||||
if err != nil {
|
||||
@@ -97,9 +102,9 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]any, error) {
|
||||
func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit, useGoTemplate bool, project string, goTemplateOptions []string) ([]map[string]any, error) {
|
||||
// Directories, not files
|
||||
allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, noRevisionCache, verifyCommit)
|
||||
allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, project, noRevisionCache, verifyCommit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting directories from repo: %w", err)
|
||||
}
|
||||
@@ -122,11 +127,11 @@ func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoproj
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]any, error) {
|
||||
func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache, verifyCommit, useGoTemplate bool, project string, goTemplateOptions []string) ([]map[string]any, error) {
|
||||
// Get all files that match the requested path string, removing duplicates
|
||||
allFiles := make(map[string][]byte)
|
||||
for _, requestedPath := range appSetGenerator.Git.Files {
|
||||
files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path, noRevisionCache, verifyCommit)
|
||||
files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, project, requestedPath.Path, noRevisionCache, verifyCommit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -302,3 +307,11 @@ func (g *GitGenerator) generateParamsFromApps(requestedApps []string, appSetGene
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func resolveProjectName(project string) string {
|
||||
if strings.Contains(project, "{{") {
|
||||
return ""
|
||||
}
|
||||
|
||||
return project
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/utils/ptr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/services/mocks"
|
||||
@@ -169,11 +170,12 @@ foo:
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
params, err := (*GitGenerator)(nil).generateParamsFromGitFile(tt.args.filePath, tt.args.fileContent, tt.args.values, tt.args.useGoTemplate, tt.args.goTemplateOptions, tt.args.pathParamPrefix)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GitGenerator.generateParamsFromGitFile() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err, "GitGenerator.generateParamsFromGitFile()")
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.want, params)
|
||||
}
|
||||
assert.Equal(t, tt.want, params)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -198,7 +200,6 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
"app_3",
|
||||
"p1/app4",
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]any{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "path[0]": "app2"},
|
||||
@@ -233,7 +234,6 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
"p1/p2/app3",
|
||||
"p1/p2/p3/app4",
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]any{
|
||||
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path[2]": "app3", "path.basenameNormalized": "app3"},
|
||||
@@ -321,7 +321,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
|
||||
argoCDServiceMock := mocks.Repos{}
|
||||
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
|
||||
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
|
||||
applicationSetInfo := v1alpha1.ApplicationSet{
|
||||
@@ -622,7 +622,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) {
|
||||
|
||||
argoCDServiceMock := mocks.Repos{}
|
||||
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
|
||||
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
|
||||
applicationSetInfo := v1alpha1.ApplicationSet{
|
||||
@@ -986,7 +986,7 @@ cluster:
|
||||
t.Parallel()
|
||||
|
||||
argoCDServiceMock := mocks.Repos{}
|
||||
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
||||
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
||||
Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError)
|
||||
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
|
||||
@@ -1342,7 +1342,7 @@ cluster:
|
||||
t.Parallel()
|
||||
|
||||
argoCDServiceMock := mocks.Repos{}
|
||||
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
||||
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
||||
Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError)
|
||||
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
|
||||
@@ -1387,6 +1387,7 @@ cluster:
|
||||
func TestGitGenerator_GenerateParams(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
appProject v1alpha1.AppProject
|
||||
directories []v1alpha1.GitDirectoryGeneratorItem
|
||||
pathParamPrefix string
|
||||
repoApps []string
|
||||
@@ -1395,6 +1396,7 @@ func TestGitGenerator_GenerateParams(t *testing.T) {
|
||||
values map[string]string
|
||||
expected []map[string]any
|
||||
expectedError error
|
||||
expectedProject *string
|
||||
appset v1alpha1.ApplicationSet
|
||||
callGetDirectories bool
|
||||
}{
|
||||
@@ -1466,21 +1468,102 @@ func TestGitGenerator_GenerateParams(t *testing.T) {
|
||||
expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
|
||||
expectedError: errors.New("error getting project project: appprojects.argoproj.io \"project\" not found"),
|
||||
},
|
||||
{
|
||||
name: "Project field is not templated - verify that project is passed through to repo-server as-is",
|
||||
repoApps: []string{
|
||||
"app1",
|
||||
},
|
||||
callGetDirectories: true,
|
||||
appProject: v1alpha1.AppProject{
|
||||
TypeMeta: metav1.TypeMeta{},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "project",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
},
|
||||
appset: v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "set",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Generators: []v1alpha1.ApplicationSetGenerator{{
|
||||
Git: &v1alpha1.GitGenerator{
|
||||
RepoURL: "RepoURL",
|
||||
Revision: "Revision",
|
||||
Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}},
|
||||
PathParamPrefix: "",
|
||||
Values: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
}},
|
||||
Template: v1alpha1.ApplicationSetTemplate{
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "project",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
|
||||
expectedProject: ptr.To("project"),
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Project field is templated - verify that project is passed through to repo-server as empty string",
|
||||
repoApps: []string{
|
||||
"app1",
|
||||
},
|
||||
callGetDirectories: true,
|
||||
appset: v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "set",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Generators: []v1alpha1.ApplicationSetGenerator{{
|
||||
Git: &v1alpha1.GitGenerator{
|
||||
RepoURL: "RepoURL",
|
||||
Revision: "Revision",
|
||||
Directories: []v1alpha1.GitDirectoryGeneratorItem{{Path: "*"}},
|
||||
PathParamPrefix: "",
|
||||
Values: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
}},
|
||||
Template: v1alpha1.ApplicationSetTemplate{
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "{{.project}}",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []map[string]any{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
|
||||
expectedProject: ptr.To(""),
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
for _, testCase := range cases {
|
||||
argoCDServiceMock := mocks.Repos{}
|
||||
|
||||
if testCase.callGetDirectories {
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError)
|
||||
var project any
|
||||
if testCase.expectedProject != nil {
|
||||
project = *testCase.expectedProject
|
||||
} else {
|
||||
project = mock.Anything
|
||||
}
|
||||
|
||||
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, project, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError)
|
||||
}
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace")
|
||||
gitGenerator := NewGitGenerator(&argoCDServiceMock, "argocd")
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
err := v1alpha1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
appProject := v1alpha1.AppProject{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build()
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&testCase.appProject).Build()
|
||||
|
||||
got, err := gitGenerator.GenerateParams(&testCase.appset.Spec.Generators[0], &testCase.appset, client)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ func NewListGenerator() Generator {
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *ListGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
func (g *ListGenerator) GetRequeueAfter(_ *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
return NoRequeueAfter
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var _ Generator = (*MatrixGenerator)(nil)
|
||||
@@ -86,22 +84,10 @@ func (m *MatrixGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.Appli
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if matrixGen != nil && !appSet.Spec.ApplyNestedSelectors {
|
||||
foundSelector := dropDisabledNestedSelectors(matrixGen.Generators)
|
||||
if foundSelector {
|
||||
log.Warnf("AppSet '%v' defines selector on nested matrix generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selectors", appSet.Name)
|
||||
}
|
||||
}
|
||||
mergeGen, err := getMergeGenerator(appSetBaseGenerator)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving merge generator: %w", err)
|
||||
}
|
||||
if mergeGen != nil && !appSet.Spec.ApplyNestedSelectors {
|
||||
foundSelector := dropDisabledNestedSelectors(mergeGen.Generators)
|
||||
if foundSelector {
|
||||
log.Warnf("AppSet '%v' defines selector on nested merge generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selectors", appSet.Name)
|
||||
}
|
||||
}
|
||||
|
||||
t, err := Transform(
|
||||
argoprojiov1alpha1.ApplicationSetGenerator{
|
||||
@@ -169,9 +155,8 @@ func (m *MatrixGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.Ap
|
||||
|
||||
if found {
|
||||
return res
|
||||
} else {
|
||||
return NoRequeueAfter
|
||||
}
|
||||
return NoRequeueAfter
|
||||
}
|
||||
|
||||
func getMatrixGenerator(r argoprojiov1alpha1.ApplicationSetNestedGenerator) (*argoprojiov1alpha1.MatrixGenerator, error) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -644,7 +643,7 @@ func TestInterpolatedMatrixGenerate(t *testing.T) {
|
||||
fakeClient,
|
||||
testCase.clientError,
|
||||
}
|
||||
clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace")
|
||||
clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace")
|
||||
|
||||
for _, g := range testCaseCopy.baseGenerators {
|
||||
gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{
|
||||
@@ -827,7 +826,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) {
|
||||
fakeClient,
|
||||
testCase.clientError,
|
||||
}
|
||||
clusterGenerator := NewClusterGenerator(cl, context.Background(), appClientset, "namespace")
|
||||
clusterGenerator := NewClusterGenerator(t.Context(), cl, appClientset, "namespace")
|
||||
|
||||
for _, g := range testCaseCopy.baseGenerators {
|
||||
gitGeneratorSpec := v1alpha1.ApplicationSetGenerator{
|
||||
@@ -1087,7 +1086,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) {
|
||||
}
|
||||
|
||||
repoServiceMock := &mocks.Repos{}
|
||||
repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{
|
||||
repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{
|
||||
"some/path.json": []byte("test: content"),
|
||||
}, nil)
|
||||
gitGenerator := NewGitGenerator(repoServiceMock, "")
|
||||
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var _ Generator = (*MergeGenerator)(nil)
|
||||
@@ -124,11 +122,11 @@ func getParamSetsByMergeKey(mergeKeys []string, paramSets []map[string]any) (map
|
||||
for mergeKey := range deDuplicatedMergeKeys {
|
||||
paramSetKey[mergeKey] = paramSet[mergeKey]
|
||||
}
|
||||
paramSetKeyJson, err := json.Marshal(paramSetKey)
|
||||
paramSetKeyJSON, err := json.Marshal(paramSetKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshalling param set key json: %w", err)
|
||||
}
|
||||
paramSetKeyString := string(paramSetKeyJson)
|
||||
paramSetKeyString := string(paramSetKeyJSON)
|
||||
if _, exists := paramSetsByMergeKey[paramSetKeyString]; exists {
|
||||
return nil, fmt.Errorf("%w. Duplicate key was %s", ErrNonUniqueParamSets, paramSetKeyString)
|
||||
}
|
||||
@@ -144,22 +142,10 @@ func (m *MergeGenerator) getParams(appSetBaseGenerator argoprojiov1alpha1.Applic
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if matrixGen != nil && !appSet.Spec.ApplyNestedSelectors {
|
||||
foundSelector := dropDisabledNestedSelectors(matrixGen.Generators)
|
||||
if foundSelector {
|
||||
log.Warnf("AppSet '%v' defines selector on nested matrix generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selector", appSet.Name)
|
||||
}
|
||||
}
|
||||
mergeGen, err := getMergeGenerator(appSetBaseGenerator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mergeGen != nil && !appSet.Spec.ApplyNestedSelectors {
|
||||
foundSelector := dropDisabledNestedSelectors(mergeGen.Generators)
|
||||
if foundSelector {
|
||||
log.Warnf("AppSet '%v' defines selector on nested merge generator's generator without enabling them via 'spec.applyNestedSelectors', ignoring nested selector", appSet.Name)
|
||||
}
|
||||
}
|
||||
|
||||
t, err := Transform(
|
||||
argoprojiov1alpha1.ApplicationSetGenerator{
|
||||
@@ -224,9 +210,8 @@ func (m *MergeGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.App
|
||||
|
||||
if found {
|
||||
return res
|
||||
} else {
|
||||
return NoRequeueAfter
|
||||
}
|
||||
return NoRequeueAfter
|
||||
}
|
||||
|
||||
func getMergeGenerator(r argoprojiov1alpha1.ApplicationSetNestedGenerator) (*argoprojiov1alpha1.MergeGenerator, error) {
|
||||
|
||||
@@ -39,12 +39,12 @@ func getTerminalListGeneratorMultiple(jsons []string) argoprojiov1alpha1.Applica
|
||||
func listOfMapsToSet(maps []map[string]any) (map[string]bool, error) {
|
||||
set := make(map[string]bool, len(maps))
|
||||
for _, paramMap := range maps {
|
||||
paramMapAsJson, err := json.Marshal(paramMap)
|
||||
paramMapAsJSON, err := json.Marshal(paramMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
set[string(paramMapAsJson)] = false
|
||||
set[string(paramMapAsJSON)] = false
|
||||
}
|
||||
return set, nil
|
||||
}
|
||||
|
||||
2
applicationset/generators/mocks/Generator.go
generated
2
applicationset/generators/mocks/Generator.go
generated
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ type PluginGenerator struct {
|
||||
namespace string
|
||||
}
|
||||
|
||||
func NewPluginGenerator(client client.Client, ctx context.Context, clientset kubernetes.Interface, namespace string) Generator {
|
||||
func NewPluginGenerator(ctx context.Context, client client.Client, clientset kubernetes.Interface, namespace string) Generator {
|
||||
g := &PluginGenerator{
|
||||
client: client,
|
||||
ctx: ctx,
|
||||
@@ -106,7 +106,7 @@ func (g *PluginGenerator) getPluginFromGenerator(ctx context.Context, appSetName
|
||||
}
|
||||
}
|
||||
|
||||
pluginClient, err := plugin.NewPluginService(ctx, appSetName, cm["baseUrl"], token, requestTimeout)
|
||||
pluginClient, err := plugin.NewPluginService(appSetName, cm["baseUrl"], token, requestTimeout)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing plugin client: %w", err)
|
||||
}
|
||||
@@ -193,8 +193,8 @@ func (g *PluginGenerator) getConfigMap(ctx context.Context, configMapRef string)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseUrl, ok := cm.Data["baseUrl"]
|
||||
if !ok || baseUrl == "" {
|
||||
baseURL, ok := cm.Data["baseUrl"]
|
||||
if !ok || baseURL == "" {
|
||||
return nil, errors.New("baseUrl not found in ConfigMap")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -629,7 +628,7 @@ func TestPluginGenerateParams(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
@@ -671,7 +670,7 @@ func TestPluginGenerateParams(t *testing.T) {
|
||||
|
||||
fakeClientWithCache := fake.NewClientBuilder().WithObjects([]client.Object{testCase.configmap, testCase.secret}...).Build()
|
||||
|
||||
pluginGenerator := NewPluginGenerator(fakeClientWithCache, ctx, fakeClient, "default")
|
||||
pluginGenerator := NewPluginGenerator(ctx, fakeClientWithCache, fakeClient, "default")
|
||||
|
||||
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -691,11 +690,11 @@ func TestPluginGenerateParams(t *testing.T) {
|
||||
require.EqualError(t, err, testCase.expectedError.Error())
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
expectedJson, err := json.Marshal(testCase.expected)
|
||||
expectedJSON, err := json.Marshal(testCase.expected)
|
||||
require.NoError(t, err)
|
||||
gotJson, err := json.Marshal(got)
|
||||
gotJSON, err := json.Marshal(got)
|
||||
require.NoError(t, err)
|
||||
assert.JSONEq(t, string(expectedJson), string(gotJson))
|
||||
assert.JSONEq(t, string(expectedJSON), string(gotJSON))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -109,6 +109,11 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
|
||||
"author": pull.Author,
|
||||
}
|
||||
|
||||
err := appendTemplatedValues(appSetGenerator.PullRequest.Values, paramMap, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to append templated values: %w", err)
|
||||
}
|
||||
|
||||
// PR lables will only be supported for Go Template appsets, since fasttemplate will be deprecated.
|
||||
if applicationSetInfo != nil && applicationSetInfo.Spec.GoTemplate {
|
||||
paramMap["labels"] = pull.Labels
|
||||
@@ -144,7 +149,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewGitLabService(ctx, token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
return pullrequest.NewGitLabService(token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
}
|
||||
if generatorConfig.Gitea != nil {
|
||||
providerConfig := generatorConfig.Gitea
|
||||
@@ -152,7 +157,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewGiteaService(ctx, token, providerConfig.API, providerConfig.Owner, providerConfig.Repo, providerConfig.Insecure)
|
||||
return pullrequest.NewGiteaService(token, providerConfig.API, providerConfig.Owner, providerConfig.Repo, providerConfig.Insecure)
|
||||
}
|
||||
if generatorConfig.BitbucketServer != nil {
|
||||
providerConfig := generatorConfig.BitbucketServer
|
||||
@@ -176,9 +181,8 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
} else {
|
||||
return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
}
|
||||
return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
}
|
||||
if generatorConfig.Bitbucket != nil {
|
||||
providerConfig := generatorConfig.Bitbucket
|
||||
@@ -194,9 +198,8 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewBitbucketCloudServiceBasicAuth(providerConfig.API, providerConfig.BasicAuth.Username, password, providerConfig.Owner, providerConfig.Repo)
|
||||
} else {
|
||||
return pullrequest.NewBitbucketCloudServiceNoAuth(providerConfig.API, providerConfig.Owner, providerConfig.Repo)
|
||||
}
|
||||
return pullrequest.NewBitbucketCloudServiceNoAuth(providerConfig.API, providerConfig.Owner, providerConfig.Repo)
|
||||
}
|
||||
if generatorConfig.AzureDevOps != nil {
|
||||
providerConfig := generatorConfig.AzureDevOps
|
||||
@@ -204,7 +207,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewAzureDevOpsService(ctx, token, providerConfig.API, providerConfig.Organization, providerConfig.Project, providerConfig.Repo, providerConfig.Labels)
|
||||
return pullrequest.NewAzureDevOpsService(token, providerConfig.API, providerConfig.Organization, providerConfig.Project, providerConfig.Repo, providerConfig.Labels)
|
||||
}
|
||||
return nil, errors.New("no Pull Request provider implementation configured")
|
||||
}
|
||||
@@ -224,5 +227,5 @@ func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alph
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
return pullrequest.NewGithubService(ctx, token, cfg.API, cfg.Owner, cfg.Repo, cfg.Labels)
|
||||
return pullrequest.NewGithubService(token, cfg.API, cfg.Owner, cfg.Repo, cfg.Labels)
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ import (
|
||||
)
|
||||
|
||||
func TestPullRequestGithubGenerateParams(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
cases := []struct {
|
||||
selectFunc func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error)
|
||||
values map[string]string
|
||||
expected []map[string]any
|
||||
expectedErr error
|
||||
applicationSet argoprojiov1alpha1.ApplicationSet
|
||||
@@ -120,6 +121,45 @@ func TestPullRequestGithubGenerateParams(t *testing.T) {
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) {
|
||||
return pullrequest.NewFakeService(
|
||||
ctx,
|
||||
[]*pullrequest.PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
Title: "title1",
|
||||
Branch: "my_branch",
|
||||
TargetBranch: "master",
|
||||
HeadSHA: "abcd",
|
||||
Author: "testName",
|
||||
},
|
||||
},
|
||||
nil,
|
||||
)
|
||||
},
|
||||
values: map[string]string{
|
||||
"foo": "bar",
|
||||
"pr_branch": "{{ branch }}",
|
||||
},
|
||||
expected: []map[string]any{
|
||||
{
|
||||
"number": "1",
|
||||
"title": "title1",
|
||||
"branch": "my_branch",
|
||||
"branch_slug": "my-branch",
|
||||
"target_branch": "master",
|
||||
"target_branch_slug": "master",
|
||||
"head_sha": "abcd",
|
||||
"head_short_sha": "abcd",
|
||||
"head_short_sha_7": "abcd",
|
||||
"author": "testName",
|
||||
"values.foo": "bar",
|
||||
"values.pr_branch": "my_branch",
|
||||
},
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) {
|
||||
return pullrequest.NewFakeService(
|
||||
@@ -219,12 +259,14 @@ func TestPullRequestGithubGenerateParams(t *testing.T) {
|
||||
selectServiceProviderFunc: c.selectFunc,
|
||||
}
|
||||
generatorConfig := argoprojiov1alpha1.ApplicationSetGenerator{
|
||||
PullRequest: &argoprojiov1alpha1.PullRequestGenerator{},
|
||||
PullRequest: &argoprojiov1alpha1.PullRequestGenerator{
|
||||
Values: c.values,
|
||||
},
|
||||
}
|
||||
|
||||
got, gotErr := gen.GenerateParams(&generatorConfig, &c.applicationSet, nil)
|
||||
if c.expectedErr != nil {
|
||||
assert.Equal(t, c.expectedErr.Error(), gotErr.Error())
|
||||
require.EqualError(t, gotErr, c.expectedErr.Error())
|
||||
} else {
|
||||
require.NoError(t, gotErr)
|
||||
}
|
||||
|
||||
@@ -138,15 +138,16 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
|
||||
|
||||
ctx := context.Background()
|
||||
var provider scm_provider.SCMProviderService
|
||||
if g.overrideProvider != nil {
|
||||
switch {
|
||||
case g.overrideProvider != nil:
|
||||
provider = g.overrideProvider
|
||||
} else if providerConfig.Github != nil {
|
||||
case providerConfig.Github != nil:
|
||||
var err error
|
||||
provider, err = g.githubProvider(ctx, providerConfig.Github, applicationSetInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scm provider: %w", err)
|
||||
}
|
||||
} else if providerConfig.Gitlab != nil {
|
||||
case providerConfig.Gitlab != nil:
|
||||
providerConfig := providerConfig.Gitlab
|
||||
var caCerts []byte
|
||||
var scmError error
|
||||
@@ -160,20 +161,20 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Gitlab token: %w", err)
|
||||
}
|
||||
provider, err = scm_provider.NewGitlabProvider(ctx, providerConfig.Group, token, providerConfig.API, providerConfig.AllBranches, providerConfig.IncludeSubgroups, providerConfig.WillIncludeSharedProjects(), providerConfig.Insecure, g.scmRootCAPath, providerConfig.Topic, caCerts)
|
||||
provider, err = scm_provider.NewGitlabProvider(providerConfig.Group, token, providerConfig.API, providerConfig.AllBranches, providerConfig.IncludeSubgroups, providerConfig.WillIncludeSharedProjects(), providerConfig.Insecure, g.scmRootCAPath, providerConfig.Topic, caCerts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing Gitlab service: %w", err)
|
||||
}
|
||||
} else if providerConfig.Gitea != nil {
|
||||
case providerConfig.Gitea != nil:
|
||||
token, err := utils.GetSecretRef(ctx, g.client, providerConfig.Gitea.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Gitea token: %w", err)
|
||||
}
|
||||
provider, err = scm_provider.NewGiteaProvider(ctx, providerConfig.Gitea.Owner, token, providerConfig.Gitea.API, providerConfig.Gitea.AllBranches, providerConfig.Gitea.Insecure)
|
||||
provider, err = scm_provider.NewGiteaProvider(providerConfig.Gitea.Owner, token, providerConfig.Gitea.API, providerConfig.Gitea.AllBranches, providerConfig.Gitea.Insecure)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing Gitea service: %w", err)
|
||||
}
|
||||
} else if providerConfig.BitbucketServer != nil {
|
||||
case providerConfig.BitbucketServer != nil:
|
||||
providerConfig := providerConfig.BitbucketServer
|
||||
var caCerts []byte
|
||||
var scmError error
|
||||
@@ -183,49 +184,50 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
|
||||
return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError)
|
||||
}
|
||||
}
|
||||
if providerConfig.BearerToken != nil {
|
||||
switch {
|
||||
case providerConfig.BearerToken != nil:
|
||||
appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err)
|
||||
}
|
||||
provider, scmError = scm_provider.NewBitbucketServerProviderBearerToken(ctx, appToken, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
} else if providerConfig.BasicAuth != nil {
|
||||
case providerConfig.BasicAuth != nil:
|
||||
password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Secret token: %w", err)
|
||||
}
|
||||
provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
} else {
|
||||
default:
|
||||
provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts)
|
||||
}
|
||||
if scmError != nil {
|
||||
return nil, fmt.Errorf("error initializing Bitbucket Server service: %w", scmError)
|
||||
}
|
||||
} else if providerConfig.AzureDevOps != nil {
|
||||
case providerConfig.AzureDevOps != nil:
|
||||
token, err := utils.GetSecretRef(ctx, g.client, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Azure Devops access token: %w", err)
|
||||
}
|
||||
provider, err = scm_provider.NewAzureDevOpsProvider(ctx, token, providerConfig.AzureDevOps.Organization, providerConfig.AzureDevOps.API, providerConfig.AzureDevOps.TeamProject, providerConfig.AzureDevOps.AllBranches)
|
||||
provider, err = scm_provider.NewAzureDevOpsProvider(token, providerConfig.AzureDevOps.Organization, providerConfig.AzureDevOps.API, providerConfig.AzureDevOps.TeamProject, providerConfig.AzureDevOps.AllBranches)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing Azure Devops service: %w", err)
|
||||
}
|
||||
} else if providerConfig.Bitbucket != nil {
|
||||
case providerConfig.Bitbucket != nil:
|
||||
appPassword, err := utils.GetSecretRef(ctx, g.client, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Bitbucket cloud appPassword: %w", err)
|
||||
}
|
||||
provider, err = scm_provider.NewBitBucketCloudProvider(ctx, providerConfig.Bitbucket.Owner, providerConfig.Bitbucket.User, appPassword, providerConfig.Bitbucket.AllBranches)
|
||||
provider, err = scm_provider.NewBitBucketCloudProvider(providerConfig.Bitbucket.Owner, providerConfig.Bitbucket.User, appPassword, providerConfig.Bitbucket.AllBranches)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing Bitbucket cloud service: %w", err)
|
||||
}
|
||||
} else if providerConfig.AWSCodeCommit != nil {
|
||||
case providerConfig.AWSCodeCommit != nil:
|
||||
var awsErr error
|
||||
provider, awsErr = scm_provider.NewAWSCodeCommitProvider(ctx, providerConfig.AWSCodeCommit.TagFilters, providerConfig.AWSCodeCommit.Role, providerConfig.AWSCodeCommit.Region, providerConfig.AWSCodeCommit.AllBranches)
|
||||
if awsErr != nil {
|
||||
return nil, fmt.Errorf("error initializing AWS codecommit service: %w", awsErr)
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
return nil, errors.New("no SCM provider implementation configured")
|
||||
}
|
||||
|
||||
@@ -289,5 +291,5 @@ func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argop
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Github token: %w", err)
|
||||
}
|
||||
return scm_provider.NewGithubProvider(ctx, github.Organization, token, github.API, github.AllBranches)
|
||||
return scm_provider.NewGithubProvider(github.Organization, token, github.API, github.AllBranches)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package generators
|
||||
|
||||
type SCMGeneratorWithCustomApiUrl interface {
|
||||
type SCMGeneratorWithCustomApiUrl interface { //nolint:revive //FIXME(var-naming)
|
||||
CustomApiUrl() string
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import (
|
||||
func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, namespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator {
|
||||
terminalGenerators := map[string]Generator{
|
||||
"List": NewListGenerator(),
|
||||
"Clusters": NewClusterGenerator(c, ctx, k8sClient, namespace),
|
||||
"Clusters": NewClusterGenerator(ctx, c, k8sClient, namespace),
|
||||
"Git": NewGitGenerator(argoCDService, namespace),
|
||||
"SCMProvider": NewSCMProviderGenerator(c, scmConfig),
|
||||
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace),
|
||||
"PullRequest": NewPullRequestGenerator(c, scmConfig),
|
||||
"Plugin": NewPluginGenerator(c, ctx, k8sClient, namespace),
|
||||
"Plugin": NewPluginGenerator(ctx, c, k8sClient, namespace),
|
||||
}
|
||||
|
||||
nestedGenerators := map[string]Generator{
|
||||
|
||||
@@ -2,11 +2,10 @@ package metrics
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// Fake implementation for testing
|
||||
func NewFakeAppsetMetrics(client ctrlclient.WithWatch) *ApplicationsetMetrics {
|
||||
func NewFakeAppsetMetrics() *ApplicationsetMetrics {
|
||||
reconcileHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_appset_reconcile",
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1"
|
||||
metricsutil "github.com/argoproj/argo-cd/v3/util/metrics"
|
||||
"github.com/argoproj/argo-cd/v3/util/metrics/kubectl"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -57,6 +58,10 @@ func NewApplicationsetMetrics(appsetLister applisters.ApplicationSetLister, apps
|
||||
metrics.Registry.MustRegister(reconcileHistogram)
|
||||
metrics.Registry.MustRegister(appsetCollector)
|
||||
|
||||
kubectlMetricsServer := kubectl.NewKubectlMetrics()
|
||||
kubectlMetricsServer.RegisterWithClientGo()
|
||||
kubectl.RegisterWithPrometheus(metrics.Registry)
|
||||
|
||||
return ApplicationsetMetrics{
|
||||
reconcileHistogram: reconcileHistogram,
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func newClient(baseURL string, options ...ClientOptionFunc) (*Client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Client) NewRequest(method, path string, body any, options []ClientOptionFunc) (*http.Request, error) {
|
||||
func (c *Client) NewRequestWithContext(ctx context.Context, method, path string, body any) (*http.Request, error) {
|
||||
// Make sure the given URL end with a slash
|
||||
if !strings.HasSuffix(c.baseURL, "/") {
|
||||
c.baseURL += "/"
|
||||
@@ -82,7 +82,7 @@ func (c *Client) NewRequest(method, path string, body any, options []ClientOptio
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, c.baseURL+path, buf)
|
||||
req, err := http.NewRequestWithContext(ctx, method, c.baseURL+path, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func (c *Client) NewRequest(method, path string, body any, options []ClientOptio
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (c *Client) Do(ctx context.Context, req *http.Request, v any) (*http.Response, error) {
|
||||
func (c *Client) Do(req *http.Request, v any) (*http.Response, error) {
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,7 +2,6 @@ package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -15,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func TestClient(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err := w.Write([]byte("Hello, World!"))
|
||||
if err != nil {
|
||||
@@ -30,8 +29,6 @@ func TestClient(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClientDo(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
for _, c := range []struct {
|
||||
name string
|
||||
params map[string]string
|
||||
@@ -48,7 +45,7 @@ func TestClientDo(t *testing.T) {
|
||||
"pkey1": "val1",
|
||||
"pkey2": "val2",
|
||||
},
|
||||
fakeServer: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fakeServer: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err := w.Write([]byte(`[{
|
||||
"key1": "val1",
|
||||
@@ -120,12 +117,12 @@ func TestClientDo(t *testing.T) {
|
||||
client, err := NewClient(cc.fakeServer.URL, cc.clientOptionFns...)
|
||||
require.NoError(t, err, "NewClient returned unexpected error")
|
||||
|
||||
req, err := client.NewRequest("POST", "", cc.params, nil)
|
||||
req, err := client.NewRequestWithContext(t.Context(), http.MethodPost, "", cc.params)
|
||||
require.NoError(t, err, "NewRequest returned unexpected error")
|
||||
|
||||
var data []map[string]any
|
||||
|
||||
resp, err := client.Do(ctx, req, &data)
|
||||
resp, err := client.Do(req, &data)
|
||||
|
||||
if cc.expectedError != nil {
|
||||
assert.EqualError(t, err, cc.expectedError.Error())
|
||||
|
||||
38
applicationset/services/mocks/Repos.go
generated
38
applicationset/services/mocks/Repos.go
generated
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -13,9 +13,9 @@ type Repos struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// GetDirectories provides a mock function with given fields: ctx, repoURL, revision, noRevisionCache, verifyCommit
|
||||
func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool, verifyCommit bool) ([]string, error) {
|
||||
ret := _m.Called(ctx, repoURL, revision, noRevisionCache, verifyCommit)
|
||||
// GetDirectories provides a mock function with given fields: ctx, repoURL, revision, project, noRevisionCache, verifyCommit
|
||||
func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, project string, noRevisionCache bool, verifyCommit bool) ([]string, error) {
|
||||
ret := _m.Called(ctx, repoURL, revision, project, noRevisionCache, verifyCommit)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetDirectories")
|
||||
@@ -23,19 +23,19 @@ func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision st
|
||||
|
||||
var r0 []string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, bool, bool) ([]string, error)); ok {
|
||||
return rf(ctx, repoURL, revision, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) ([]string, error)); ok {
|
||||
return rf(ctx, repoURL, revision, project, noRevisionCache, verifyCommit)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, bool, bool) []string); ok {
|
||||
r0 = rf(ctx, repoURL, revision, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) []string); ok {
|
||||
r0 = rf(ctx, repoURL, revision, project, noRevisionCache, verifyCommit)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, bool, bool) error); ok {
|
||||
r1 = rf(ctx, repoURL, revision, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, bool, bool) error); ok {
|
||||
r1 = rf(ctx, repoURL, revision, project, noRevisionCache, verifyCommit)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -43,9 +43,9 @@ func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision st
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit
|
||||
func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool, verifyCommit bool) (map[string][]byte, error) {
|
||||
ret := _m.Called(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit)
|
||||
// GetFiles provides a mock function with given fields: ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit
|
||||
func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, project string, pattern string, noRevisionCache bool, verifyCommit bool) (map[string][]byte, error) {
|
||||
ret := _m.Called(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetFiles")
|
||||
@@ -53,19 +53,19 @@ func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string,
|
||||
|
||||
var r0 map[string][]byte
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) (map[string][]byte, error)); ok {
|
||||
return rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, bool, bool) (map[string][]byte, error)); ok {
|
||||
return rf(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool, bool) map[string][]byte); ok {
|
||||
r0 = rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, bool, bool) map[string][]byte); ok {
|
||||
r0 = rf(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(map[string][]byte)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, bool, bool) error); ok {
|
||||
r1 = rf(ctx, repoURL, revision, pattern, noRevisionCache, verifyCommit)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, bool, bool) error); ok {
|
||||
r1 = rf(ctx, repoURL, revision, project, pattern, noRevisionCache, verifyCommit)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ type Service struct {
|
||||
appSetName string
|
||||
}
|
||||
|
||||
func NewPluginService(ctx context.Context, appSetName string, baseURL string, token string, requestTimeout int) (*Service, error) {
|
||||
func NewPluginService(appSetName string, baseURL string, token string, requestTimeout int) (*Service, error) {
|
||||
var clientOptionFns []internalhttp.ClientOptionFunc
|
||||
|
||||
clientOptionFns = append(clientOptionFns, internalhttp.WithToken(token))
|
||||
@@ -55,14 +55,14 @@ func NewPluginService(ctx context.Context, appSetName string, baseURL string, to
|
||||
}
|
||||
|
||||
func (p *Service) List(ctx context.Context, parameters v1alpha1.PluginParameters) (*ServiceResponse, error) {
|
||||
req, err := p.client.NewRequest(http.MethodPost, "api/v1/getparams.execute", ServiceRequest{ApplicationSetName: p.appSetName, Input: v1alpha1.PluginInput{Parameters: parameters}}, nil)
|
||||
req, err := p.client.NewRequestWithContext(ctx, http.MethodPost, "api/v1/getparams.execute", ServiceRequest{ApplicationSetName: p.appSetName, Input: v1alpha1.PluginInput{Parameters: parameters}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewRequest returned unexpected error: %w", err)
|
||||
}
|
||||
|
||||
var data ServiceResponse
|
||||
|
||||
_, err = p.client.Do(ctx, req, &data)
|
||||
_, err = p.client.Do(req, &data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error get api '%s': %w", p.appSetName, err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -31,10 +30,10 @@ func TestPlugin(t *testing.T) {
|
||||
ts := httptest.NewServer(handler)
|
||||
defer ts.Close()
|
||||
|
||||
client, err := NewPluginService(context.Background(), "plugin-test", ts.URL, token, 0)
|
||||
client, err := NewPluginService("plugin-test", ts.URL, token, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
data, err := client.List(context.Background(), nil)
|
||||
data, err := client.List(t.Context(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var expectedData ServiceResponse
|
||||
|
||||
@@ -41,14 +41,14 @@ var (
|
||||
_ AzureDevOpsClientFactory = &devopsFactoryImpl{}
|
||||
)
|
||||
|
||||
func NewAzureDevOpsService(ctx context.Context, token, url, organization, project, repo string, labels []string) (PullRequestService, error) {
|
||||
organizationUrl := buildURL(url, organization)
|
||||
func NewAzureDevOpsService(token, url, organization, project, repo string, labels []string) (PullRequestService, error) {
|
||||
organizationURL := buildURL(url, organization)
|
||||
|
||||
var connection *azuredevops.Connection
|
||||
if token == "" {
|
||||
connection = azuredevops.NewAnonymousConnection(organizationUrl)
|
||||
connection = azuredevops.NewAnonymousConnection(organizationURL)
|
||||
} else {
|
||||
connection = azuredevops.NewPatConnection(organizationUrl, token)
|
||||
connection = azuredevops.NewPatConnection(organizationURL, token)
|
||||
}
|
||||
|
||||
return &AzureDevOpsService{
|
||||
|
||||
@@ -61,20 +61,20 @@ func (m *AzureClientFactoryMock) GetClient(ctx context.Context) (git.Client, err
|
||||
func TestListPullRequest(t *testing.T) {
|
||||
teamProject := "myorg_project"
|
||||
repoName := "myorg_project_repo"
|
||||
pr_id := 123
|
||||
pr_title := "feat(123)"
|
||||
pr_head_sha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056"
|
||||
ctx := context.Background()
|
||||
prID := 123
|
||||
prTitle := "feat(123)"
|
||||
prHeadSha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056"
|
||||
ctx := t.Context()
|
||||
uniqueName := "testName"
|
||||
|
||||
pullRequestMock := []git.GitPullRequest{
|
||||
{
|
||||
PullRequestId: createIntPtr(pr_id),
|
||||
Title: createStringPtr(pr_title),
|
||||
PullRequestId: createIntPtr(prID),
|
||||
Title: createStringPtr(prTitle),
|
||||
SourceRefName: createStringPtr("refs/heads/feature-branch"),
|
||||
TargetRefName: createStringPtr("refs/heads/main"),
|
||||
LastMergeSourceCommit: &git.GitCommitRef{
|
||||
CommitId: createStringPtr(pr_head_sha),
|
||||
CommitId: createStringPtr(prHeadSha),
|
||||
},
|
||||
Labels: &[]core.WebApiTagDefinition{},
|
||||
Repository: &git.GitRepository{
|
||||
@@ -108,9 +108,9 @@ func TestListPullRequest(t *testing.T) {
|
||||
assert.Len(t, list, 1)
|
||||
assert.Equal(t, "feature-branch", list[0].Branch)
|
||||
assert.Equal(t, "main", list[0].TargetBranch)
|
||||
assert.Equal(t, pr_head_sha, list[0].HeadSHA)
|
||||
assert.Equal(t, prHeadSha, list[0].HeadSHA)
|
||||
assert.Equal(t, "feat(123)", list[0].Title)
|
||||
assert.Equal(t, pr_id, list[0].Number)
|
||||
assert.Equal(t, prID, list[0].Number)
|
||||
assert.Equal(t, uniqueName, list[0].Author)
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ type PullRequestResponse struct {
|
||||
|
||||
var _ PullRequestService = (*BitbucketCloudService)(nil)
|
||||
|
||||
func parseUrl(uri string) (*url.URL, error) {
|
||||
func parseURL(uri string) (*url.URL, error) {
|
||||
if uri == "" {
|
||||
uri = "https://api.bitbucket.org/2.0"
|
||||
}
|
||||
@@ -65,10 +65,10 @@ func parseUrl(uri string) (*url.URL, error) {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func NewBitbucketCloudServiceBasicAuth(baseUrl, username, password, owner, repositorySlug string) (PullRequestService, error) {
|
||||
url, err := parseUrl(baseUrl)
|
||||
func NewBitbucketCloudServiceBasicAuth(baseURL, username, password, owner, repositorySlug string) (PullRequestService, error) {
|
||||
url, err := parseURL(baseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseUrl, owner, repositorySlug, err)
|
||||
return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseURL, owner, repositorySlug, err)
|
||||
}
|
||||
|
||||
bitbucketClient := bitbucket.NewBasicAuth(username, password)
|
||||
@@ -81,10 +81,10 @@ func NewBitbucketCloudServiceBasicAuth(baseUrl, username, password, owner, repos
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewBitbucketCloudServiceBearerToken(baseUrl, bearerToken, owner, repositorySlug string) (PullRequestService, error) {
|
||||
url, err := parseUrl(baseUrl)
|
||||
func NewBitbucketCloudServiceBearerToken(baseURL, bearerToken, owner, repositorySlug string) (PullRequestService, error) {
|
||||
url, err := parseURL(baseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseUrl, owner, repositorySlug, err)
|
||||
return nil, fmt.Errorf("error parsing base url of %s for %s/%s: %w", baseURL, owner, repositorySlug, err)
|
||||
}
|
||||
|
||||
bitbucketClient := bitbucket.NewOAuthbearerToken(bearerToken)
|
||||
@@ -97,9 +97,9 @@ func NewBitbucketCloudServiceBearerToken(baseUrl, bearerToken, owner, repository
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewBitbucketCloudServiceNoAuth(baseUrl, owner, repositorySlug string) (PullRequestService, error) {
|
||||
func NewBitbucketCloudServiceNoAuth(baseURL, owner, repositorySlug string) (PullRequestService, error) {
|
||||
// There is currently no method to explicitly not require auth
|
||||
return NewBitbucketCloudServiceBearerToken(baseUrl, "", owner, repositorySlug)
|
||||
return NewBitbucketCloudServiceBearerToken(baseURL, "", owner, repositorySlug)
|
||||
}
|
||||
|
||||
func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -54,11 +53,11 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
func TestParseUrlEmptyUrl(t *testing.T) {
|
||||
url, err := parseUrl("")
|
||||
bitbucketUrl, _ := url.Parse("https://api.bitbucket.org/2.0")
|
||||
url, err := parseURL("")
|
||||
bitbucketURL, _ := url.Parse("https://api.bitbucket.org/2.0")
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, bitbucketUrl, url)
|
||||
assert.Equal(t, bitbucketURL, url)
|
||||
}
|
||||
|
||||
func TestInvalidBaseUrlBasicAuthCloud(t *testing.T) {
|
||||
@@ -87,7 +86,7 @@ func TestListPullRequestBearerTokenCloud(t *testing.T) {
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketCloudServiceBearerToken(ts.URL, "TOKEN", "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -105,7 +104,7 @@ func TestListPullRequestNoAuthCloud(t *testing.T) {
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -123,7 +122,7 @@ func TestListPullRequestBasicAuthCloud(t *testing.T) {
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketCloudServiceBasicAuth(ts.URL, "user", "password", "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -214,7 +213,7 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 3)
|
||||
assert.Equal(t, PullRequest{
|
||||
@@ -241,12 +240,12 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestListResponseErrorCloud(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
_, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
_, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -270,7 +269,7 @@ func TestListResponseMalformedCloud(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
_, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
_, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -294,7 +293,7 @@ func TestListResponseMalformedValuesCloud(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
_, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
_, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -319,7 +318,7 @@ func TestListResponseEmptyCloud(t *testing.T) {
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, pullRequests)
|
||||
}
|
||||
@@ -406,7 +405,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
regexp := `feature-1[\d]{2}`
|
||||
svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
@@ -431,7 +430,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
regexp = `.*2$`
|
||||
svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
pullRequests, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
@@ -449,7 +448,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
regexp = `[\d{2}`
|
||||
svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO")
|
||||
require.NoError(t, err)
|
||||
_, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
_, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
@@ -64,9 +63,9 @@ func TestListPullRequestNoAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -165,9 +164,9 @@ func TestListPullRequestPagination(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 3)
|
||||
assert.Equal(t, PullRequest{
|
||||
@@ -207,9 +206,9 @@ func TestListPullRequestBasicAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -224,9 +223,9 @@ func TestListPullRequestBearerAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketServiceBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceBearerToken(t.Context(), "tolkien", ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, 101, pullRequests[0].Number)
|
||||
@@ -277,7 +276,7 @@ func TestListPullRequestTLS(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
var certs []byte
|
||||
if test.passCerts == true {
|
||||
if test.passCerts {
|
||||
for _, cert := range ts.TLS.Certificates {
|
||||
for _, c := range cert.Certificate {
|
||||
parsedCert, err := x509.ParseCertificate(c)
|
||||
@@ -290,9 +289,9 @@ func TestListPullRequestTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", test.tlsInsecure, certs)
|
||||
svc, err := NewBitbucketServiceBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", "REPO", "", test.tlsInsecure, certs)
|
||||
require.NoError(t, err)
|
||||
_, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
_, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
if test.requireErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
@@ -303,12 +302,12 @@ func TestListPullRequestTLS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestListResponseError(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
_, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
svc, _ := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
_, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -332,8 +331,8 @@ func TestListResponseMalformed(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
_, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
svc, _ := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
_, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -357,9 +356,9 @@ func TestListResponseEmpty(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, pullRequests)
|
||||
}
|
||||
@@ -453,9 +452,9 @@ func TestListPullRequestBranchMatch(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
regexp := `feature-1[\d]{2}`
|
||||
svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err := NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
pullRequests, err := ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
@@ -482,9 +481,9 @@ func TestListPullRequestBranchMatch(t *testing.T) {
|
||||
}, *pullRequests[1])
|
||||
|
||||
regexp = `.*2$`
|
||||
svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err = NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
pullRequests, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
@@ -502,9 +501,9 @@ func TestListPullRequestBranchMatch(t *testing.T) {
|
||||
}, *pullRequests[0])
|
||||
|
||||
regexp = `[\d{2}`
|
||||
svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
svc, err = NewBitbucketServiceNoAuth(t.Context(), ts.URL, "PROJECT", "REPO", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
_, err = ListPullRequests(t.Context(), svc, []v1alpha1.PullRequestGeneratorFilter{
|
||||
{
|
||||
BranchMatch: ®exp,
|
||||
},
|
||||
|
||||
@@ -18,6 +18,6 @@ func NewFakeService(_ context.Context, listPullReuests []*PullRequest, listError
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g *FakeService) List(ctx context.Context) ([]*PullRequest, error) {
|
||||
func (g *FakeService) List(_ context.Context) ([]*PullRequest, error) {
|
||||
return g.listPullReuests, g.listError
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ type GiteaService struct {
|
||||
|
||||
var _ PullRequestService = (*GiteaService)(nil)
|
||||
|
||||
func NewGiteaService(ctx context.Context, token, url, owner, repo string, insecure bool) (PullRequestService, error) {
|
||||
func NewGiteaService(token, url, owner, repo string, insecure bool) (PullRequestService, error) {
|
||||
if token == "" {
|
||||
token = os.Getenv("GITEA_TOKEN")
|
||||
}
|
||||
@@ -49,6 +49,7 @@ func (g *GiteaService) List(ctx context.Context) ([]*PullRequest, error) {
|
||||
opts := gitea.ListPullRequestsOptions{
|
||||
State: gitea.StateOpen,
|
||||
}
|
||||
g.client.SetContext(ctx)
|
||||
prs, _, err := g.client.ListRepoPullRequests(g.owner, g.repo, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -251,9 +250,9 @@ func TestGiteaList(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
giteaMockHandler(t)(w, r)
|
||||
}))
|
||||
host, err := NewGiteaService(context.Background(), "", ts.URL, "test-argocd", "pr-test", false)
|
||||
host, err := NewGiteaService("", ts.URL, "test-argocd", "pr-test", false)
|
||||
require.NoError(t, err)
|
||||
prs, err := host.List(context.Background())
|
||||
prs, err := host.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
assert.Equal(t, 1, prs[0].Number)
|
||||
|
||||
@@ -3,10 +3,10 @@ package pull_request
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-github/v66/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type GithubService struct {
|
||||
@@ -18,21 +18,15 @@ type GithubService struct {
|
||||
|
||||
var _ PullRequestService = (*GithubService)(nil)
|
||||
|
||||
func NewGithubService(ctx context.Context, token, url, owner, repo string, labels []string) (PullRequestService, error) {
|
||||
var ts oauth2.TokenSource
|
||||
func NewGithubService(token, url, owner, repo string, labels []string) (PullRequestService, error) {
|
||||
// Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits.
|
||||
if token == "" {
|
||||
token = os.Getenv("GITHUB_TOKEN")
|
||||
}
|
||||
if token != "" {
|
||||
ts = oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: token},
|
||||
)
|
||||
}
|
||||
httpClient := oauth2.NewClient(ctx, ts)
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -21,7 +21,7 @@ type GitLabService struct {
|
||||
|
||||
var _ PullRequestService = (*GitLabService)(nil)
|
||||
|
||||
func NewGitLabService(ctx context.Context, token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
|
||||
func NewGitLabService(token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
|
||||
var clientOptionFns []gitlab.ClientOptionFunc
|
||||
|
||||
// Set a custom Gitlab base URL if one is provided
|
||||
@@ -74,7 +74,7 @@ func (g *GitLabService) List(ctx context.Context) ([]*PullRequest, error) {
|
||||
|
||||
pullRequests := []*PullRequest{}
|
||||
for {
|
||||
mrs, resp, err := g.client.MergeRequests.ListProjectMergeRequests(g.project, opts)
|
||||
mrs, resp, err := g.client.MergeRequests.ListProjectMergeRequests(g.project, opts, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing merge requests for project '%s': %w", g.project, err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
@@ -35,10 +34,10 @@ func TestGitLabServiceCustomBaseURL(t *testing.T) {
|
||||
writeMRListResponse(t, w)
|
||||
})
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", nil, "", "", false, nil)
|
||||
svc, err := NewGitLabService("", server.URL, "278964", nil, "", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.List(context.Background())
|
||||
_, err = svc.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -54,10 +53,10 @@ func TestGitLabServiceToken(t *testing.T) {
|
||||
writeMRListResponse(t, w)
|
||||
})
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "token-123", server.URL, "278964", nil, "", "", false, nil)
|
||||
svc, err := NewGitLabService("token-123", server.URL, "278964", nil, "", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.List(context.Background())
|
||||
_, err = svc.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -73,10 +72,10 @@ func TestList(t *testing.T) {
|
||||
writeMRListResponse(t, w)
|
||||
})
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "", "", false, nil)
|
||||
svc, err := NewGitLabService("", server.URL, "278964", []string{}, "", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
prs, err := svc.List(context.Background())
|
||||
prs, err := svc.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
assert.Equal(t, 15442, prs[0].Number)
|
||||
@@ -99,10 +98,10 @@ func TestListWithLabels(t *testing.T) {
|
||||
writeMRListResponse(t, w)
|
||||
})
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil)
|
||||
svc, err := NewGitLabService("", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.List(context.Background())
|
||||
_, err = svc.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -118,10 +117,10 @@ func TestListWithState(t *testing.T) {
|
||||
writeMRListResponse(t, w)
|
||||
})
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "opened", "", false, nil)
|
||||
svc, err := NewGitLabService("", server.URL, "278964", []string{}, "opened", "", false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.List(context.Background())
|
||||
_, err = svc.List(t.Context())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -161,13 +160,13 @@ func TestListWithStateTLS(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
writeMRListResponse(t, w)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
var certs []byte
|
||||
if test.passCerts == true {
|
||||
if test.passCerts {
|
||||
for _, cert := range ts.TLS.Certificates {
|
||||
for _, c := range cert.Certificate {
|
||||
parsedCert, err := x509.ParseCertificate(c)
|
||||
@@ -180,10 +179,10 @@ func TestListWithStateTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
svc, err := NewGitLabService(context.Background(), "", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs)
|
||||
svc, err := NewGitLabService("", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.List(context.Background())
|
||||
_, err = svc.List(t.Context())
|
||||
if test.requireErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -16,7 +15,7 @@ func strp(s string) *string {
|
||||
|
||||
func TestFilterBranchMatchBadRegexp(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -34,13 +33,13 @@ func TestFilterBranchMatchBadRegexp(t *testing.T) {
|
||||
BranchMatch: strp("("),
|
||||
},
|
||||
}
|
||||
_, err := ListPullRequests(context.Background(), provider, filters)
|
||||
_, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestFilterBranchMatch(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -82,7 +81,7 @@ func TestFilterBranchMatch(t *testing.T) {
|
||||
BranchMatch: strp("w"),
|
||||
},
|
||||
}
|
||||
pullRequests, err := ListPullRequests(context.Background(), provider, filters)
|
||||
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, "two", pullRequests[0].Branch)
|
||||
@@ -90,7 +89,7 @@ func TestFilterBranchMatch(t *testing.T) {
|
||||
|
||||
func TestFilterTargetBranchMatch(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -132,7 +131,7 @@ func TestFilterTargetBranchMatch(t *testing.T) {
|
||||
TargetBranchMatch: strp("1"),
|
||||
},
|
||||
}
|
||||
pullRequests, err := ListPullRequests(context.Background(), provider, filters)
|
||||
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 1)
|
||||
assert.Equal(t, "two", pullRequests[0].Branch)
|
||||
@@ -140,7 +139,7 @@ func TestFilterTargetBranchMatch(t *testing.T) {
|
||||
|
||||
func TestMultiFilterOr(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -185,7 +184,7 @@ func TestMultiFilterOr(t *testing.T) {
|
||||
BranchMatch: strp("r"),
|
||||
},
|
||||
}
|
||||
pullRequests, err := ListPullRequests(context.Background(), provider, filters)
|
||||
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 3)
|
||||
assert.Equal(t, "two", pullRequests[0].Branch)
|
||||
@@ -195,7 +194,7 @@ func TestMultiFilterOr(t *testing.T) {
|
||||
|
||||
func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -242,7 +241,7 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) {
|
||||
TargetBranchMatch: strp("3"),
|
||||
},
|
||||
}
|
||||
pullRequests, err := ListPullRequests(context.Background(), provider, filters)
|
||||
pullRequests, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, pullRequests, 2)
|
||||
assert.Equal(t, "two", pullRequests[0].Branch)
|
||||
@@ -251,7 +250,7 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) {
|
||||
|
||||
func TestNoFilters(t *testing.T) {
|
||||
provider, _ := NewFakeService(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
[]*PullRequest{
|
||||
{
|
||||
Number: 1,
|
||||
@@ -273,7 +272,7 @@ func TestNoFilters(t *testing.T) {
|
||||
nil,
|
||||
)
|
||||
filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{}
|
||||
repos, err := ListPullRequests(context.Background(), provider, filters)
|
||||
repos, err := ListPullRequests(t.Context(), provider, filters)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
assert.Equal(t, "one", repos[0].Branch)
|
||||
|
||||
@@ -6,37 +6,52 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
type argoCDService struct {
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
storecreds git.CredsStore
|
||||
submoduleEnabled bool
|
||||
repoServerClientSet apiclient.Clientset
|
||||
newFileGlobbingEnabled bool
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
submoduleEnabled bool
|
||||
newFileGlobbingEnabled bool
|
||||
getGitFilesFromRepoServer func(ctx context.Context, req *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error)
|
||||
getGitDirectoriesFromRepoServer func(ctx context.Context, req *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error)
|
||||
}
|
||||
|
||||
type Repos interface {
|
||||
// GetFiles returns content of files (not directories) within the target repo
|
||||
GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error)
|
||||
GetFiles(ctx context.Context, repoURL, revision, project, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error)
|
||||
|
||||
// GetDirectories returns a list of directories (not files) within the target repo
|
||||
GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache, verifyCommit bool) ([]string, error)
|
||||
GetDirectories(ctx context.Context, repoURL, revision, project string, noRevisionCache, verifyCommit bool) ([]string, error)
|
||||
}
|
||||
|
||||
func NewArgoCDService(getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error), submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) (Repos, error) {
|
||||
func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) Repos {
|
||||
return &argoCDService{
|
||||
getRepository: getRepository,
|
||||
getRepository: db.GetRepository,
|
||||
submoduleEnabled: submoduleEnabled,
|
||||
repoServerClientSet: repoClientset,
|
||||
newFileGlobbingEnabled: newFileGlobbingEnabled,
|
||||
}, nil
|
||||
getGitFilesFromRepoServer: func(ctx context.Context, fileRequest *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) {
|
||||
closer, client, err := repoClientset.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing new repo server client: %w", err)
|
||||
}
|
||||
defer io.Close(closer)
|
||||
return client.GetGitFiles(ctx, fileRequest)
|
||||
},
|
||||
getGitDirectoriesFromRepoServer: func(ctx context.Context, dirRequest *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) {
|
||||
closer, client, err := repoClientset.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initialising new repo server client: %w", err)
|
||||
}
|
||||
defer io.Close(closer)
|
||||
return client.GetGitDirectories(ctx, dirRequest)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) {
|
||||
repo, err := a.getRepository(ctx, repoURL, "")
|
||||
func (a *argoCDService) GetFiles(ctx context.Context, repoURL, revision, project, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) {
|
||||
repo, err := a.getRepository(ctx, repoURL, project)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in GetRepository: %w", err)
|
||||
}
|
||||
@@ -50,21 +65,15 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s
|
||||
NoRevisionCache: noRevisionCache,
|
||||
VerifyCommit: verifyCommit,
|
||||
}
|
||||
closer, client, err := a.repoServerClientSet.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initialising new repo server client: %w", err)
|
||||
}
|
||||
defer io.Close(closer)
|
||||
|
||||
fileResponse, err := client.GetGitFiles(ctx, fileRequest)
|
||||
fileResponse, err := a.getGitFilesFromRepoServer(ctx, fileRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving Git files: %w", err)
|
||||
}
|
||||
return fileResponse.GetMap(), nil
|
||||
}
|
||||
|
||||
func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache, verifyCommit bool) ([]string, error) {
|
||||
repo, err := a.getRepository(ctx, repoURL, "")
|
||||
func (a *argoCDService) GetDirectories(ctx context.Context, repoURL, revision, project string, noRevisionCache, verifyCommit bool) ([]string, error) {
|
||||
repo, err := a.getRepository(ctx, repoURL, project)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in GetRepository: %w", err)
|
||||
}
|
||||
@@ -77,13 +86,7 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revi
|
||||
VerifyCommit: verifyCommit,
|
||||
}
|
||||
|
||||
closer, client, err := a.repoServerClientSet.NewRepoServerClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initialising new repo server client: %w", err)
|
||||
}
|
||||
defer io.Close(closer)
|
||||
|
||||
dirResponse, err := client.GetGitDirectories(ctx, dirRequest)
|
||||
dirResponse, err := a.getGitDirectoriesFromRepoServer(ctx, dirRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving Git Directories: %w", err)
|
||||
}
|
||||
|
||||
@@ -7,22 +7,21 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
repo_mocks "github.com/argoproj/argo-cd/v3/reposerver/apiclient/mocks"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
"github.com/argoproj/argo-cd/v3/util/settings"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
func TestGetDirectories(t *testing.T) {
|
||||
type fields struct {
|
||||
storecreds git.CredsStore
|
||||
submoduleEnabled bool
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient)
|
||||
submoduleEnabled bool
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
getGitDirectories func(ctx context.Context, req *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error)
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -39,58 +38,49 @@ func TestGetDirectories(t *testing.T) {
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{name: "ErrorGettingRepos", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return nil, errors.New("unable to get repos")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
{name: "ErrorGettingDirs", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(nil, errors.New("unable to get dirs"))
|
||||
},
|
||||
getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) {
|
||||
return nil, errors.New("unable to get dirs")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
{name: "HappyCase", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(&apiclient.GitDirectoriesResponse{
|
||||
Paths: []string{"foo", "foo/bar", "bar/foo"},
|
||||
}, nil)
|
||||
},
|
||||
getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) {
|
||||
return &apiclient.GitDirectoriesResponse{
|
||||
Paths: []string{"foo", "foo/bar", "bar/foo"},
|
||||
}, nil
|
||||
},
|
||||
}, args: args{}, want: []string{"foo", "foo/bar", "bar/foo"}, wantErr: assert.NoError},
|
||||
}, args: args{
|
||||
repoURL: "foo",
|
||||
}, want: []string{"foo", "foo/bar", "bar/foo"}, wantErr: assert.NoError},
|
||||
{name: "ErrorVerifyingCommit", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitDirectories", mock.Anything, mock.Anything).Return(nil, errors.New("revision HEAD is not signed"))
|
||||
},
|
||||
getGitDirectories: func(_ context.Context, _ *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) {
|
||||
return nil, errors.New("revision HEAD is not signed")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockRepoClient := &repo_mocks.RepoServerServiceClient{}
|
||||
// decorate the mocks
|
||||
for i := range tt.fields.repoServerClientFuncs {
|
||||
tt.fields.repoServerClientFuncs[i](mockRepoClient)
|
||||
}
|
||||
|
||||
a := &argoCDService{
|
||||
getRepository: tt.fields.getRepository,
|
||||
storecreds: tt.fields.storecreds,
|
||||
submoduleEnabled: tt.fields.submoduleEnabled,
|
||||
repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient},
|
||||
getRepository: tt.fields.getRepository,
|
||||
submoduleEnabled: tt.fields.submoduleEnabled,
|
||||
getGitDirectoriesFromRepoServer: tt.fields.getGitDirectories,
|
||||
}
|
||||
got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache, tt.args.verifyCommit)
|
||||
got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, "", tt.args.noRevisionCache, tt.args.verifyCommit)
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache)) {
|
||||
return
|
||||
}
|
||||
@@ -101,10 +91,9 @@ func TestGetDirectories(t *testing.T) {
|
||||
|
||||
func TestGetFiles(t *testing.T) {
|
||||
type fields struct {
|
||||
storecreds git.CredsStore
|
||||
submoduleEnabled bool
|
||||
repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient)
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
submoduleEnabled bool
|
||||
getRepository func(ctx context.Context, url, project string) (*v1alpha1.Repository, error)
|
||||
getGitFiles func(ctx context.Context, req *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error)
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -122,64 +111,55 @@ func TestGetFiles(t *testing.T) {
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{name: "ErrorGettingRepos", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return nil, errors.New("unable to get repos")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
{name: "ErrorGettingFiles", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitFiles", mock.Anything, mock.Anything).Return(nil, errors.New("unable to get files"))
|
||||
},
|
||||
getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) {
|
||||
return nil, errors.New("unable to get files")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
{name: "HappyCase", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitFiles", mock.Anything, mock.Anything).Return(&apiclient.GitFilesResponse{
|
||||
Map: map[string][]byte{
|
||||
"foo.json": []byte("hello: world!"),
|
||||
"bar.yaml": []byte("yay: appsets"),
|
||||
},
|
||||
}, nil)
|
||||
},
|
||||
getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) {
|
||||
return &apiclient.GitFilesResponse{
|
||||
Map: map[string][]byte{
|
||||
"foo.json": []byte("hello: world!"),
|
||||
"bar.yaml": []byte("yay: appsets"),
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}, args: args{}, want: map[string][]byte{
|
||||
}, args: args{
|
||||
repoURL: "foo",
|
||||
}, want: map[string][]byte{
|
||||
"foo.json": []byte("hello: world!"),
|
||||
"bar.yaml": []byte("yay: appsets"),
|
||||
}, wantErr: assert.NoError},
|
||||
{name: "ErrorVerifyingCommit", fields: fields{
|
||||
getRepository: func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
getRepository: func(_ context.Context, _, _ string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
},
|
||||
repoServerClientFuncs: []func(*repo_mocks.RepoServerServiceClient){
|
||||
func(client *repo_mocks.RepoServerServiceClient) {
|
||||
client.On("GetGitFiles", mock.Anything, mock.Anything).Return(nil, errors.New("revision HEAD is not signed"))
|
||||
},
|
||||
getGitFiles: func(_ context.Context, _ *apiclient.GitFilesRequest) (*apiclient.GitFilesResponse, error) {
|
||||
return nil, errors.New("revision HEAD is not signed")
|
||||
},
|
||||
}, args: args{}, want: nil, wantErr: assert.Error},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockRepoClient := &repo_mocks.RepoServerServiceClient{}
|
||||
// decorate the mocks
|
||||
for i := range tt.fields.repoServerClientFuncs {
|
||||
tt.fields.repoServerClientFuncs[i](mockRepoClient)
|
||||
}
|
||||
|
||||
a := &argoCDService{
|
||||
getRepository: tt.fields.getRepository,
|
||||
storecreds: tt.fields.storecreds,
|
||||
submoduleEnabled: tt.fields.submoduleEnabled,
|
||||
repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient},
|
||||
getRepository: tt.fields.getRepository,
|
||||
submoduleEnabled: tt.fields.submoduleEnabled,
|
||||
getGitFilesFromRepoServer: tt.fields.getGitFiles,
|
||||
}
|
||||
got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache, tt.args.verifyCommit)
|
||||
got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, "", tt.args.noRevisionCache, tt.args.verifyCommit)
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache)) {
|
||||
return
|
||||
}
|
||||
@@ -189,9 +169,9 @@ func TestGetFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewArgoCDService(t *testing.T) {
|
||||
service, err := NewArgoCDService(func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) {
|
||||
return &v1alpha1.Repository{}, nil
|
||||
}, false, &repo_mocks.Clientset{}, false)
|
||||
require.NoError(t, err)
|
||||
testNamespace := "test"
|
||||
clientset := fake.NewClientset()
|
||||
testDB := db.NewDB(testNamespace, settings.NewSettingsManager(t.Context(), clientset, testNamespace), clientset)
|
||||
service := NewArgoCDService(testDB, false, &repo_mocks.Clientset{}, false)
|
||||
assert.NotNil(t, service)
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import (
|
||||
|
||||
const (
|
||||
resourceTypeCodeCommitRepository = "codecommit:repository"
|
||||
prefixGitUrlHttps = "https://git-codecommit."
|
||||
prefixGitUrlHttpsFIPS = "https://git-codecommit-fips."
|
||||
prefixGitURLHTTPS = "https://git-codecommit."
|
||||
prefixGitURLHTTPSFIPS = "https://git-codecommit-fips."
|
||||
)
|
||||
|
||||
// AWSCodeCommitClient is a lean facade to the codecommitiface.CodeCommitAPI
|
||||
@@ -315,16 +315,16 @@ func getCodeCommitRepoName(repoArn string) (string, error) {
|
||||
// getCodeCommitFIPSEndpoint transforms provided https:// codecommit URL to a FIPS-compliant endpoint.
|
||||
// note that the specified region must support FIPS, otherwise the returned URL won't be reachable
|
||||
// see: https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html#regions-git
|
||||
func getCodeCommitFIPSEndpoint(repoUrl string) (string, error) {
|
||||
if strings.HasPrefix(repoUrl, prefixGitUrlHttpsFIPS) {
|
||||
log.Debugf("provided repoUrl %s is already a fips endpoint", repoUrl)
|
||||
return repoUrl, nil
|
||||
func getCodeCommitFIPSEndpoint(repoURL string) (string, error) {
|
||||
if strings.HasPrefix(repoURL, prefixGitURLHTTPSFIPS) {
|
||||
log.Debugf("provided repoUrl %s is already a fips endpoint", repoURL)
|
||||
return repoURL, nil
|
||||
}
|
||||
if !strings.HasPrefix(repoUrl, prefixGitUrlHttps) {
|
||||
return "", fmt.Errorf("the provided https endpoint isn't recognized, cannot be transformed to FIPS endpoint: %s", repoUrl)
|
||||
if !strings.HasPrefix(repoURL, prefixGitURLHTTPS) {
|
||||
return "", fmt.Errorf("the provided https endpoint isn't recognized, cannot be transformed to FIPS endpoint: %s", repoURL)
|
||||
}
|
||||
// we already have the prefix, so we guarantee to replace exactly the prefix only.
|
||||
return strings.Replace(repoUrl, prefixGitUrlHttps, prefixGitUrlHttpsFIPS, 1), nil
|
||||
return strings.Replace(repoURL, prefixGitURLHTTPS, prefixGitURLHTTPSFIPS, 1), nil
|
||||
}
|
||||
|
||||
func hasAwsError(err error, codes ...string) bool {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
"testing"
|
||||
@@ -23,7 +22,7 @@ type awsCodeCommitTestRepository struct {
|
||||
arn string
|
||||
accountId string
|
||||
defaultBranch string
|
||||
expectedCloneUrl string
|
||||
expectedCloneURL string
|
||||
getRepositoryError error
|
||||
getRepositoryNilMetadata bool
|
||||
valid bool
|
||||
@@ -49,7 +48,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) {
|
||||
id: "8235624d-d248-4df9-a983-2558b01dbe83",
|
||||
arn: "arn:aws:codecommit:us-east-1:111111111111:repo1",
|
||||
defaultBranch: "main",
|
||||
expectedCloneUrl: "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
expectedCloneURL: "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
valid: true,
|
||||
},
|
||||
},
|
||||
@@ -74,7 +73,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) {
|
||||
id: "8235624d-d248-4df9-a983-2558b01dbe83",
|
||||
arn: "arn:aws:codecommit:us-east-1:111111111111:repo1",
|
||||
defaultBranch: "main",
|
||||
expectedCloneUrl: "https://git-codecommit-fips.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
expectedCloneURL: "https://git-codecommit-fips.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
valid: true,
|
||||
},
|
||||
},
|
||||
@@ -96,7 +95,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) {
|
||||
id: "8235624d-d248-4df9-a983-2558b01dbe83",
|
||||
arn: "arn:aws:codecommit:us-east-1:111111111111:repo1",
|
||||
defaultBranch: "main",
|
||||
expectedCloneUrl: "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
expectedCloneURL: "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1",
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
@@ -160,7 +159,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
codeCommitClient := mocks.NewAWSCodeCommitClient(t)
|
||||
taggingClient := mocks.NewAWSTaggingClient(t)
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
codecommitRepoNameIdPairs := make([]*codecommit.RepositoryNameIdPair, 0)
|
||||
resourceTaggings := make([]*resourcegroupstaggingapi.ResourceTagMapping, 0)
|
||||
validRepositories := make([]*awsCodeCommitTestRepository, 0)
|
||||
@@ -226,7 +225,7 @@ func TestAWSCodeCommitListRepos(t *testing.T) {
|
||||
assert.Equal(t, originRepo.name, repo.Repository)
|
||||
assert.Equal(t, originRepo.id, repo.RepositoryId)
|
||||
assert.Equal(t, originRepo.defaultBranch, repo.Branch)
|
||||
assert.Equal(t, originRepo.expectedCloneUrl, repo.URL)
|
||||
assert.Equal(t, originRepo.expectedCloneURL, repo.URL)
|
||||
assert.Empty(t, repo.SHA, "SHA is always empty")
|
||||
}
|
||||
}
|
||||
@@ -349,7 +348,7 @@ func TestAWSCodeCommitRepoHasPath(t *testing.T) {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
codeCommitClient := mocks.NewAWSCodeCommitClient(t)
|
||||
taggingClient := mocks.NewAWSTaggingClient(t)
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
if testCase.expectedGetFolderPath != "" {
|
||||
codeCommitClient.
|
||||
On("GetFolderWithContext", ctx, &codecommit.GetFolderInput{
|
||||
@@ -382,7 +381,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) {
|
||||
id := "1a64adc4-2fb5-4abd-afe7-127984ba83c0"
|
||||
defaultBranch := "main"
|
||||
organization := "111111111111"
|
||||
cloneUrl := "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1"
|
||||
cloneURL := "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repo1"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -422,7 +421,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
codeCommitClient := mocks.NewAWSCodeCommitClient(t)
|
||||
taggingClient := mocks.NewAWSTaggingClient(t)
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
if testCase.allBranches {
|
||||
codeCommitClient.
|
||||
On("ListBranchesWithContext", ctx, &codecommit.ListBranchesInput{
|
||||
@@ -445,7 +444,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) {
|
||||
actual, err := provider.GetBranches(ctx, &Repository{
|
||||
Organization: organization,
|
||||
Repository: name,
|
||||
URL: cloneUrl,
|
||||
URL: cloneURL,
|
||||
RepositoryId: id,
|
||||
})
|
||||
if testCase.expectOverallError {
|
||||
@@ -454,7 +453,7 @@ func TestAWSCodeCommitGetBranches(t *testing.T) {
|
||||
assertCopiedProperties := func(repo *Repository) {
|
||||
assert.Equal(t, id, repo.RepositoryId)
|
||||
assert.Equal(t, name, repo.Repository)
|
||||
assert.Equal(t, cloneUrl, repo.URL)
|
||||
assert.Equal(t, cloneURL, repo.URL)
|
||||
assert.Equal(t, organization, repo.Organization)
|
||||
assert.Empty(t, repo.SHA)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ var (
|
||||
_ AzureDevOpsClientFactory = &devopsFactoryImpl{}
|
||||
)
|
||||
|
||||
func NewAzureDevOpsProvider(ctx context.Context, accessToken string, org string, url string, project string, allBranches bool) (*AzureDevOpsProvider, error) {
|
||||
func NewAzureDevOpsProvider(accessToken string, org string, url string, project string, allBranches bool) (*AzureDevOpsProvider, error) {
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("no access token provided")
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func NewAzureDevOpsProvider(ctx context.Context, accessToken string, org string,
|
||||
return &AzureDevOpsProvider{organization: org, teamProject: project, accessToken: accessToken, clientFactory: &devopsFactoryImpl{connection: connection}, allBranches: allBranches}, nil
|
||||
}
|
||||
|
||||
func (g *AzureDevOpsProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
func (g *AzureDevOpsProvider) ListRepos(ctx context.Context, _ string) ([]*Repository, error) {
|
||||
gitClient, err := g.clientFactory.GetClient(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get Azure DevOps client: %w", err)
|
||||
@@ -107,7 +107,7 @@ func (g *AzureDevOpsProvider) RepoHasPath(ctx context.Context, repo *Repository,
|
||||
}
|
||||
|
||||
var repoId string
|
||||
if uuid, isUuid := repo.RepositoryId.(uuid.UUID); isUuid { // most likely an UUID, but do type-safe check anyway. Do %v fallback if not expected type.
|
||||
if uuid, isUUID := repo.RepositoryId.(uuid.UUID); isUUID { // most likely an UUID, but do type-safe check anyway. Do %v fallback if not expected type.
|
||||
repoId = uuid.String()
|
||||
} else {
|
||||
repoId = fmt.Sprintf("%v", repo.RepositoryId)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestAzureDevopsRepoHasPath(t *testing.T) {
|
||||
path := "dir/subdir/item.yaml"
|
||||
branchName := "my/featurebranch"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
uuid := uuid.New().String()
|
||||
|
||||
testCases := []struct {
|
||||
@@ -115,7 +115,7 @@ func TestGetDefaultBranchOnDisabledRepo(t *testing.T) {
|
||||
repoName := "myorg_project_repo"
|
||||
defaultBranch := "main"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -174,7 +174,7 @@ func TestGetAllBranchesOnDisabledRepo(t *testing.T) {
|
||||
repoName := "myorg_project_repo"
|
||||
defaultBranch := "main"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -233,7 +233,7 @@ func TestAzureDevOpsGetDefaultBranchStripsRefsName(t *testing.T) {
|
||||
teamProject := "myorg_project"
|
||||
repoName := "myorg_project_repo"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
uuid := uuid.New().String()
|
||||
strippedBranchName := "somebranch"
|
||||
defaultBranch := fmt.Sprintf("refs/heads/%v", strippedBranchName)
|
||||
@@ -264,7 +264,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
|
||||
teamProject := "myorg_project"
|
||||
repoName := "myorg_project_repo"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
uuid := uuid.New().String()
|
||||
|
||||
defaultBranch := "main"
|
||||
@@ -272,7 +272,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedBranch *azureGit.GitBranchStats
|
||||
getBranchesApiError error
|
||||
getBranchesAPIError error
|
||||
clientError error
|
||||
}{
|
||||
{
|
||||
@@ -281,7 +281,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "GetBranches AllBranches false when request fails returns error and empty result",
|
||||
getBranchesApiError: errors.New("Remote Azure Devops GetBranches error"),
|
||||
getBranchesAPIError: errors.New("Remote Azure Devops GetBranches error"),
|
||||
},
|
||||
{
|
||||
name: "GetBranches AllBranches false when Azure DevOps client fails returns error",
|
||||
@@ -300,7 +300,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
|
||||
clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}}
|
||||
clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError)
|
||||
|
||||
gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(testCase.expectedBranch, testCase.getBranchesApiError)
|
||||
gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(testCase.expectedBranch, testCase.getBranchesAPIError)
|
||||
|
||||
repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch}
|
||||
|
||||
@@ -314,9 +314,9 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if testCase.getBranchesApiError != nil {
|
||||
if testCase.getBranchesAPIError != nil {
|
||||
assert.Empty(t, branches)
|
||||
require.ErrorContains(t, err, testCase.getBranchesApiError.Error())
|
||||
require.ErrorContains(t, err, testCase.getBranchesAPIError.Error())
|
||||
} else {
|
||||
if testCase.expectedBranch != nil {
|
||||
assert.NotEmpty(t, branches)
|
||||
@@ -335,13 +335,13 @@ func TestAzureDevopsGetBranches(t *testing.T) {
|
||||
teamProject := "myorg_project"
|
||||
repoName := "myorg_project_repo"
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
uuid := uuid.New().String()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedBranches *[]azureGit.GitBranchStats
|
||||
getBranchesApiError error
|
||||
getBranchesAPIError error
|
||||
clientError error
|
||||
allBranches bool
|
||||
expectedProcessingErrorMsg string
|
||||
@@ -353,7 +353,7 @@ func TestAzureDevopsGetBranches(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "GetBranches when Azure DevOps request fails returns error and empty result",
|
||||
getBranchesApiError: errors.New("Remote Azure Devops GetBranches error"),
|
||||
getBranchesAPIError: errors.New("Remote Azure Devops GetBranches error"),
|
||||
allBranches: true,
|
||||
},
|
||||
{
|
||||
@@ -384,7 +384,7 @@ func TestAzureDevopsGetBranches(t *testing.T) {
|
||||
clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}}
|
||||
clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError)
|
||||
|
||||
gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(testCase.expectedBranches, testCase.getBranchesApiError)
|
||||
gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(testCase.expectedBranches, testCase.getBranchesAPIError)
|
||||
|
||||
repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid}
|
||||
|
||||
@@ -403,9 +403,9 @@ func TestAzureDevopsGetBranches(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if testCase.getBranchesApiError != nil {
|
||||
if testCase.getBranchesAPIError != nil {
|
||||
assert.Empty(t, branches)
|
||||
require.ErrorContains(t, err, testCase.getBranchesApiError.Error())
|
||||
require.ErrorContains(t, err, testCase.getBranchesAPIError.Error())
|
||||
} else {
|
||||
if len(*testCase.expectedBranches) > 0 {
|
||||
assert.NotEmpty(t, branches)
|
||||
@@ -427,7 +427,7 @@ func TestGetAzureDevopsRepositories(t *testing.T) {
|
||||
teamProject := "myorg_project"
|
||||
|
||||
uuid := uuid.New()
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
repoId := &uuid
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func (c *ExtendedClient) GetContents(repo *Repository, path string) (bool, error
|
||||
|
||||
var _ SCMProviderService = &BitBucketCloudProvider{}
|
||||
|
||||
func NewBitBucketCloudProvider(ctx context.Context, owner string, user string, password string, allBranches bool) (*BitBucketCloudProvider, error) {
|
||||
func NewBitBucketCloudProvider(owner string, user string, password string, allBranches bool) (*BitBucketCloudProvider, error) {
|
||||
client := &ExtendedClient{
|
||||
bitbucket.NewBasicAuth(user, password),
|
||||
user,
|
||||
@@ -62,7 +62,7 @@ func NewBitBucketCloudProvider(ctx context.Context, owner string, user string, p
|
||||
return &BitBucketCloudProvider{client: client, owner: owner, allBranches: allBranches}, nil
|
||||
}
|
||||
|
||||
func (g *BitBucketCloudProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) {
|
||||
func (g *BitBucketCloudProvider) GetBranches(_ context.Context, repo *Repository) ([]*Repository, error) {
|
||||
repos := []*Repository{}
|
||||
branches, err := g.listBranches(repo)
|
||||
if err != nil {
|
||||
@@ -87,7 +87,7 @@ func (g *BitBucketCloudProvider) GetBranches(ctx context.Context, repo *Reposito
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (g *BitBucketCloudProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
func (g *BitBucketCloudProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
if cloneProtocol == "" {
|
||||
cloneProtocol = "ssh"
|
||||
}
|
||||
@@ -101,7 +101,7 @@ func (g *BitBucketCloudProvider) ListRepos(ctx context.Context, cloneProtocol st
|
||||
return nil, fmt.Errorf("error listing repositories for %s: %w", g.owner, err)
|
||||
}
|
||||
for _, bitBucketRepo := range accountReposResp.Items {
|
||||
cloneUrl, err := findCloneURL(cloneProtocol, &bitBucketRepo)
|
||||
cloneURL, err := findCloneURL(cloneProtocol, &bitBucketRepo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching clone url for repo %s: %w", bitBucketRepo.Slug, err)
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func (g *BitBucketCloudProvider) ListRepos(ctx context.Context, cloneProtocol st
|
||||
Organization: g.owner,
|
||||
Repository: bitBucketRepo.Slug,
|
||||
Branch: bitBucketRepo.Mainbranch.Name,
|
||||
URL: *cloneUrl,
|
||||
URL: *cloneURL,
|
||||
Labels: []string{},
|
||||
RepositoryId: bitBucketRepo.Uuid,
|
||||
})
|
||||
@@ -117,7 +117,7 @@ func (g *BitBucketCloudProvider) ListRepos(ctx context.Context, cloneProtocol st
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (g *BitBucketCloudProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) {
|
||||
func (g *BitBucketCloudProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) {
|
||||
contents, err := g.client.GetContents(repo, path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -87,14 +86,14 @@ func TestBitbucketHasRepo(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewBitBucketCloudProvider(context.Background(), c.owner, "user", "password", false)
|
||||
provider, _ := NewBitBucketCloudProvider(c.owner, "user", "password", false)
|
||||
repo := &Repository{
|
||||
Organization: c.owner,
|
||||
Repository: c.repo,
|
||||
SHA: c.sha,
|
||||
Branch: "main",
|
||||
}
|
||||
hasPath, err := provider.RepoHasPath(context.Background(), repo, c.path)
|
||||
hasPath, err := provider.RepoHasPath(t.Context(), repo, c.path)
|
||||
if err != nil {
|
||||
require.Error(t, fmt.Errorf("Error in test %w", err))
|
||||
}
|
||||
@@ -487,8 +486,8 @@ func TestBitbucketListRepos(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewBitBucketCloudProvider(context.Background(), c.owner, "user", "password", c.allBranches)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
provider, _ := NewBitBucketCloudProvider(c.owner, "user", "password", c.allBranches)
|
||||
rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
@@ -103,9 +102,9 @@ func TestListReposNoAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
verifyDefaultRepo(t, err, repos)
|
||||
}
|
||||
|
||||
@@ -195,9 +194,9 @@ func TestListReposPagination(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
assert.Equal(t, Repository{
|
||||
@@ -272,9 +271,9 @@ func TestGetBranchesBranchPagination(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.GetBranches(context.Background(), &Repository{
|
||||
repos, err := provider.GetBranches(t.Context(), &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git",
|
||||
@@ -307,8 +306,7 @@ func TestGetBranchesBranchPagination(t *testing.T) {
|
||||
func TestGetBranchesDefaultOnly(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
_, err := io.WriteString(w, `{
|
||||
"id": "refs/heads/default",
|
||||
"displayId": "default",
|
||||
@@ -325,9 +323,9 @@ func TestGetBranchesDefaultOnly(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.GetBranches(context.Background(), &Repository{
|
||||
repos, err := provider.GetBranches(t.Context(), &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git",
|
||||
@@ -350,16 +348,15 @@ func TestGetBranchesDefaultOnly(t *testing.T) {
|
||||
func TestGetBranchesMissingDefault(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
http.Error(w, "Not found", http.StatusNotFound)
|
||||
}
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.GetBranches(context.Background(), &Repository{
|
||||
repos, err := provider.GetBranches(t.Context(), &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git",
|
||||
@@ -371,17 +368,16 @@ func TestGetBranchesMissingDefault(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetBranchesEmptyRepo(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
return
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.GetBranches(context.Background(), &Repository{
|
||||
repos, err := provider.GetBranches(t.Context(), &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git",
|
||||
@@ -395,16 +391,15 @@ func TestGetBranchesEmptyRepo(t *testing.T) {
|
||||
func TestGetBranchesErrorDefaultBranch(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = provider.GetBranches(context.Background(), &Repository{
|
||||
_, err = provider.GetBranches(t.Context(), &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git",
|
||||
@@ -456,7 +451,7 @@ func TestListReposTLS(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
var certs []byte
|
||||
if test.passCerts == true {
|
||||
if test.passCerts {
|
||||
for _, cert := range ts.TLS.Certificates {
|
||||
for _, c := range cert.Certificate {
|
||||
parsedCert, err := x509.ParseCertificate(c)
|
||||
@@ -469,9 +464,9 @@ func TestListReposTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs)
|
||||
provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs)
|
||||
require.NoError(t, err)
|
||||
_, err = provider.ListRepos(context.Background(), "ssh")
|
||||
_, err = provider.ListRepos(t.Context(), "ssh")
|
||||
if test.requireErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
@@ -488,9 +483,9 @@ func TestListReposBasicAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
verifyDefaultRepo(t, err, repos)
|
||||
}
|
||||
|
||||
@@ -501,17 +496,16 @@ func TestListReposBearerAuth(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderBearerToken(t.Context(), "tolkien", ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
verifyDefaultRepo(t, err, repos)
|
||||
}
|
||||
|
||||
func TestListReposDefaultBranch(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
_, err := io.WriteString(w, `{
|
||||
"id": "refs/heads/default",
|
||||
"displayId": "default",
|
||||
@@ -528,9 +522,9 @@ func TestListReposDefaultBranch(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 1)
|
||||
assert.Equal(t, Repository{
|
||||
@@ -547,16 +541,15 @@ func TestListReposDefaultBranch(t *testing.T) {
|
||||
func TestListReposMissingDefaultBranch(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
http.Error(w, "Not found", http.StatusNotFound)
|
||||
}
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "ssh")
|
||||
repos, err := provider.ListRepos(t.Context(), "ssh")
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, repos)
|
||||
}
|
||||
@@ -564,16 +557,15 @@ func TestListReposMissingDefaultBranch(t *testing.T) {
|
||||
func TestListReposErrorDefaultBranch(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Empty(t, r.Header.Get("Authorization"))
|
||||
switch r.RequestURI {
|
||||
case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default":
|
||||
if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = provider.ListRepos(context.Background(), "ssh")
|
||||
_, err = provider.ListRepos(t.Context(), "ssh")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -583,9 +575,9 @@ func TestListReposCloneProtocol(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repos, err := provider.ListRepos(context.Background(), "https")
|
||||
repos, err := provider.ListRepos(t.Context(), "https")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 1)
|
||||
assert.Equal(t, Repository{
|
||||
@@ -605,9 +597,9 @@ func TestListReposUnknownProtocol(t *testing.T) {
|
||||
defaultHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
_, errProtocol := provider.ListRepos(context.Background(), "http")
|
||||
_, errProtocol := provider.ListRepos(t.Context(), "http")
|
||||
require.Error(t, errProtocol)
|
||||
}
|
||||
|
||||
@@ -643,37 +635,37 @@ func TestBitbucketServerHasPath(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil)
|
||||
require.NoError(t, err)
|
||||
repo := &Repository{
|
||||
Organization: "PROJECT",
|
||||
Repository: "REPO",
|
||||
Branch: "main",
|
||||
}
|
||||
ok, err := provider.RepoHasPath(context.Background(), repo, "pkg")
|
||||
ok, err := provider.RepoHasPath(t.Context(), repo, "pkg")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
ok, err = provider.RepoHasPath(context.Background(), repo, "pkg/")
|
||||
ok, err = provider.RepoHasPath(t.Context(), repo, "pkg/")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/file.txt")
|
||||
ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/file.txt")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/missing.txt")
|
||||
ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/missing.txt")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, ok)
|
||||
|
||||
ok, err = provider.RepoHasPath(context.Background(), repo, "notathing")
|
||||
ok, err = provider.RepoHasPath(t.Context(), repo, "notathing")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, ok)
|
||||
|
||||
ok, err = provider.RepoHasPath(context.Background(), repo, "return-redirect")
|
||||
ok, err = provider.RepoHasPath(t.Context(), repo, "return-redirect")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
_, err = provider.RepoHasPath(context.Background(), repo, "unauthorized-response")
|
||||
_, err = provider.RepoHasPath(t.Context(), repo, "unauthorized-response")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ type GiteaProvider struct {
|
||||
|
||||
var _ SCMProviderService = &GiteaProvider{}
|
||||
|
||||
func NewGiteaProvider(ctx context.Context, owner, token, url string, allBranches, insecure bool) (*GiteaProvider, error) {
|
||||
func NewGiteaProvider(owner, token, url string, allBranches, insecure bool) (*GiteaProvider, error) {
|
||||
if token == "" {
|
||||
token = os.Getenv("GITEA_TOKEN")
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func NewGiteaProvider(ctx context.Context, owner, token, url string, allBranches
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g *GiteaProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) {
|
||||
func (g *GiteaProvider) GetBranches(_ context.Context, repo *Repository) ([]*Repository, error) {
|
||||
if !g.allBranches {
|
||||
branch, status, err := g.client.GetRepoBranch(g.owner, repo.Repository, repo.Branch)
|
||||
if status.StatusCode == http.StatusNotFound {
|
||||
@@ -87,7 +87,7 @@ func (g *GiteaProvider) GetBranches(ctx context.Context, repo *Repository) ([]*R
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (g *GiteaProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
func (g *GiteaProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
repos := []*Repository{}
|
||||
repoOpts := gitea.ListOrgReposOptions{}
|
||||
giteaRepos, _, err := g.client.ListOrgRepos(g.owner, repoOpts)
|
||||
@@ -126,7 +126,7 @@ func (g *GiteaProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (g *GiteaProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) {
|
||||
func (g *GiteaProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) {
|
||||
_, resp, err := g.client.GetContents(repo.Organization, repo.Repository, repo.Branch, path)
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
return false, nil
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -304,8 +303,8 @@ func TestGiteaListRepos(t *testing.T) {
|
||||
defer ts.Close()
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGiteaProvider(context.Background(), "test-argocd", "", ts.URL, c.allBranches, false)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
provider, _ := NewGiteaProvider("test-argocd", "", ts.URL, c.allBranches, false)
|
||||
rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
@@ -334,7 +333,7 @@ func TestGiteaHasPath(t *testing.T) {
|
||||
giteaMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGiteaProvider(context.Background(), "gitea", "", ts.URL, false, false)
|
||||
host, _ := NewGiteaProvider("gitea", "", ts.URL, false, false)
|
||||
repo := &Repository{
|
||||
Organization: "gitea",
|
||||
Repository: "go-sdk",
|
||||
@@ -342,19 +341,19 @@ func TestGiteaHasPath(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("file exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "README.md")
|
||||
ok, err := host.RepoHasPath(t.Context(), repo, "README.md")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("directory exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "gitea")
|
||||
ok, err := host.RepoHasPath(t.Context(), repo, "gitea")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("does not exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "notathing")
|
||||
ok, err := host.RepoHasPath(t.Context(), repo, "notathing")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, ok)
|
||||
})
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/google/go-github/v66/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type GithubProvider struct {
|
||||
@@ -18,21 +17,15 @@ type GithubProvider struct {
|
||||
|
||||
var _ SCMProviderService = &GithubProvider{}
|
||||
|
||||
func NewGithubProvider(ctx context.Context, organization string, token string, url string, allBranches bool) (*GithubProvider, error) {
|
||||
var ts oauth2.TokenSource
|
||||
func NewGithubProvider(organization string, token string, url string, allBranches bool) (*GithubProvider, error) {
|
||||
// Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits.
|
||||
if token == "" {
|
||||
token = os.Getenv("GITHUB_TOKEN")
|
||||
}
|
||||
if token != "" {
|
||||
ts = oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: token},
|
||||
)
|
||||
}
|
||||
httpClient := oauth2.NewClient(ctx, ts)
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -243,8 +242,8 @@ func TestGithubListRepos(t *testing.T) {
|
||||
defer ts.Close()
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, c.allBranches)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
provider, _ := NewGithubProvider("argoproj", "", ts.URL, c.allBranches)
|
||||
rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
@@ -273,17 +272,17 @@ func TestGithubHasPath(t *testing.T) {
|
||||
githubMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false)
|
||||
host, _ := NewGithubProvider("argoproj", "", ts.URL, false)
|
||||
repo := &Repository{
|
||||
Organization: "argoproj",
|
||||
Repository: "argo-cd",
|
||||
Branch: "master",
|
||||
}
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "pkg/")
|
||||
ok, err := host.RepoHasPath(t.Context(), repo, "pkg/")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
ok, err = host.RepoHasPath(context.Background(), repo, "notathing/")
|
||||
ok, err = host.RepoHasPath(t.Context(), repo, "notathing/")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, ok)
|
||||
}
|
||||
@@ -293,13 +292,13 @@ func TestGithubGetBranches(t *testing.T) {
|
||||
githubMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false)
|
||||
host, _ := NewGithubProvider("argoproj", "", ts.URL, false)
|
||||
repo := &Repository{
|
||||
Organization: "argoproj",
|
||||
Repository: "argo-cd",
|
||||
Branch: "master",
|
||||
}
|
||||
repos, err := host.GetBranches(context.Background(), repo)
|
||||
repos, err := host.GetBranches(t.Context(), repo)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
@@ -311,12 +310,12 @@ func TestGithubGetBranches(t *testing.T) {
|
||||
Repository: "applicationset",
|
||||
Branch: "main",
|
||||
}
|
||||
_, err = host.GetBranches(context.Background(), repo2)
|
||||
_, err = host.GetBranches(t.Context(), repo2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Get all branches
|
||||
host.allBranches = true
|
||||
repos, err = host.GetBranches(context.Background(), repo)
|
||||
repos, err = host.GetBranches(t.Context(), repo)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
|
||||
@@ -2,10 +2,10 @@ package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
pathpkg "path"
|
||||
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
gitlab "gitlab.com/gitlab-org/api/client-go"
|
||||
@@ -24,7 +24,7 @@ type GitlabProvider struct {
|
||||
|
||||
var _ SCMProviderService = &GitlabProvider{}
|
||||
|
||||
func NewGitlabProvider(ctx context.Context, organization string, token string, url string, allBranches, includeSubgroups, includeSharedProjects, insecure bool, scmRootCAPath, topic string, caCerts []byte) (*GitlabProvider, error) {
|
||||
func NewGitlabProvider(organization string, token string, url string, allBranches, includeSubgroups, includeSharedProjects, insecure bool, scmRootCAPath, topic string, caCerts []byte) (*GitlabProvider, error) {
|
||||
// Undocumented environment variable to set a default token, to be used in testing to dodge anonymous rate limits.
|
||||
if token == "" {
|
||||
token = os.Getenv("GITLAB_TOKEN")
|
||||
@@ -75,7 +75,7 @@ func (g *GitlabProvider) GetBranches(ctx context.Context, repo *Repository) ([]*
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (g *GitlabProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
func (g *GitlabProvider) ListRepos(_ context.Context, cloneProtocol string) ([]*Repository, error) {
|
||||
opt := &gitlab.ListGroupProjectsOptions{
|
||||
ListOptions: gitlab.ListOptions{PerPage: 100},
|
||||
IncludeSubGroups: &g.includeSubgroups,
|
||||
@@ -129,40 +129,31 @@ func (g *GitlabProvider) ListRepos(ctx context.Context, cloneProtocol string) ([
|
||||
func (g *GitlabProvider) RepoHasPath(_ context.Context, repo *Repository, path string) (bool, error) {
|
||||
p, _, err := g.client.Projects.GetProject(repo.Organization+"/"+repo.Repository, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, fmt.Errorf("error getting Project Info: %w", err)
|
||||
}
|
||||
directories := []string{
|
||||
path,
|
||||
pathpkg.Dir(path),
|
||||
}
|
||||
for _, directory := range directories {
|
||||
options := gitlab.ListTreeOptions{
|
||||
Path: &directory,
|
||||
Ref: &repo.Branch,
|
||||
}
|
||||
for {
|
||||
treeNode, resp, err := g.client.Repositories.ListTree(p.ID, &options)
|
||||
|
||||
// search if the path is a file and exists in the repo
|
||||
fileOptions := gitlab.GetFileOptions{Ref: &repo.Branch}
|
||||
_, _, err = g.client.RepositoryFiles.GetFile(p.ID, path, &fileOptions)
|
||||
if err != nil {
|
||||
if errors.Is(err, gitlab.ErrNotFound) {
|
||||
// no file found, check for a directory
|
||||
options := gitlab.ListTreeOptions{
|
||||
Path: &path,
|
||||
Ref: &repo.Branch,
|
||||
}
|
||||
_, _, err := g.client.Repositories.ListTree(p.ID, &options)
|
||||
if err != nil {
|
||||
if errors.Is(err, gitlab.ErrNotFound) {
|
||||
return false, nil // no file or directory found
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if path == directory {
|
||||
if resp.TotalItems > 0 {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
for i := range treeNode {
|
||||
if treeNode[i].Path == path {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
if resp.NextPage == 0 {
|
||||
// no future pages
|
||||
break
|
||||
}
|
||||
options.Page = resp.NextPage
|
||||
return true, nil // directory found
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
return true, nil // file found
|
||||
}
|
||||
|
||||
func (g *GitlabProvider) listBranches(_ context.Context, repo *Repository) ([]gitlab.Branch, error) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
@@ -20,6 +19,7 @@ func gitlabMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
t.Helper()
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
fmt.Println(r.RequestURI)
|
||||
switch r.RequestURI {
|
||||
case "/api/v4":
|
||||
fmt.Println("here1")
|
||||
@@ -1040,6 +1040,32 @@ func gitlabMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
// Recent versions of the Gitlab API (v17.7+) listTree return 404 not only when a file doesn't exist, but also
|
||||
// when a path is to a file instead of a directory. Code was refactored to explicitly search for file then
|
||||
// search for directory, catching 404 errors as "file not found".
|
||||
case "/api/v4/projects/27084533/repository/files/argocd?ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/files/argocd%2Finstall%2Eyaml?ref=master":
|
||||
_, err := io.WriteString(w, `{"file_name":"install.yaml","file_path":"argocd/install.yaml","size":0,"encoding":"base64","content_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","ref":"main","blob_id":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391","commit_id":"6d4c0f9d34534ccc73aa3f3180b25e2aebe630eb","last_commit_id":"b50eb63f9c0e09bfdb070db26fd32c7210291f52","execute_filemode":false,"content":""}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/27084533/repository/files/notathing?ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/tree?path=notathing&ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/files/argocd%2Fnotathing%2Eyaml?ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/tree?path=argocd%2Fnotathing.yaml&ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/files/notathing%2Fnotathing%2Eyaml?ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/tree?path=notathing%2Fnotathing.yaml&ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/files/notathing%2Fnotathing%2Fnotathing%2Eyaml?ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/tree?path=notathing%2Fnotathing%2Fnotathing.yaml&ref=master":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case "/api/v4/projects/27084533/repository/branches/foo":
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
default:
|
||||
@@ -1124,8 +1150,8 @@ func TestGitlabListRepos(t *testing.T) {
|
||||
}))
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups, c.includeSharedProjects, c.insecure, "", c.topic, nil)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
provider, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups, c.includeSharedProjects, c.insecure, "", c.topic, nil)
|
||||
rawRepos, err := ListRepos(t.Context(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
@@ -1163,7 +1189,7 @@ func TestGitlabHasPath(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gitlabMockHandler(t)(w, r)
|
||||
}))
|
||||
host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil)
|
||||
host, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil)
|
||||
repo := &Repository{
|
||||
Organization: "test-argocd-proton",
|
||||
Repository: "argocd",
|
||||
@@ -1194,11 +1220,21 @@ func TestGitlabHasPath(t *testing.T) {
|
||||
path: "argocd/notathing.yaml",
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
name: "noexistent file in noexistent directory",
|
||||
path: "notathing/notathing.yaml",
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
name: "noexistent file in nested noexistent directory",
|
||||
path: "notathing/notathing/notathing.yaml",
|
||||
exists: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, c.path)
|
||||
ok, err := host.RepoHasPath(t.Context(), repo, c.path)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, c.exists, ok)
|
||||
})
|
||||
@@ -1209,14 +1245,14 @@ func TestGitlabGetBranches(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gitlabMockHandler(t)(w, r)
|
||||
}))
|
||||
host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil)
|
||||
host, _ := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil)
|
||||
|
||||
repo := &Repository{
|
||||
RepositoryId: 27084533,
|
||||
Branch: "master",
|
||||
}
|
||||
t.Run("branch exists", func(t *testing.T) {
|
||||
repos, err := host.GetBranches(context.Background(), repo)
|
||||
repos, err := host.GetBranches(t.Context(), repo)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "master", repos[0].Branch)
|
||||
})
|
||||
@@ -1226,7 +1262,7 @@ func TestGitlabGetBranches(t *testing.T) {
|
||||
Branch: "foo",
|
||||
}
|
||||
t.Run("unknown branch", func(t *testing.T) {
|
||||
_, err := host.GetBranches(context.Background(), repo2)
|
||||
_, err := host.GetBranches(t.Context(), repo2)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
@@ -1273,7 +1309,7 @@ func TestGetBranchesTLS(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
var certs []byte
|
||||
if test.passCerts == true {
|
||||
if test.passCerts {
|
||||
for _, cert := range ts.TLS.Certificates {
|
||||
for _, c := range cert.Certificate {
|
||||
parsedCert, err := x509.ParseCertificate(c)
|
||||
@@ -1286,13 +1322,13 @@ func TestGetBranchesTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
host, err := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, test.tlsInsecure, "", "", certs)
|
||||
host, err := NewGitlabProvider("test-argocd-proton", "", ts.URL, false, true, true, test.tlsInsecure, "", "", certs)
|
||||
require.NoError(t, err)
|
||||
repo := &Repository{
|
||||
RepositoryId: 27084533,
|
||||
Branch: "master",
|
||||
}
|
||||
_, err = host.GetBranches(context.Background(), repo)
|
||||
_, err = host.GetBranches(t.Context(), repo)
|
||||
if test.requireErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
@@ -37,7 +36,7 @@ func TestFilterRepoMatch(t *testing.T) {
|
||||
RepositoryMatch: strp("n|hr"),
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
assert.Equal(t, "one", repos[0].Repository)
|
||||
@@ -66,7 +65,7 @@ func TestFilterLabelMatch(t *testing.T) {
|
||||
LabelMatch: strp("^prod-.*$"),
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
assert.Equal(t, "one", repos[0].Repository)
|
||||
@@ -92,7 +91,7 @@ func TestFilterPathExists(t *testing.T) {
|
||||
PathsExist: []string{"two"},
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 1)
|
||||
assert.Equal(t, "two", repos[0].Repository)
|
||||
@@ -117,7 +116,7 @@ func TestFilterPathDoesntExists(t *testing.T) {
|
||||
PathsDoNotExist: []string{"two"},
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func TestFilterRepoMatchBadRegexp(t *testing.T) {
|
||||
RepositoryMatch: strp("("),
|
||||
},
|
||||
}
|
||||
_, err := ListRepos(context.Background(), provider, filters, "")
|
||||
_, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -152,7 +151,7 @@ func TestFilterLabelMatchBadRegexp(t *testing.T) {
|
||||
LabelMatch: strp("("),
|
||||
},
|
||||
}
|
||||
_, err := ListRepos(context.Background(), provider, filters, "")
|
||||
_, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -186,7 +185,7 @@ func TestFilterBranchMatch(t *testing.T) {
|
||||
BranchMatch: strp("w"),
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 2)
|
||||
assert.Equal(t, "one", repos[0].Repository)
|
||||
@@ -218,7 +217,7 @@ func TestMultiFilterAnd(t *testing.T) {
|
||||
LabelMatch: strp("^prod-.*$"),
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 1)
|
||||
assert.Equal(t, "two", repos[0].Repository)
|
||||
@@ -249,7 +248,7 @@ func TestMultiFilterOr(t *testing.T) {
|
||||
LabelMatch: strp("^prod-.*$"),
|
||||
},
|
||||
}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 3)
|
||||
assert.Equal(t, "one", repos[0].Repository)
|
||||
@@ -275,7 +274,7 @@ func TestNoFilters(t *testing.T) {
|
||||
},
|
||||
}
|
||||
filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{}
|
||||
repos, err := ListRepos(context.Background(), provider, filters, "")
|
||||
repos, err := ListRepos(t.Context(), provider, filters, "")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, repos, 3)
|
||||
assert.Equal(t, "one", repos[0].Repository)
|
||||
|
||||
@@ -7,31 +7,17 @@ import (
|
||||
func BuildResourceStatus(statusMap map[string]argov1alpha1.ResourceStatus, apps []argov1alpha1.Application) map[string]argov1alpha1.ResourceStatus {
|
||||
appMap := map[string]argov1alpha1.Application{}
|
||||
for _, app := range apps {
|
||||
appCopy := app
|
||||
appMap[app.Name] = app
|
||||
|
||||
gvk := app.GroupVersionKind()
|
||||
// Create status if it does not exist
|
||||
status, ok := statusMap[app.Name]
|
||||
if !ok {
|
||||
status = argov1alpha1.ResourceStatus{
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind,
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
Status: app.Status.Sync.Status,
|
||||
Health: &appCopy.Status.Health,
|
||||
}
|
||||
}
|
||||
|
||||
var status argov1alpha1.ResourceStatus
|
||||
status.Group = gvk.Group
|
||||
status.Version = gvk.Version
|
||||
status.Kind = gvk.Kind
|
||||
status.Name = app.Name
|
||||
status.Namespace = app.Namespace
|
||||
status.Status = app.Status.Sync.Status
|
||||
status.Health = &appCopy.Status.Health
|
||||
status.Health = app.Status.Health.DeepCopy()
|
||||
|
||||
statusMap[app.Name] = status
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func NewAppsetLister(client ctrlclient.Client) ApplicationSetLister {
|
||||
return &AppsetLister{Client: client}
|
||||
}
|
||||
|
||||
func (l *AppsetLister) List(selector labels.Selector) (ret []*ApplicationSet, err error) {
|
||||
func (l *AppsetLister) List(_ labels.Selector) (ret []*ApplicationSet, err error) {
|
||||
return clientListAppsets(l.Client, ctrlclient.ListOptions{})
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ type appsetNamespaceLister struct {
|
||||
Namespace string
|
||||
}
|
||||
|
||||
func (n *appsetNamespaceLister) List(selector labels.Selector) (ret []*ApplicationSet, err error) {
|
||||
func (n *appsetNamespaceLister) List(_ labels.Selector) (ret []*ApplicationSet, err error) {
|
||||
return clientListAppsets(n.Client, ctrlclient.ListOptions{Namespace: n.Namespace})
|
||||
}
|
||||
|
||||
func (n *appsetNamespaceLister) Get(name string) (*ApplicationSet, error) {
|
||||
func (n *appsetNamespaceLister) Get(_ string) (*ApplicationSet, error) {
|
||||
appset := ApplicationSet{}
|
||||
err := n.Client.Get(context.TODO(), ctrlclient.ObjectKeyFromObject(&appset), &appset)
|
||||
return &appset, err
|
||||
|
||||
@@ -3,7 +3,6 @@ package utils
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
@@ -13,16 +12,14 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
var (
|
||||
localCluster = appv1.Cluster{
|
||||
Name: "in-cluster",
|
||||
Server: appv1.KubernetesInternalAPIServerAddr,
|
||||
ConnectionState: appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful},
|
||||
}
|
||||
initLocalCluster sync.Once
|
||||
)
|
||||
// ClusterSpecifier contains only the name and server URL of a cluster. We use this struct to avoid partially-populating
|
||||
// the full Cluster struct, which would be misleading.
|
||||
type ClusterSpecifier struct {
|
||||
Name string
|
||||
Server string
|
||||
}
|
||||
|
||||
func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace string) (*appv1.ClusterList, error) {
|
||||
func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace string) ([]ClusterSpecifier, error) {
|
||||
clusterSecretsList, err := clientset.CoreV1().Secrets(namespace).List(ctx,
|
||||
metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster})
|
||||
if err != nil {
|
||||
@@ -35,54 +32,29 @@ func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace
|
||||
|
||||
clusterSecrets := clusterSecretsList.Items
|
||||
|
||||
clusterList := appv1.ClusterList{
|
||||
Items: make([]appv1.Cluster, len(clusterSecrets)),
|
||||
}
|
||||
clusterList := make([]ClusterSpecifier, len(clusterSecrets))
|
||||
|
||||
hasInClusterCredentials := false
|
||||
for i, clusterSecret := range clusterSecrets {
|
||||
// This line has changed from the original Argo CD code: now receives an error, and handles it
|
||||
cluster, err := db.SecretToCluster(&clusterSecret)
|
||||
if err != nil || cluster == nil {
|
||||
return nil, fmt.Errorf("unable to convert cluster secret to cluster object '%s': %w", clusterSecret.Name, err)
|
||||
}
|
||||
|
||||
// db.SecretToCluster populates these, but they're not meant to be available to the caller.
|
||||
cluster.Labels = nil
|
||||
cluster.Annotations = nil
|
||||
|
||||
clusterList.Items[i] = *cluster
|
||||
clusterList[i] = ClusterSpecifier{
|
||||
Name: cluster.Name,
|
||||
Server: cluster.Server,
|
||||
}
|
||||
if cluster.Server == appv1.KubernetesInternalAPIServerAddr {
|
||||
hasInClusterCredentials = true
|
||||
}
|
||||
}
|
||||
if !hasInClusterCredentials {
|
||||
localCluster := getLocalCluster(clientset)
|
||||
if localCluster != nil {
|
||||
clusterList.Items = append(clusterList.Items, *localCluster)
|
||||
}
|
||||
// There was no secret for the in-cluster config, so we add it here. We don't fully-populate the Cluster struct,
|
||||
// since only the name and server fields are used by the generator.
|
||||
clusterList = append(clusterList, ClusterSpecifier{
|
||||
Name: "in-cluster",
|
||||
Server: appv1.KubernetesInternalAPIServerAddr,
|
||||
})
|
||||
}
|
||||
return &clusterList, nil
|
||||
}
|
||||
|
||||
func getLocalCluster(clientset kubernetes.Interface) *appv1.Cluster {
|
||||
initLocalCluster.Do(func() {
|
||||
info, err := clientset.Discovery().ServerVersion()
|
||||
if err == nil {
|
||||
// nolint:staticcheck
|
||||
localCluster.ServerVersion = fmt.Sprintf("%s.%s", info.Major, info.Minor)
|
||||
// nolint:staticcheck
|
||||
localCluster.ConnectionState = appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful}
|
||||
} else {
|
||||
// nolint:staticcheck
|
||||
localCluster.ConnectionState = appv1.ConnectionState{
|
||||
Status: appv1.ConnectionStatusFailed,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
})
|
||||
cluster := localCluster.DeepCopy()
|
||||
now := metav1.Now()
|
||||
// nolint:staticcheck
|
||||
cluster.ConnectionState.ModifiedAt = &now
|
||||
return cluster
|
||||
return clusterList, nil
|
||||
}
|
||||
|
||||
@@ -163,12 +163,12 @@ func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.Applica
|
||||
if len(result.Lives) != 1 {
|
||||
return fmt.Errorf("expected 1 normalized application, got %d", len(result.Lives))
|
||||
}
|
||||
foundJsonNormalized, err := json.Marshal(result.Lives[0].Object)
|
||||
foundJSONNormalized, err := json.Marshal(result.Lives[0].Object)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal normalized app to json: %w", err)
|
||||
}
|
||||
foundNormalized := &argov1alpha1.Application{}
|
||||
err = json.Unmarshal(foundJsonNormalized, &foundNormalized)
|
||||
err = json.Unmarshal(foundJSONNormalized, &foundNormalized)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal normalized app to json: %w", err)
|
||||
}
|
||||
@@ -176,12 +176,12 @@ func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.Applica
|
||||
return fmt.Errorf("expected 1 normalized application, got %d", len(result.Targets))
|
||||
}
|
||||
foundNormalized.DeepCopyInto(found)
|
||||
generatedJsonNormalized, err := json.Marshal(result.Targets[0].Object)
|
||||
generatedJSONNormalized, err := json.Marshal(result.Targets[0].Object)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal normalized app to json: %w", err)
|
||||
}
|
||||
generatedAppNormalized := &argov1alpha1.Application{}
|
||||
err = json.Unmarshal(generatedJsonNormalized, &generatedAppNormalized)
|
||||
err = json.Unmarshal(generatedJSONNormalized, &generatedAppNormalized)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal normalized app json to structured app: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -21,7 +20,7 @@ func TestGetSecretRef(t *testing.T) {
|
||||
},
|
||||
}
|
||||
client := fake.NewClientBuilder().WithObjects(secret).Build()
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
cases := []struct {
|
||||
name, namespace, token string
|
||||
@@ -86,7 +85,7 @@ func TestGetConfigMapData(t *testing.T) {
|
||||
},
|
||||
}
|
||||
client := fake.NewClientBuilder().WithObjects(configMap).Build()
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
cases := []struct {
|
||||
name, namespace, data string
|
||||
|
||||
2
applicationset/utils/mocks/Renderer.go
generated
2
applicationset/utils/mocks/Renderer.go
generated
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@ func (s internalSelector) Add(reqs ...Requirement) Selector {
|
||||
|
||||
type nothingSelector struct{}
|
||||
|
||||
func (n nothingSelector) Matches(l labels.Labels) bool {
|
||||
func (n nothingSelector) Matches(_ labels.Labels) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n nothingSelector) Add(r ...Requirement) Selector {
|
||||
func (n nothingSelector) Add(_ ...Requirement) Selector {
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
@@ -139,11 +139,11 @@ func (r *Render) deeplyReplace(copy, original reflect.Value, replaceMap map[stri
|
||||
} else if currentType == "Raw.k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" || currentType == "Raw.k8s.io/apimachinery/pkg/runtime" {
|
||||
var unmarshaled any
|
||||
originalBytes := original.Field(i).Bytes()
|
||||
convertedToJson, err := ConvertYAMLToJSON(string(originalBytes))
|
||||
convertedToJSON, err := ConvertYAMLToJSON(string(originalBytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while converting template to json %q: %w", convertedToJson, err)
|
||||
return fmt.Errorf("error while converting template to json %q: %w", convertedToJSON, err)
|
||||
}
|
||||
err = json.Unmarshal([]byte(convertedToJson), &unmarshaled)
|
||||
err = json.Unmarshal([]byte(convertedToJSON), &unmarshaled)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal JSON field: %w", err)
|
||||
}
|
||||
@@ -489,7 +489,7 @@ func SlugifyName(args ...any) string {
|
||||
return urlSlug
|
||||
}
|
||||
|
||||
func getTlsConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config {
|
||||
func getTLSConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config {
|
||||
tlsConfig := &tls.Config{}
|
||||
|
||||
if scmRootCAPath != "" {
|
||||
@@ -518,8 +518,8 @@ func getTlsConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config {
|
||||
return tlsConfig
|
||||
}
|
||||
|
||||
func GetTlsConfig(scmRootCAPath string, insecure bool, caCerts []byte) *tls.Config {
|
||||
tlsConfig := getTlsConfigWithCACert(scmRootCAPath, caCerts)
|
||||
func GetTlsConfig(scmRootCAPath string, insecure bool, caCerts []byte) *tls.Config { //nolint:revive //FIXME(var-naming)
|
||||
tlsConfig := getTLSConfigWithCACert(scmRootCAPath, caCerts)
|
||||
|
||||
if insecure {
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
|
||||
@@ -565,7 +565,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) {
|
||||
expectedVal: " foo:\n bar:\n bool: true\n number: 2\n str: Hello world",
|
||||
errorMessage: "failed to execute go template {{ toYaml . | indent 2 }}: template: :1:3: executing \"\" at <toYaml .>: error calling toYaml: error marshaling into JSON: json: unsupported type: func(*string)",
|
||||
params: map[string]any{
|
||||
"foo": func(test *string) {
|
||||
"foo": func(_ *string) {
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1331,42 +1331,42 @@ WkBKOclmOV2xlTVuPw==
|
||||
scmRootCAPath string
|
||||
insecure bool
|
||||
caCerts []byte
|
||||
validateCertInTlsConfig bool
|
||||
validateCertInTLSConfig bool
|
||||
}{
|
||||
{
|
||||
name: "Insecure mode configured, SCM Root CA Path not set",
|
||||
scmRootCAPath: "",
|
||||
insecure: true,
|
||||
caCerts: nil,
|
||||
validateCertInTlsConfig: false,
|
||||
validateCertInTLSConfig: false,
|
||||
},
|
||||
{
|
||||
name: "SCM Root CA Path set, Insecure mode set to false",
|
||||
scmRootCAPath: rootCAPath,
|
||||
insecure: false,
|
||||
caCerts: nil,
|
||||
validateCertInTlsConfig: true,
|
||||
validateCertInTLSConfig: true,
|
||||
},
|
||||
{
|
||||
name: "SCM Root CA Path set, Insecure mode set to true",
|
||||
scmRootCAPath: rootCAPath,
|
||||
insecure: true,
|
||||
caCerts: nil,
|
||||
validateCertInTlsConfig: true,
|
||||
validateCertInTLSConfig: true,
|
||||
},
|
||||
{
|
||||
name: "Cert passed, Insecure mode set to false",
|
||||
scmRootCAPath: "",
|
||||
insecure: false,
|
||||
caCerts: []byte(certFromCM),
|
||||
validateCertInTlsConfig: true,
|
||||
validateCertInTLSConfig: true,
|
||||
},
|
||||
{
|
||||
name: "SCM Root CA Path set, cert passed, Insecure mode set to false",
|
||||
scmRootCAPath: rootCAPath,
|
||||
insecure: false,
|
||||
caCerts: []byte(certFromCM),
|
||||
validateCertInTlsConfig: true,
|
||||
validateCertInTLSConfig: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1384,7 +1384,7 @@ WkBKOclmOV2xlTVuPw==
|
||||
assert.True(t, ok)
|
||||
}
|
||||
assert.NotNil(t, tlsConfig)
|
||||
if testCase.validateCertInTlsConfig {
|
||||
if testCase.validateCertInTLSConfig {
|
||||
assert.True(t, tlsConfig.RootCAs.Equal(certPool))
|
||||
}
|
||||
})
|
||||
|
||||
126
applicationset/webhook/testdata/gitlab-event.json
vendored
126
applicationset/webhook/testdata/gitlab-event.json
vendored
@@ -1,65 +1,65 @@
|
||||
{
|
||||
"object_kind": "push",
|
||||
"event_name": "push",
|
||||
"before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a",
|
||||
"after": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"ref": "refs/heads/master",
|
||||
"checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"message": null,
|
||||
"user_id": 1,
|
||||
"user_name": "name",
|
||||
"user_username": "username",
|
||||
"user_email": "",
|
||||
"user_avatar": "",
|
||||
"project_id": 1,
|
||||
"project": {
|
||||
"id": 1,
|
||||
"name": "project",
|
||||
"description": "",
|
||||
"web_url": "https://gitlab/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab/group/name.git",
|
||||
"namespace": "group",
|
||||
"visibility_level": 1,
|
||||
"path_with_namespace": "group/name",
|
||||
"default_branch": "master",
|
||||
"ci_config_path": null,
|
||||
"homepage": "https://gitlab/group/name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"http_url": "https://gitlab/group/name.git"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"message": "Test commit message\n",
|
||||
"timestamp": "2020-01-06T03:47:55Z",
|
||||
"url": "https://gitlab/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"author": {
|
||||
"name": "User",
|
||||
"email": "user@example.com"
|
||||
},
|
||||
"added": [
|
||||
"file.yaml"
|
||||
],
|
||||
"modified": [
|
||||
],
|
||||
"removed": [
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"total_commits_count": 1,
|
||||
"push_options": {
|
||||
},
|
||||
"repository": {
|
||||
"name": "name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"description": "",
|
||||
"homepage": "https://gitlab/group/name",
|
||||
"git_http_url": "https://gitlab/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"visibility_level": 10
|
||||
"object_kind": "push",
|
||||
"event_name": "push",
|
||||
"before": "e5ba5f6c13b64670048daa88e4c053d60b0e115a",
|
||||
"after": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"ref": "refs/heads/master",
|
||||
"checkout_sha": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"message": null,
|
||||
"user_id": 1,
|
||||
"user_name": "name",
|
||||
"user_username": "username",
|
||||
"user_email": "",
|
||||
"user_avatar": "",
|
||||
"project_id": 1,
|
||||
"project": {
|
||||
"id": 1,
|
||||
"name": "project",
|
||||
"description": "",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "group",
|
||||
"visibility_level": 1,
|
||||
"path_with_namespace": "group/name",
|
||||
"default_branch": "master",
|
||||
"ci_config_path": null,
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"message": "Test commit message\n",
|
||||
"timestamp": "2020-01-06T03:47:55Z",
|
||||
"url": "https://gitlab.com/group/name/commit/bb0748feaa336d841c251017e4e374c22d0c8a98",
|
||||
"author": {
|
||||
"name": "User",
|
||||
"email": "user@example.com"
|
||||
},
|
||||
"added": [
|
||||
"file.yaml"
|
||||
],
|
||||
"modified": [
|
||||
],
|
||||
"removed": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_commits_count": 1,
|
||||
"push_options": {
|
||||
},
|
||||
"repository": {
|
||||
"name": "name",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"description": "",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"visibility_level": 10
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"description": "",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "group",
|
||||
"visibility_level": 1,
|
||||
@@ -22,17 +22,17 @@
|
||||
"default_branch": "master",
|
||||
"ci_config_path": null,
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"repository": {
|
||||
"name": "name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"description": "",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"visibility_level": 10
|
||||
},
|
||||
"object_attributes": {
|
||||
@@ -60,7 +60,7 @@
|
||||
"description": "Aut reprehenderit ut est.",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "Awesome Space",
|
||||
"visibility_level": 20,
|
||||
@@ -68,7 +68,7 @@
|
||||
"default_branch": "master",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "https://gitlab.com/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"target": {
|
||||
@@ -76,7 +76,7 @@
|
||||
"description": "Aut reprehenderit ut est.",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "Awesome Space",
|
||||
"visibility_level": 20,
|
||||
@@ -84,7 +84,7 @@
|
||||
"default_branch": "master",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "https://gitlab.com/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"last_commit": {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"description": "",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "group",
|
||||
"visibility_level": 1,
|
||||
@@ -22,17 +22,17 @@
|
||||
"default_branch": "master",
|
||||
"ci_config_path": null,
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"repository": {
|
||||
"name": "name",
|
||||
"url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"description": "",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"visibility_level": 10
|
||||
},
|
||||
"object_attributes": {
|
||||
@@ -60,7 +60,7 @@
|
||||
"description": "Aut reprehenderit ut est.",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "Awesome Space",
|
||||
"visibility_level": 20,
|
||||
@@ -68,7 +68,7 @@
|
||||
"default_branch": "master",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "https://gitlab.com/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"target": {
|
||||
@@ -76,7 +76,7 @@
|
||||
"description": "Aut reprehenderit ut est.",
|
||||
"web_url": "https://gitlab.com/group/name",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"git_ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"git_http_url": "https://gitlab.com/group/name.git",
|
||||
"namespace": "Awesome Space",
|
||||
"visibility_level": 20,
|
||||
@@ -84,7 +84,7 @@
|
||||
"default_branch": "master",
|
||||
"homepage": "https://gitlab.com/group/name",
|
||||
"url": "https://gitlab.com/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab:2222/group/name.git",
|
||||
"ssh_url": "ssh://git@gitlab.com:2222/group/name.git",
|
||||
"http_url": "https://gitlab.com/group/name.git"
|
||||
},
|
||||
"last_commit": {
|
||||
|
||||
@@ -217,13 +217,7 @@ func getGitGeneratorInfo(payload any) *gitGeneratorInfo {
|
||||
}
|
||||
|
||||
log.Infof("Received push event repo: %s, revision: %s, touchedHead: %v", webURL, revision, touchedHead)
|
||||
urlObj, err := url.Parse(webURL)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to parse repoURL '%s'", webURL)
|
||||
return nil
|
||||
}
|
||||
regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + urlObj.Path[1:] + "(\\.git)?$"
|
||||
repoRegexp, err := regexp.Compile(regexpStr)
|
||||
repoRegexp, err := webhook.GetWebURLRegex(webURL)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to compile regexp for repoURL '%s'", webURL)
|
||||
return nil
|
||||
@@ -245,13 +239,7 @@ func getPRGeneratorInfo(payload any) *prGeneratorInfo {
|
||||
}
|
||||
|
||||
apiURL := payload.Repository.URL
|
||||
urlObj, err := url.Parse(apiURL)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to parse repoURL '%s'", apiURL)
|
||||
return nil
|
||||
}
|
||||
regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]"
|
||||
apiRegexp, err := regexp.Compile(regexpStr)
|
||||
apiRegexp, err := webhook.GetAPIURLRegex(apiURL)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to compile regexp for repoURL '%s'", apiURL)
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package webhook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -35,15 +34,15 @@ type generatorMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (g *generatorMock) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate {
|
||||
func (g *generatorMock) GetTemplate(_ *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate {
|
||||
return &v1alpha1.ApplicationSetTemplate{}
|
||||
}
|
||||
|
||||
func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, client client.Client) ([]map[string]any, error) {
|
||||
func (g *generatorMock) GenerateParams(_ *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) {
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
|
||||
func (g *generatorMock) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
func (g *generatorMock) GetRequeueAfter(_ *v1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
d, _ := time.ParseDuration("10s")
|
||||
return d
|
||||
}
|
||||
@@ -63,7 +62,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-GitHub-Event",
|
||||
headerValue: "push",
|
||||
payloadFile: "github-commit-event.json",
|
||||
effectedAppSets: []string{"git-github", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"},
|
||||
effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"},
|
||||
expectedStatusCode: http.StatusOK,
|
||||
expectedRefresh: true,
|
||||
},
|
||||
@@ -81,7 +80,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-GitHub-Event",
|
||||
headerValue: "push",
|
||||
payloadFile: "github-commit-branch-event.json",
|
||||
effectedAppSets: []string{"git-github", "plugin", "matrix-pull-request-github-plugin"},
|
||||
effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin", "matrix-pull-request-github-plugin"},
|
||||
expectedStatusCode: http.StatusOK,
|
||||
expectedRefresh: true,
|
||||
},
|
||||
@@ -90,7 +89,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-GitHub-Event",
|
||||
headerValue: "ping",
|
||||
payloadFile: "github-ping-event.json",
|
||||
effectedAppSets: []string{"git-github", "plugin"},
|
||||
effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin"},
|
||||
expectedStatusCode: http.StatusOK,
|
||||
expectedRefresh: false,
|
||||
},
|
||||
@@ -99,7 +98,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-Gitlab-Event",
|
||||
headerValue: "Push Hook",
|
||||
payloadFile: "gitlab-event.json",
|
||||
effectedAppSets: []string{"git-gitlab", "plugin", "matrix-pull-request-github-plugin"},
|
||||
effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"},
|
||||
expectedStatusCode: http.StatusOK,
|
||||
expectedRefresh: true,
|
||||
},
|
||||
@@ -108,7 +107,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-Gitlab-Event",
|
||||
headerValue: "System Hook",
|
||||
payloadFile: "gitlab-event.json",
|
||||
effectedAppSets: []string{"git-gitlab", "plugin", "matrix-pull-request-github-plugin"},
|
||||
effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"},
|
||||
expectedStatusCode: http.StatusOK,
|
||||
expectedRefresh: true,
|
||||
},
|
||||
@@ -117,7 +116,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-Random-Event",
|
||||
headerValue: "Push Hook",
|
||||
payloadFile: "gitlab-event.json",
|
||||
effectedAppSets: []string{"git-gitlab", "plugin"},
|
||||
effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"},
|
||||
expectedStatusCode: http.StatusBadRequest,
|
||||
expectedRefresh: false,
|
||||
},
|
||||
@@ -126,7 +125,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
headerKey: "X-Random-Event",
|
||||
headerValue: "Push Hook",
|
||||
payloadFile: "invalid-event.json",
|
||||
effectedAppSets: []string{"git-gitlab", "plugin"},
|
||||
effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"},
|
||||
expectedStatusCode: http.StatusBadRequest,
|
||||
expectedRefresh: false,
|
||||
},
|
||||
@@ -209,7 +208,11 @@ func TestWebhookHandler(t *testing.T) {
|
||||
fc := fake.NewClientBuilder().WithScheme(scheme).WithObjects(
|
||||
fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"),
|
||||
fakeAppWithGitGenerator("git-github-copy", namespace, "https://github.com/org/repo-copy"),
|
||||
fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab/group/name"),
|
||||
fakeAppWithGitGenerator("git-github-ssh", namespace, "ssh://git@github.com/org/repo"),
|
||||
fakeAppWithGitGenerator("git-github-alt-ssh", namespace, "ssh://git@ssh.github.com:443/org/repo"),
|
||||
fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab.com/group/name"),
|
||||
fakeAppWithGitGenerator("git-gitlab-ssh", namespace, "ssh://git@gitlab.com/group/name"),
|
||||
fakeAppWithGitGenerator("git-gitlab-alt-ssh", namespace, "ssh://git@altssh.gitlab.com:443/group/name"),
|
||||
fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"),
|
||||
fakeAppWithGitGeneratorWithRevision("github-shorthand", namespace, "https://github.com/org/repo", "env/dev"),
|
||||
fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "CodErTOcat", "Hello-World"),
|
||||
@@ -226,7 +229,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
fakeAppWithMergeAndPullRequestGenerator("merge-pull-request-github", namespace, "Codertocat", "Hello-World"),
|
||||
fakeAppWithMergeAndNestedGitGenerator("merge-nested-git-github", namespace, "https://github.com/org/repo"),
|
||||
).Build()
|
||||
set := argosettings.NewSettingsManager(context.TODO(), fakeClient, namespace)
|
||||
set := argosettings.NewSettingsManager(t.Context(), fakeClient, namespace)
|
||||
h, err := NewWebhookHandler(namespace, webhookParallelism, set, fc, mockGenerators())
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -243,7 +246,7 @@ func TestWebhookHandler(t *testing.T) {
|
||||
assert.Equal(t, test.expectedStatusCode, w.Code)
|
||||
|
||||
list := &v1alpha1.ApplicationSetList{}
|
||||
err = fc.List(context.TODO(), list)
|
||||
err = fc.List(t.Context(), list)
|
||||
require.NoError(t, err)
|
||||
effectedAppSetsAsExpected := make(map[string]bool)
|
||||
for _, appSetName := range test.effectedAppSets {
|
||||
|
||||
@@ -18,7 +18,9 @@ p, role:readonly, logs, get, */*, allow
|
||||
|
||||
p, role:admin, applications, create, */*, allow
|
||||
p, role:admin, applications, update, */*, allow
|
||||
p, role:admin, applications, update/*, */*, allow
|
||||
p, role:admin, applications, delete, */*, allow
|
||||
p, role:admin, applications, delete/*, */*, allow
|
||||
p, role:admin, applications, sync, */*, allow
|
||||
p, role:admin, applications, override, */*, allow
|
||||
p, role:admin, applications, action/*, */*, allow
|
||||
@@ -47,4 +49,4 @@ p, role:admin, gpgkeys, delete, *, allow
|
||||
p, role:admin, exec, create, */*, allow
|
||||
|
||||
g, role:admin, role:readonly
|
||||
g, admin, role:admin
|
||||
g, admin, role:admin
|
||||
|
||||
|
176
assets/swagger.json
generated
176
assets/swagger.json
generated
@@ -920,6 +920,11 @@
|
||||
"type": "string",
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "matchCase",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -1153,6 +1158,11 @@
|
||||
"type": "string",
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "matchCase",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -3771,6 +3781,18 @@
|
||||
"description": "Whether to force HTTP basic auth.",
|
||||
"name": "forceHttpBasicAuth",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether to use azure workload identity for authentication.",
|
||||
"name": "useAzureWorkloadIdentity",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "BearerToken contains the bearer token used for Git auth at the repo server.",
|
||||
"name": "bearerToken",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -4597,6 +4619,18 @@
|
||||
"description": "Whether to force HTTP basic auth.",
|
||||
"name": "forceHttpBasicAuth",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether to use azure workload identity for authentication.",
|
||||
"name": "useAzureWorkloadIdentity",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "BearerToken contains the bearer token used for Git auth at the repo server.",
|
||||
"name": "bearerToken",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -5067,41 +5101,51 @@
|
||||
}
|
||||
},
|
||||
"applicationv1alpha1ResourceStatus": {
|
||||
"description": "ResourceStatus holds the current synchronization and health status of a Kubernetes resource.",
|
||||
"type": "object",
|
||||
"title": "ResourceStatus holds the current sync and health status of a resource\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"group": {
|
||||
"description": "Group represents the API group of the resource (e.g., \"apps\" for Deployments).",
|
||||
"type": "string"
|
||||
},
|
||||
"health": {
|
||||
"$ref": "#/definitions/v1alpha1HealthStatus"
|
||||
},
|
||||
"hook": {
|
||||
"description": "Hook is true if the resource is used as a lifecycle hook in an Argo CD application.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Kind specifies the type of the resource (e.g., \"Deployment\", \"Service\").",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name is the unique name of the resource within the namespace.",
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"description": "Namespace defines the Kubernetes namespace where the resource is located.",
|
||||
"type": "string"
|
||||
},
|
||||
"requiresDeletionConfirmation": {
|
||||
"description": "RequiresDeletionConfirmation is true if the resource requires explicit user confirmation before deletion.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"requiresPruning": {
|
||||
"description": "RequiresPruning is true if the resource needs to be pruned (deleted) as part of synchronization.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"status": {
|
||||
"description": "Status represents the synchronization state of the resource (e.g., Synced, OutOfSync).",
|
||||
"type": "string"
|
||||
},
|
||||
"syncWave": {
|
||||
"description": "SyncWave determines the order in which resources are applied during a sync operation.\nLower values are applied first.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version indicates the API version of the resource (e.g., \"v1\", \"v1beta1\").",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -6395,6 +6439,7 @@
|
||||
},
|
||||
"v1PortStatus": {
|
||||
"type": "object",
|
||||
"title": "PortStatus represents the error condition of a service port",
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string",
|
||||
@@ -6904,8 +6949,8 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"applyNestedSelectors": {
|
||||
"type": "boolean",
|
||||
"title": "ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators"
|
||||
"description": "ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators\nDeprecated: This field is ignored, and the behavior is always enabled. The field will be removed in a future\nversion of the ApplicationSet CRD.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"generators": {
|
||||
"type": "array",
|
||||
@@ -7263,6 +7308,10 @@
|
||||
"type": "boolean",
|
||||
"title": "ForceCommonLabels specifies whether to force applying common labels to resources for Kustomize apps"
|
||||
},
|
||||
"ignoreMissingComponents": {
|
||||
"type": "boolean",
|
||||
"title": "IgnoreMissingComponents prevents kustomize from failing when components do not exist locally by not appending them to kustomization file"
|
||||
},
|
||||
"images": {
|
||||
"type": "array",
|
||||
"title": "Images is a list of Kustomize image override specifications",
|
||||
@@ -7274,6 +7323,10 @@
|
||||
"description": "KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD\nuses the Kubernetes version of the target cluster.",
|
||||
"type": "string"
|
||||
},
|
||||
"labelIncludeTemplates": {
|
||||
"type": "boolean",
|
||||
"title": "LabelIncludeTemplates specifies whether to apply common labels to resource templates or not"
|
||||
},
|
||||
"labelWithoutSelector": {
|
||||
"type": "boolean",
|
||||
"title": "LabelWithoutSelector specifies whether to apply common labels to resource selectors or not"
|
||||
@@ -7494,34 +7547,34 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1ApplicationTree": {
|
||||
"description": "ApplicationTree represents the hierarchical structure of resources associated with an Argo CD application.",
|
||||
"type": "object",
|
||||
"title": "ApplicationTree holds nodes which belongs to the application\nTODO: describe purpose of this type",
|
||||
"properties": {
|
||||
"hosts": {
|
||||
"description": "Hosts provides a list of Kubernetes nodes that are running pods related to the application.",
|
||||
"type": "array",
|
||||
"title": "Hosts holds list of Kubernetes nodes that run application related pods",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1HostInfo"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"description": "Nodes contains list of nodes which either directly managed by the application and children of directly managed nodes.",
|
||||
"description": "Nodes contains a list of resources that are either directly managed by the application\nor are children of directly managed resources.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1ResourceNode"
|
||||
}
|
||||
},
|
||||
"orphanedNodes": {
|
||||
"description": "OrphanedNodes contains if or orphaned nodes: nodes which are not managed by the app but in the same namespace. List is populated only if orphaned resources enabled in app project.",
|
||||
"description": "OrphanedNodes contains resources that exist in the same namespace as the application\nbut are not managed by it. This list is populated only if orphaned resource tracking\nis enabled in the application's project settings.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1ResourceNode"
|
||||
}
|
||||
},
|
||||
"shardsCount": {
|
||||
"description": "ShardsCount represents the total number of shards the application tree is split into.\nThis is used to distribute resource processing across multiple shards.",
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"title": "ShardsCount contains total number of shards the application tree is split into"
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8115,13 +8168,15 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1HostInfo": {
|
||||
"description": "HostInfo holds metadata and resource usage metrics for a specific host in the cluster.",
|
||||
"type": "object",
|
||||
"title": "HostInfo holds host name and resources metrics\nTODO: describe purpose of this type\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Name is the hostname or node name in the Kubernetes cluster.",
|
||||
"type": "string"
|
||||
},
|
||||
"resourcesInfo": {
|
||||
"description": "ResourcesInfo provides a list of resource usage details for different resource types on this host.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1HostResourceInfo"
|
||||
@@ -8133,22 +8188,26 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1HostResourceInfo": {
|
||||
"description": "HostResourceInfo represents resource usage details for a specific resource type on a host.",
|
||||
"type": "object",
|
||||
"title": "TODO: describe this type",
|
||||
"properties": {
|
||||
"capacity": {
|
||||
"description": "Capacity represents the total available capacity of this resource on the host.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"requestedByApp": {
|
||||
"description": "RequestedByApp indicates the total amount of this resource requested by the application running on the host.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"requestedByNeighbors": {
|
||||
"description": "RequestedByNeighbors indicates the total amount of this resource requested by other workloads on the same host.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"resourceName": {
|
||||
"description": "ResourceName specifies the type of resource (e.g., CPU, memory, storage).",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -8264,13 +8323,15 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1KnownTypeField": {
|
||||
"description": "KnownTypeField contains a mapping between a Custom Resource Definition (CRD) field\nand a well-known Kubernetes type. This mapping is primarily used for unit conversions\nin resources where the type is not explicitly defined (e.g., converting \"0.1\" to \"100m\" for CPU requests).",
|
||||
"type": "object",
|
||||
"title": "KnownTypeField contains mapping between CRD field and known Kubernetes type.\nThis is mainly used for unit conversion in unknown resources (e.g. 0.1 == 100mi)\nTODO: Describe the members of this type",
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"title": "Field represents the JSON path to the specific field in the CRD that requires type conversion.\nExample: \"spec.resources.requests.cpu\""
|
||||
},
|
||||
"type": {
|
||||
"description": "Type specifies the expected Kubernetes type for the field, such as \"cpu\" or \"memory\".\nThis helps in converting values between different formats (e.g., \"0.1\" to \"100m\" for CPU).",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -8680,6 +8741,13 @@
|
||||
},
|
||||
"template": {
|
||||
"$ref": "#/definitions/v1alpha1ApplicationSetTemplate"
|
||||
},
|
||||
"values": {
|
||||
"type": "object",
|
||||
"title": "Values contains key/value pairs which are passed directly as parameters to the template",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8878,6 +8946,10 @@
|
||||
"type": "object",
|
||||
"title": "RepoCreds holds the definition for repository credentials",
|
||||
"properties": {
|
||||
"bearerToken": {
|
||||
"type": "string",
|
||||
"title": "BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server"
|
||||
},
|
||||
"enableOCI": {
|
||||
"type": "boolean",
|
||||
"title": "EnableOCI specifies whether helm-oci support should be enabled for this repo"
|
||||
@@ -8940,6 +9012,10 @@
|
||||
"type": "string",
|
||||
"title": "URL is the URL to which these credentials match"
|
||||
},
|
||||
"useAzureWorkloadIdentity": {
|
||||
"type": "boolean",
|
||||
"title": "UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication"
|
||||
},
|
||||
"username": {
|
||||
"type": "string",
|
||||
"title": "Username for authenticating at the repo server"
|
||||
@@ -8965,6 +9041,10 @@
|
||||
"type": "object",
|
||||
"title": "Repository is a repository holding application configurations",
|
||||
"properties": {
|
||||
"bearerToken": {
|
||||
"type": "string",
|
||||
"title": "BearerToken contains the bearer token used for Git BitBucket Data Center auth at the repo server"
|
||||
},
|
||||
"connectionState": {
|
||||
"$ref": "#/definitions/v1alpha1ConnectionState"
|
||||
},
|
||||
@@ -9054,6 +9134,10 @@
|
||||
"description": "Type specifies the type of the repo. Can be either \"git\" or \"helm. \"git\" is assumed if empty or absent.",
|
||||
"type": "string"
|
||||
},
|
||||
"useAzureWorkloadIdentity": {
|
||||
"type": "boolean",
|
||||
"title": "UseAzureWorkloadIdentity specifies whether to use Azure Workload Identity for authentication"
|
||||
},
|
||||
"username": {
|
||||
"type": "string",
|
||||
"title": "Username contains the user name used for authenticating at the remote repository"
|
||||
@@ -9119,22 +9203,27 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1ResourceAction": {
|
||||
"description": "ResourceAction represents an individual action that can be performed on a resource.\nIt includes parameters, an optional disabled flag, an icon for display, and a name for the action.",
|
||||
"type": "object",
|
||||
"title": "TODO: describe this type\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"disabled": {
|
||||
"description": "Disabled indicates whether the action is disabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"displayName": {
|
||||
"description": "DisplayName provides a user-friendly name for the action.",
|
||||
"type": "string"
|
||||
},
|
||||
"iconClass": {
|
||||
"description": "IconClass specifies the CSS class for the action's icon.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name is the name or identifier for the action.",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"description": "Params contains the parameters required to execute the action.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1ResourceActionParam"
|
||||
@@ -9143,67 +9232,78 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1ResourceActionParam": {
|
||||
"description": "ResourceActionParam represents a parameter for a resource action.\nIt includes a name, value, type, and an optional default value for the parameter.",
|
||||
"type": "object",
|
||||
"title": "TODO: describe this type\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "Default is the default value of the parameter, if any.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name is the name of the parameter.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type is the type of the parameter (e.g., string, integer).",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value is the value of the parameter.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1ResourceDiff": {
|
||||
"description": "ResourceDiff holds the diff between a live and target resource object in Argo CD.\nIt is used to compare the desired state (from Git/Helm) with the actual state in the cluster.",
|
||||
"type": "object",
|
||||
"title": "ResourceDiff holds the diff of a live and target resource object\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"title": "Diff contains the JSON patch between target and live resource\nDeprecated: use NormalizedLiveState and PredictedLiveState to render the difference"
|
||||
"description": "Diff contains the JSON patch representing the difference between the live and target resource.\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.",
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
"description": "Group represents the API group of the resource (e.g., \"apps\" for Deployments).",
|
||||
"type": "string"
|
||||
},
|
||||
"hook": {
|
||||
"description": "Hook indicates whether this resource is a hook resource (e.g., pre-sync or post-sync hooks).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Kind represents the Kubernetes resource kind (e.g., \"Deployment\", \"Service\").",
|
||||
"type": "string"
|
||||
},
|
||||
"liveState": {
|
||||
"type": "string",
|
||||
"title": "TargetState contains the JSON live resource manifest"
|
||||
"description": "LiveState contains the JSON-serialized resource manifest of the resource currently running in the cluster.",
|
||||
"type": "string"
|
||||
},
|
||||
"modified": {
|
||||
"description": "Modified indicates whether the live resource has changes compared to the target resource.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name is the name of the resource.",
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"description": "Namespace specifies the namespace where the resource exists.",
|
||||
"type": "string"
|
||||
},
|
||||
"normalizedLiveState": {
|
||||
"type": "string",
|
||||
"title": "NormalizedLiveState contains JSON serialized live resource state with applied normalizations"
|
||||
"description": "NormalizedLiveState contains the JSON-serialized live resource state after applying normalizations.\nNormalizations may include ignoring irrelevant fields like timestamps or defaults applied by Kubernetes.",
|
||||
"type": "string"
|
||||
},
|
||||
"predictedLiveState": {
|
||||
"type": "string",
|
||||
"title": "PredictedLiveState contains JSON serialized resource state that is calculated based on normalized and target resource state"
|
||||
"description": "PredictedLiveState contains the JSON-serialized resource state that Argo CD predicts based on the\ncombination of the normalized live state and the desired target state.",
|
||||
"type": "string"
|
||||
},
|
||||
"resourceVersion": {
|
||||
"description": "ResourceVersion is the Kubernetes resource version, which helps in tracking changes.",
|
||||
"type": "string"
|
||||
},
|
||||
"targetState": {
|
||||
"type": "string",
|
||||
"title": "TargetState contains the JSON serialized resource manifest defined in the Git/Helm"
|
||||
"description": "TargetState contains the JSON-serialized resource manifest as defined in the Git/Helm repository.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -9245,35 +9345,39 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1ResourceNetworkingInfo": {
|
||||
"description": "ResourceNetworkingInfo holds networking-related information for a resource.",
|
||||
"type": "object",
|
||||
"title": "ResourceNetworkingInfo holds networking resource related information\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"externalURLs": {
|
||||
"description": "ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames.",
|
||||
"description": "ExternalURLs holds a list of URLs that should be accessible externally.\nThis field is typically populated for Ingress resources based on their hostname rules.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ingress": {
|
||||
"description": "Ingress provides information about external access points (e.g., load balancer ingress) for this resource.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1LoadBalancerIngress"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"description": "Labels holds the labels associated with this networking resource.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"targetLabels": {
|
||||
"description": "TargetLabels represents labels associated with the target resources that this resource communicates with.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"targetRefs": {
|
||||
"description": "TargetRefs contains references to other resources that this resource interacts with, such as Services or Pods.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1ResourceRef"
|
||||
@@ -9282,8 +9386,8 @@
|
||||
}
|
||||
},
|
||||
"v1alpha1ResourceNode": {
|
||||
"description": "ResourceNode contains information about a live Kubernetes resource and its relationships with other resources.",
|
||||
"type": "object",
|
||||
"title": "ResourceNode contains information about live resource and its children\nTODO: describe members of this type",
|
||||
"properties": {
|
||||
"createdAt": {
|
||||
"$ref": "#/definitions/v1Time"
|
||||
@@ -9292,12 +9396,14 @@
|
||||
"$ref": "#/definitions/v1alpha1HealthStatus"
|
||||
},
|
||||
"images": {
|
||||
"description": "Images lists container images associated with the resource.\nThis is primarily useful for pods and other workload resources.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"description": "Info provides additional metadata or annotations about the resource.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1InfoItem"
|
||||
@@ -9307,12 +9413,14 @@
|
||||
"$ref": "#/definitions/v1alpha1ResourceNetworkingInfo"
|
||||
},
|
||||
"parentRefs": {
|
||||
"description": "ParentRefs lists the parent resources that reference this resource.\nThis helps in understanding ownership and hierarchical relationships.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1ResourceRef"
|
||||
}
|
||||
},
|
||||
"resourceVersion": {
|
||||
"description": "ResourceVersion indicates the version of the resource, used to track changes.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -9324,12 +9432,14 @@
|
||||
},
|
||||
"v1alpha1ResourceOverride": {
|
||||
"type": "object",
|
||||
"title": "ResourceOverride holds configuration to customize resource diffing and health assessment\nTODO: describe the members of this type",
|
||||
"title": "ResourceOverride holds configuration to customize resource diffing and health assessment",
|
||||
"properties": {
|
||||
"actions": {
|
||||
"description": "Actions defines the set of actions that can be performed on the resource, as a Lua script.",
|
||||
"type": "string"
|
||||
},
|
||||
"healthLua": {
|
||||
"description": "HealthLua contains a Lua script that defines custom health checks for the resource.",
|
||||
"type": "string"
|
||||
},
|
||||
"ignoreDifferences": {
|
||||
@@ -9339,12 +9449,14 @@
|
||||
"$ref": "#/definitions/v1alpha1OverrideIgnoreDiff"
|
||||
},
|
||||
"knownTypeFields": {
|
||||
"description": "KnownTypeFields lists fields for which unit conversions should be applied.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1alpha1KnownTypeField"
|
||||
}
|
||||
},
|
||||
"useOpenLibs": {
|
||||
"description": "UseOpenLibs indicates whether to use open-source libraries for the resource.",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
@@ -10077,6 +10189,10 @@
|
||||
"type": "object",
|
||||
"title": "SyncWindow contains the kind, time, duration and attributes that are used to assign the syncWindows to apps",
|
||||
"properties": {
|
||||
"andOperator": {
|
||||
"type": "boolean",
|
||||
"title": "UseAndOperator use AND operator for matching applications, namespaces and clusters instead of the default OR operator"
|
||||
},
|
||||
"applications": {
|
||||
"type": "array",
|
||||
"title": "Applications contains a list of applications that the window will apply to",
|
||||
|
||||
@@ -72,6 +72,7 @@ func NewCommand() *cobra.Command {
|
||||
metricsCacheExpiration time.Duration
|
||||
metricsAplicationLabels []string
|
||||
metricsAplicationConditions []string
|
||||
metricsClusterLabels []string
|
||||
kubectlParallelismLimit int64
|
||||
cacheSource func() (*appstatecache.Cache, error)
|
||||
redisClient *redis.Client
|
||||
@@ -97,7 +98,7 @@ func NewCommand() *cobra.Command {
|
||||
Short: "Run ArgoCD Application Controller",
|
||||
Long: "ArgoCD application controller is a Kubernetes controller that continuously monitors running applications and compares the current, live state against the desired target state (as specified in the repo). This command runs Application Controller in the foreground. It can be configured by following options.",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
ctx, cancel := context.WithCancel(c.Context())
|
||||
defer cancel()
|
||||
|
||||
@@ -202,6 +203,7 @@ func NewCommand() *cobra.Command {
|
||||
metricsCacheExpiration,
|
||||
metricsAplicationLabels,
|
||||
metricsAplicationConditions,
|
||||
metricsClusterLabels,
|
||||
kubectlParallelismLimit,
|
||||
persistResourceHealth,
|
||||
clusterSharding,
|
||||
@@ -257,7 +259,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().StringVar(&commitServerAddress, "commit-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER", common.DefaultCommitServerAddr), "Commit server address.")
|
||||
command.Flags().IntVar(&statusProcessors, "status-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS", 20, 0, math.MaxInt32), "Number of application status processors")
|
||||
command.Flags().IntVar(&operationProcessors, "operation-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS", 10, 0, math.MaxInt32), "Number of application operation processors")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level")
|
||||
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortArgoCDMetrics, "Start metrics server on given port")
|
||||
@@ -272,12 +274,13 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server")
|
||||
command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric")
|
||||
command.Flags().StringSliceVar(&metricsAplicationConditions, "metrics-application-conditions", []string{}, "List of Application conditions that will be added to the argocd_application_conditions metric")
|
||||
command.Flags().StringSliceVar(&metricsClusterLabels, "metrics-cluster-labels", []string{}, "List of Cluster labels that will be added to the argocd_cluster_labels metric")
|
||||
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
|
||||
command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode")
|
||||
command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)")
|
||||
command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)")
|
||||
command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that applications are allowed to be reconciled from")
|
||||
command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", true), "Enables storing the managed resources health in the Application CRD")
|
||||
command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", false), "Enables storing the managed resources health in the Application CRD")
|
||||
command.Flags().StringVar(&shardingAlgorithm, "sharding-method", env.StringFromEnv(common.EnvControllerShardingAlgorithm, common.DefaultShardingAlgorithm), "Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin, consistent-hashing] ")
|
||||
// global queue rate limit config
|
||||
command.Flags().Int64Var(&workqueueRateLimit.BucketSize, "wq-bucket-size", env.ParseInt64FromEnv("WORKQUEUE_BUCKET_SIZE", 500, 1, math.MaxInt64), "Set Workqueue Rate Limiter Bucket Size, default 500")
|
||||
|
||||
@@ -81,7 +81,7 @@ func NewCommand() *cobra.Command {
|
||||
command := cobra.Command{
|
||||
Use: "controller",
|
||||
Short: "Starts Argo CD ApplicationSet controller",
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
ctx := c.Context()
|
||||
|
||||
vers := common.GetVersion()
|
||||
@@ -188,8 +188,7 @@ func NewCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
repoClientset := apiclient.NewRepoServerClientset(argocdRepoServer, repoServerTimeoutSeconds, tlsConfig)
|
||||
argoCDService, err := services.NewArgoCDService(argoCDDB.GetRepository, gitSubmoduleEnabled, repoClientset, enableNewGitFileGlobbing)
|
||||
errors.CheckError(err)
|
||||
argoCDService := services.NewArgoCDService(argoCDDB, gitSubmoduleEnabled, repoClientset, enableNewGitFileGlobbing)
|
||||
|
||||
topLevelGenerators := generators.GetGenerators(ctx, mgr.GetClient(), k8sClient, namespace, argoCDService, dynamicClient, scmConfig)
|
||||
|
||||
@@ -252,7 +251,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().StringVar(&policy, "policy", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_POLICY", ""), "Modify how application is synced between the generator and the cluster. Default is '' (empty), which means AppSets default to 'sync', but they may override that default. Setting an explicit value prevents AppSet-level overrides, unless --allow-policy-override is enabled. Explicit options are: 'sync' (create & update & delete), 'create-only', 'create-update' (no deletion), 'create-delete' (no update)")
|
||||
command.Flags().BoolVar(&enablePolicyOverride, "enable-policy-override", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE", policy == ""), "For security reason if 'policy' is set, it is not possible to override it at applicationSet level. 'allow-policy-override' allows user to define their own policy")
|
||||
command.Flags().BoolVar(&debugLog, "debug", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG", false), "Print debug logs. Takes precedence over loglevel")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().StringSliceVar(&allowedScmProviders, "allowed-scm-providers", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS", []string{}, ","), "The list of allowed custom SCM provider API URLs. This restriction does not apply to SCM or PR generators which do not accept a custom API URL. (Default: Empty = all)")
|
||||
command.Flags().BoolVar(&enableScmProviders, "enable-scm-providers", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS", true), "Enable retrieving information from SCM providers, used by the SCM and PR generators (Default: true)")
|
||||
|
||||
@@ -36,7 +36,7 @@ func NewCommand() *cobra.Command {
|
||||
Short: "Run ArgoCD ConfigManagementPlugin Server",
|
||||
Long: "ArgoCD ConfigManagementPlugin Server is an internal service which runs as sidecar container in reposerver deployment. The following configuration options are available:",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
ctx := c.Context()
|
||||
|
||||
vers := common.GetVersion()
|
||||
@@ -89,7 +89,7 @@ func NewCommand() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_CMP_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: trace|debug|info|warn|error")
|
||||
command.Flags().StringVar(&configFilePath, "config-dir-path", common.DefaultPluginConfigFilePath, "Config management plugin configuration file location, Default is '/home/argocd/cmp-server/config/'")
|
||||
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_CMP_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
|
||||
|
||||
@@ -38,7 +38,7 @@ func NewCommand() *cobra.Command {
|
||||
Use: "argocd-commit-server",
|
||||
Short: "Run Argo CD Commit Server",
|
||||
Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
vers := common.GetVersion()
|
||||
vers.LogStartupInfo(
|
||||
"Argo CD Commit Server",
|
||||
@@ -106,7 +106,7 @@ func NewCommand() *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS", common.DefaultAddressCommitServer), "Listen on given address for incoming connections")
|
||||
command.Flags().IntVar(&listenPort, "port", common.DefaultPortCommitServer, "Listen on given port for incoming connections")
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewRunDexCommand() *cobra.Command {
|
||||
command := cobra.Command{
|
||||
Use: "rundex",
|
||||
Short: "Runs dex generating a config using settings from the Argo CD configmap and secret",
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
ctx := c.Context()
|
||||
|
||||
vers := common.GetVersion()
|
||||
@@ -144,7 +144,7 @@ func NewRunDexCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
clientConfig = cli.AddKubectlFlagsToCmd(&command)
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_DEX_SERVER_DISABLE_TLS", false), "Disable TLS on the HTTP endpoint")
|
||||
return &command
|
||||
@@ -159,7 +159,7 @@ func NewGenDexConfigCommand() *cobra.Command {
|
||||
command := cobra.Command{
|
||||
Use: "gendexcfg",
|
||||
Short: "Generates a dex config from Argo CD settings",
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
ctx := c.Context()
|
||||
|
||||
cli.SetLogFormat(cmdutil.LogFormat)
|
||||
@@ -212,7 +212,7 @@ func NewGenDexConfigCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
clientConfig = cli.AddKubectlFlagsToCmd(&command)
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_DEX_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().StringVarP(&out, "out", "o", "", "Output to the specified file instead of stdout")
|
||||
command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_DEX_SERVER_DISABLE_TLS", false), "Disable TLS on the HTTP endpoint")
|
||||
@@ -242,9 +242,8 @@ func redactor(dirtyString string) string {
|
||||
iterateStringFields(config, func(name string, val string) string {
|
||||
if name == "clientSecret" || name == "secret" || name == "bindPW" {
|
||||
return "********"
|
||||
} else {
|
||||
return val
|
||||
}
|
||||
return val
|
||||
})
|
||||
data, err := yaml.Marshal(config)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -25,7 +25,7 @@ func NewCommand() *cobra.Command {
|
||||
Use: cliName,
|
||||
Short: "Argo CD git credential helper",
|
||||
DisableAutoGenTag: true,
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
Run: func(c *cobra.Command, _ []string) {
|
||||
ctx := c.Context()
|
||||
|
||||
if len(os.Args) != 2 {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user