mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-08 01:18:47 +01:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
beef23b7a4 | ||
|
|
a97db48111 | ||
|
|
69939d427a | ||
|
|
a7d22df297 | ||
|
|
0f99cdd877 | ||
|
|
3c8c8adb37 | ||
|
|
e0b8b129a5 | ||
|
|
12c6cf3e8c | ||
|
|
197e01b834 | ||
|
|
27ff21643e | ||
|
|
ecdea743c2 | ||
|
|
fca6271d38 | ||
|
|
186c4be175 | ||
|
|
e46ae882f1 | ||
|
|
30f25ce113 | ||
|
|
72f8ff370a | ||
|
|
955417ae4f | ||
|
|
e091a92f6c | ||
|
|
de7d35b069 | ||
|
|
b6d33ba162 | ||
|
|
e3ef547f16 | ||
|
|
2868c5aa0a | ||
|
|
ba5bab807c | ||
|
|
510e3a9557 | ||
|
|
e52895aead | ||
|
|
1e53a3adcb | ||
|
|
7f4b644231 | ||
|
|
9fc46d2a0f | ||
|
|
547f666fb2 | ||
|
|
41a2505bf8 | ||
|
|
b8feaf4db9 | ||
|
|
d330967960 | ||
|
|
158a580df0 | ||
|
|
5e8ac1b2d6 | ||
|
|
7b5899be33 | ||
|
|
efa96006cc | ||
|
|
b871316bba | ||
|
|
c8a1a8650e | ||
|
|
27af817afb | ||
|
|
c7dd9bc6d2 | ||
|
|
e41612927e | ||
|
|
5c79556ab6 | ||
|
|
03b2deec02 | ||
|
|
c0774a0d21 | ||
|
|
2a47eafb5a | ||
|
|
05acf7a52e | ||
|
|
e290faa6c7 | ||
|
|
21a6025d72 | ||
|
|
1a50f7944a | ||
|
|
92df7b877f | ||
|
|
bca4b1adfc | ||
|
|
3f4b12ce0d | ||
|
|
74b5492601 | ||
|
|
187cd4337a | ||
|
|
b20ef3ecae | ||
|
|
3ce54d0b98 | ||
|
|
0d882f6da2 | ||
|
|
8b78e94e37 | ||
|
|
8fc1f80c75 | ||
|
|
983a7b0536 | ||
|
|
761636badf | ||
|
|
cb60ddc696 | ||
|
|
814964f077 | ||
|
|
f360009ff5 | ||
|
|
7381470fbe | ||
|
|
c0ecf0271b | ||
|
|
6686e43b4f | ||
|
|
d321825d9f | ||
|
|
5cf1a6705b | ||
|
|
db7d8be912 | ||
|
|
4d31d46d4c | ||
|
|
029be590bf | ||
|
|
65abd05b60 | ||
|
|
b9fb7623ad | ||
|
|
19ec34e134 | ||
|
|
5f74aa5c24 | ||
|
|
b350c11935 | ||
|
|
c271f1a6c1 | ||
|
|
e6bd9469f8 | ||
|
|
2bb180b3d9 | ||
|
|
216b10e6d8 | ||
|
|
fc8f57a0b5 | ||
|
|
56c2e3c81d | ||
|
|
83931b8515 | ||
|
|
712df99420 | ||
|
|
41f54aa556 | ||
|
|
540fe1b762 | ||
|
|
66ebec630a | ||
|
|
a6b5aa2766 | ||
|
|
1ac264e9a1 | ||
|
|
128a261513 | ||
|
|
8552cc3f07 | ||
|
|
cb05b8fb4a | ||
|
|
2ca18ab5fe | ||
|
|
e8d2d3a7e0 | ||
|
|
6d348ce4a1 | ||
|
|
3c2683dfe9 | ||
|
|
8aa4df6f17 | ||
|
|
7db5c5c589 | ||
|
|
3d9e9f2f95 | ||
|
|
ca7d83f645 | ||
|
|
e59f4889a4 | ||
|
|
fea6197af4 | ||
|
|
5b576acf5d |
78
.github/workflows/ci-build.yaml
vendored
78
.github/workflows/ci-build.yaml
vendored
@@ -18,15 +18,18 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-go:
|
||||
name: Ensure Go modules synchronicity
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Download all Go modules
|
||||
@@ -42,13 +45,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -59,17 +62,20 @@ jobs:
|
||||
run: make build-local
|
||||
|
||||
lint-go:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
name: Lint Go code
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
uses: golangci/golangci-lint-action@0ad9a0988b3973e851ab0a07adf248ec2e100376 # v3.3.1
|
||||
with:
|
||||
version: v1.45.2
|
||||
args: --timeout 10m --exclude SA5011 --verbose
|
||||
@@ -86,11 +92,11 @@ jobs:
|
||||
- name: Create checkout directory
|
||||
run: mkdir -p ~/go/src/github.com/argoproj
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -110,7 +116,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -127,12 +133,12 @@ jobs:
|
||||
- name: Run all unit tests
|
||||
run: make test-local
|
||||
- name: Generate code coverage artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
|
||||
with:
|
||||
name: code-coverage
|
||||
path: coverage.out
|
||||
- name: Generate test results artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
|
||||
with:
|
||||
name: test-results
|
||||
path: test-results/
|
||||
@@ -149,11 +155,11 @@ jobs:
|
||||
- name: Create checkout directory
|
||||
run: mkdir -p ~/go/src/github.com/argoproj
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -173,7 +179,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -190,7 +196,7 @@ jobs:
|
||||
- name: Run all unit tests
|
||||
run: make test-race-local
|
||||
- name: Generate test results artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
|
||||
with:
|
||||
name: race-results
|
||||
path: test-results/
|
||||
@@ -200,9 +206,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Create symlink in GOPATH
|
||||
@@ -244,14 +250,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3.5.1
|
||||
with:
|
||||
node-version: '12.18.4'
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -281,12 +287,12 @@ jobs:
|
||||
sonar_secret: ${{ secrets.SONAR_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -297,16 +303,16 @@ jobs:
|
||||
run: |
|
||||
mkdir -p test-results
|
||||
- name: Get code coverage artifiact
|
||||
uses: actions/download-artifact@v2
|
||||
uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1
|
||||
with:
|
||||
name: code-coverage
|
||||
- name: Get test result artifact
|
||||
uses: actions/download-artifact@v2
|
||||
uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1
|
||||
with:
|
||||
name: test-results
|
||||
path: test-results
|
||||
- name: Upload code coverage information to codecov.io
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1
|
||||
with:
|
||||
file: coverage.out
|
||||
- name: Perform static code analysis using SonarCloud
|
||||
@@ -359,14 +365,22 @@ jobs:
|
||||
GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: GH actions workaround - Kill XSP4 process
|
||||
run: |
|
||||
sudo pkill mono || true
|
||||
# ubuntu-22.04 comes with kubectl, but the version is not pinned. The version as of 2022-12-05 is 1.26.0 which
|
||||
# breaks the `TestNamespacedResourceDiffing` e2e test. So we'll pin to 1.25 and then fix the underlying issue.
|
||||
- name: Install kubectl
|
||||
run: |
|
||||
rm /usr/local/bin/kubectl
|
||||
curl -LO https://dl.k8s.io/release/v1.25.4/bin/linux/amd64/kubectl
|
||||
mv kubectl /usr/local/bin/kubectl
|
||||
chmod +x /usr/local/bin/kubectl
|
||||
- name: Install K3S
|
||||
env:
|
||||
INSTALL_K3S_VERSION: ${{ matrix.k3s-version }}+k3s1
|
||||
@@ -379,7 +393,7 @@ jobs:
|
||||
sudo chown runner $HOME/.kube/config
|
||||
kubectl version
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -405,7 +419,7 @@ jobs:
|
||||
git config --global user.email "john.doe@example.com"
|
||||
- name: Pull Docker image required for tests
|
||||
run: |
|
||||
docker pull quay.io/dexidp/dex:v2.25.0
|
||||
docker pull ghcr.io/dexidp/dex:v2.35.3
|
||||
docker pull argoproj/argo-cd-ci-builder:v1.0.0
|
||||
docker pull redis:7.0.4-alpine
|
||||
- name: Create target directory for binaries in the build-process
|
||||
@@ -435,7 +449,7 @@ jobs:
|
||||
set -x
|
||||
make test-e2e-local
|
||||
- name: Upload e2e-server logs
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
|
||||
with:
|
||||
name: e2e-server-k8s${{ matrix.k3s-version }}.log
|
||||
path: /tmp/e2e-server.log
|
||||
|
||||
15
.github/workflows/codeql.yml
vendored
15
.github/workflows/codeql.yml
vendored
@@ -13,8 +13,15 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
permissions:
|
||||
actions: read # for github/codeql-action/init to get workflow details
|
||||
contents: read # for actions/checkout to fetch code
|
||||
security-events: write # for github/codeql-action/autobuild to send a status report
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
@@ -22,11 +29,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@8aff97f12c99086bdb92ff62ae06dbbcdf07941b # v2.1.33
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
@@ -34,7 +41,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@8aff97f12c99086bdb92ff62ae06dbbcdf07941b # v2.1.33
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -48,4 +55,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@8aff97f12c99086bdb92ff62ae06dbbcdf07941b # v2.1.33
|
||||
|
||||
37
.github/workflows/image.yaml
vendored
37
.github/workflows/image.yaml
vendored
@@ -16,29 +16,34 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
permissions:
|
||||
contents: write # for git to push upgrade commit if not already deployed
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOPATH: /home/runner/work/argo-cd/argo-cd
|
||||
steps:
|
||||
- uses: actions/setup-go@v1
|
||||
- uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
with:
|
||||
path: src/github.com/argoproj/argo-cd
|
||||
|
||||
# get image tag
|
||||
- run: echo ::set-output name=tag::$(cat ./VERSION)-${GITHUB_SHA::8}
|
||||
- run: echo "tag=$(cat ./VERSION)-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT
|
||||
working-directory: ./src/github.com/argoproj/argo-cd
|
||||
id: image
|
||||
|
||||
# login
|
||||
- run: |
|
||||
docker login ghcr.io --username $USERNAME --password $PASSWORD
|
||||
docker login quay.io --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
|
||||
docker login ghcr.io --username $USERNAME --password-stdin <<< "$PASSWORD"
|
||||
docker login quay.io --username "$DOCKER_USERNAME" --password-stdin <<< "$DOCKER_TOKEN"
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
USERNAME: ${{ secrets.USERNAME }}
|
||||
@@ -47,11 +52,11 @@ jobs:
|
||||
DOCKER_TOKEN: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
|
||||
# build
|
||||
- uses: docker/setup-qemu-action@v1
|
||||
- uses: docker/setup-buildx-action@v1
|
||||
- uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0
|
||||
- uses: docker/setup-buildx-action@8c0edbc76e98fa90f69d9a2c020dcb50019dc325 # v2.2.1
|
||||
|
||||
- name: Setup cache for argocd-ui docker layer
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-single-buildx-${{ github.sha }}
|
||||
@@ -110,6 +115,22 @@ jobs:
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'test-arm-image')
|
||||
|
||||
# sign container images
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.8.1
|
||||
with:
|
||||
cosign-release: 'v1.13.0'
|
||||
|
||||
- name: Sign Argo CD latest image
|
||||
run: |
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/argocd:latest
|
||||
# Displays the public key to share.
|
||||
cosign public-key --key env://COSIGN_PRIVATE_KEY
|
||||
env:
|
||||
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
|
||||
# deploy
|
||||
- run: git clone "https://$TOKEN@github.com/argoproj/argoproj-deployments"
|
||||
if: github.event_name == 'push'
|
||||
|
||||
52
.github/workflows/release.yaml
vendored
52
.github/workflows/release.yaml
vendored
@@ -14,8 +14,13 @@ on:
|
||||
env:
|
||||
GOLANG_VERSION: '1.18'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
prepare-release:
|
||||
permissions:
|
||||
contents: write # To push changes to release branch
|
||||
name: Perform automatic release on trigger ${{ github.ref }}
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -38,7 +43,7 @@ jobs:
|
||||
GIT_EMAIL: argoproj@gmail.com
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -142,7 +147,7 @@ jobs:
|
||||
echo "RELEASE_NOTES=${RELEASE_NOTES}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
|
||||
@@ -190,13 +195,13 @@ jobs:
|
||||
QUAY_TOKEN: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
run: |
|
||||
set -ue
|
||||
docker login quay.io --username "${QUAY_USERNAME}" --password "${QUAY_TOKEN}"
|
||||
docker login quay.io --username "${QUAY_USERNAME}" --password-stdin <<< "${QUAY_TOKEN}"
|
||||
# Remove the following when Docker Hub is gone
|
||||
docker login --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
|
||||
docker login --username "${DOCKER_USERNAME}" --password-stdin <<< "${DOCKER_TOKEN}"
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- uses: docker/setup-qemu-action@v1
|
||||
- uses: docker/setup-buildx-action@v1
|
||||
- uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0
|
||||
- uses: docker/setup-buildx-action@8c0edbc76e98fa90f69d9a2c020dcb50019dc325 # v2.2.1
|
||||
- name: Build and push Docker image for release
|
||||
run: |
|
||||
set -ue
|
||||
@@ -209,9 +214,25 @@ jobs:
|
||||
./dist/argocd-linux-amd64 version --client
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.8.1
|
||||
with:
|
||||
cosign-release: 'v1.13.0'
|
||||
|
||||
- name: Sign Argo CD container images and assets
|
||||
run: |
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION}
|
||||
cosign sign-blob --key env://COSIGN_PRIVATE_KEY ./dist/argocd-${TARGET_VERSION}-checksums.txt > ./dist/argocd-${TARGET_VERSION}-checksums.sig
|
||||
# Retrieves the public key to release as an asset
|
||||
cosign public-key --key env://COSIGN_PRIVATE_KEY > ./dist/argocd-cosign.pub
|
||||
env:
|
||||
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- name: Read release notes file
|
||||
id: release-notes
|
||||
uses: juliangruber/read-file-action@v1
|
||||
uses: juliangruber/read-file-action@02bbba9876a8f870efd4ad64e3b9088d3fb94d4b # v1.1.6
|
||||
with:
|
||||
path: ${{ env.RELEASE_NOTES }}
|
||||
|
||||
@@ -222,7 +243,7 @@ jobs:
|
||||
git push origin ${RELEASE_TAG}
|
||||
|
||||
- name: Dry run GitHub release
|
||||
uses: actions/create-release@v1
|
||||
uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1.1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
id: create_release
|
||||
@@ -265,8 +286,16 @@ jobs:
|
||||
cd /tmp && tar -zcf sbom.tar.gz *.spdx
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- name: Sign sbom
|
||||
run: |
|
||||
cosign sign-blob --key env://COSIGN_PRIVATE_KEY /tmp/sbom.tar.gz > /tmp/sbom.tar.gz.sig
|
||||
env:
|
||||
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -274,16 +303,17 @@ jobs:
|
||||
tag_name: ${{ env.RELEASE_TAG }}
|
||||
draft: ${{ env.DRAFT_RELEASE }}
|
||||
prerelease: ${{ env.PRE_RELEASE }}
|
||||
body: ${{ steps.release-notes.outputs.content }}
|
||||
body: ${{ steps.release-notes.outputs.content }} # Pre-pended to the generated notes
|
||||
files: |
|
||||
dist/argocd-*
|
||||
/tmp/sbom.tar.gz
|
||||
/tmp/sbom.tar.gz.sig
|
||||
if: ${{ env.DRY_RUN != 'true' }}
|
||||
|
||||
- name: Update homebrew formula
|
||||
env:
|
||||
HOMEBREW_TOKEN: ${{ secrets.RELEASE_HOMEBREW_TOKEN }}
|
||||
uses: dawidd6/action-homebrew-bump-formula@v3
|
||||
uses: dawidd6/action-homebrew-bump-formula@02e79d9da43d79efa846d73695b6052cbbdbf48a # v3.8.3
|
||||
with:
|
||||
token: ${{env.HOMEBREW_TOKEN}}
|
||||
formula: argocd
|
||||
|
||||
8
Makefile
8
Makefile
@@ -25,7 +25,7 @@ DOCKER_WORKDIR?=/go/src/github.com/argoproj/argo-cd
|
||||
|
||||
ARGOCD_PROCFILE?=Procfile
|
||||
|
||||
# Strict mode has been disabled in latest versions of mkdocs-material.
|
||||
# Strict mode has been disabled in latest versions of mkdocs-material.
|
||||
# Thus pointing to the older image of mkdocs-material matching the version used by argo-cd.
|
||||
MKDOCS_DOCKER_IMAGE?=squidfunk/mkdocs-material:4.1.1
|
||||
MKDOCS_RUN_ARGS?=
|
||||
@@ -114,7 +114,7 @@ define run-in-test-client
|
||||
bash -c "$(1)"
|
||||
endef
|
||||
|
||||
#
|
||||
#
|
||||
define exec-in-test-server
|
||||
docker exec -it -u $(shell id -u):$(shell id -g) -e ARGOCD_E2E_K3S=$(ARGOCD_E2E_K3S) argocd-test-server $(1)
|
||||
endef
|
||||
@@ -205,7 +205,7 @@ clientgen: ensure-gopath
|
||||
|
||||
.PHONY: clidocsgen
|
||||
clidocsgen: ensure-gopath
|
||||
go run tools/cmd-docs/main.go
|
||||
go run tools/cmd-docs/main.go
|
||||
|
||||
|
||||
.PHONY: codegen-local
|
||||
@@ -568,4 +568,4 @@ applicationset-controller:
|
||||
|
||||
.PHONY: checksums
|
||||
checksums:
|
||||
for f in ./dist/$(BIN_NAME)-*; do openssl dgst -sha256 "$$f" | awk ' { print $$2 }' > "$$f".sha256 ; done
|
||||
sha256sum ./dist/$(BIN_NAME)-* | awk -F './dist/' '{print $$1 $$2}' > ./dist/$(BIN_NAME)-$(TARGET_VERSION)-checksums.txt
|
||||
|
||||
@@ -20,11 +20,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
log "github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/record"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
@@ -33,18 +38,10 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/utils"
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/util/db"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
|
||||
argoutil "github.com/argoproj/argo-cd/v2/util/argo"
|
||||
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
"github.com/argoproj/argo-cd/v2/util/db"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,6 +52,13 @@ const (
|
||||
ReconcileRequeueOnValidationError = time.Minute * 3
|
||||
)
|
||||
|
||||
var (
|
||||
preservedAnnotations = []string{
|
||||
NotifiedAnnotationKey,
|
||||
argov1alpha1.AnnotationKeyRefresh,
|
||||
}
|
||||
)
|
||||
|
||||
// ApplicationSetReconciler reconciles a ApplicationSet object
|
||||
type ApplicationSetReconciler struct {
|
||||
client.Client
|
||||
@@ -527,12 +531,16 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
|
||||
// Copy only the Application/ObjectMeta fields that are significant, from the generatedApp
|
||||
found.Spec = generatedApp.Spec
|
||||
|
||||
// Preserve argo cd notifications state (https://github.com/argoproj/applicationset/issues/180)
|
||||
if state, exists := found.ObjectMeta.Annotations[NotifiedAnnotationKey]; exists {
|
||||
if generatedApp.Annotations == nil {
|
||||
generatedApp.Annotations = map[string]string{}
|
||||
// Preserve specially treated argo cd annotations:
|
||||
// * https://github.com/argoproj/applicationset/issues/180
|
||||
// * https://github.com/argoproj/argo-cd/issues/10500
|
||||
for _, key := range preservedAnnotations {
|
||||
if state, exists := found.ObjectMeta.Annotations[key]; exists {
|
||||
if generatedApp.Annotations == nil {
|
||||
generatedApp.Annotations = map[string]string{}
|
||||
}
|
||||
generatedApp.Annotations[key] = state
|
||||
}
|
||||
generatedApp.Annotations[NotifiedAnnotationKey] = state
|
||||
}
|
||||
found.ObjectMeta.Annotations = generatedApp.Annotations
|
||||
|
||||
|
||||
@@ -13,9 +13,11 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
kubefake "k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/record"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
crtclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -25,10 +27,6 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/generators"
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/utils"
|
||||
argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
kubefake "k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
|
||||
@@ -755,7 +753,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ensure that argocd notifications state annotation is preserved from an existing app",
|
||||
name: "Ensure that argocd notifications state and refresh annotation is preserved from an existing app",
|
||||
appSet: argoprojiov1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
@@ -781,8 +779,9 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
|
||||
ResourceVersion: "2",
|
||||
Labels: map[string]string{"label-key": "label-value"},
|
||||
Annotations: map[string]string{
|
||||
"annot-key": "annot-value",
|
||||
NotifiedAnnotationKey: `{"b620d4600c771a6f4cxxxxxxx:on-deployed:[0].y7b5sbwa2Q329JYHxxxxxx-fBs:slack:slack-test":1617144614}`,
|
||||
"annot-key": "annot-value",
|
||||
NotifiedAnnotationKey: `{"b620d4600c771a6f4cxxxxxxx:on-deployed:[0].y7b5sbwa2Q329JYHxxxxxx-fBs:slack:slack-test":1617144614}`,
|
||||
argov1alpha1.AnnotationKeyRefresh: string(argov1alpha1.RefreshTypeNormal),
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
@@ -811,7 +810,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
|
||||
Namespace: "namespace",
|
||||
ResourceVersion: "3",
|
||||
Annotations: map[string]string{
|
||||
NotifiedAnnotationKey: `{"b620d4600c771a6f4cxxxxxxx:on-deployed:[0].y7b5sbwa2Q329JYHxxxxxx-fBs:slack:slack-test":1617144614}`,
|
||||
NotifiedAnnotationKey: `{"b620d4600c771a6f4cxxxxxxx:on-deployed:[0].y7b5sbwa2Q329JYHxxxxxx-fBs:slack:slack-test":1617144614}`,
|
||||
argov1alpha1.AnnotationKeyRefresh: string(argov1alpha1.RefreshTypeNormal),
|
||||
},
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSpec{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#namePrefix: kustomize-
|
||||
|
||||
resources:
|
||||
- namespace-install.yaml
|
||||
- https://github.com/argoproj/argo-workflows/releases/download/v3.4.0/namespace-install.yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
@@ -1,417 +0,0 @@
|
||||
# This is an auto-generated file. DO NOT EDIT
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: clusterworkflowtemplates.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: ClusterWorkflowTemplate
|
||||
listKind: ClusterWorkflowTemplateList
|
||||
plural: clusterworkflowtemplates
|
||||
shortNames:
|
||||
- clusterwftmpl
|
||||
- cwft
|
||||
singular: clusterworkflowtemplate
|
||||
scope: Cluster
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: cronworkflows.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: CronWorkflow
|
||||
listKind: CronWorkflowList
|
||||
plural: cronworkflows
|
||||
shortNames:
|
||||
- cwf
|
||||
- cronwf
|
||||
singular: cronworkflow
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workfloweventbindings.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: WorkflowEventBinding
|
||||
listKind: WorkflowEventBindingList
|
||||
plural: workfloweventbindings
|
||||
shortNames:
|
||||
- wfeb
|
||||
singular: workfloweventbinding
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workflows.argoproj.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.phase
|
||||
description: Status of the workflow
|
||||
name: Status
|
||||
type: string
|
||||
- JSONPath: .status.startedAt
|
||||
description: When the workflow was started
|
||||
format: date-time
|
||||
name: Age
|
||||
type: date
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: Workflow
|
||||
listKind: WorkflowList
|
||||
plural: workflows
|
||||
shortNames:
|
||||
- wf
|
||||
singular: workflow
|
||||
scope: Namespaced
|
||||
subresources: {}
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workflowtemplates.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: WorkflowTemplate
|
||||
listKind: WorkflowTemplateList
|
||||
plural: workflowtemplates
|
||||
shortNames:
|
||||
- wftmpl
|
||||
singular: workflowtemplate
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: argo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: argo-server
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: argo-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
- workflows/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- create
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflowtemplates
|
||||
- workflowtemplates/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- cronworkflows
|
||||
- cronworkflows/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- policy
|
||||
resources:
|
||||
- poddisruptionbudgets
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: argo-server-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
- workfloweventbindings
|
||||
- workflowtemplates
|
||||
- cronworkflows
|
||||
- cronworkflows/finalizers
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: argo-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: argo-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: argo
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: argo-server-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: argo-server-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: argo-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: workflow-controller-configmap
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: argo-server
|
||||
spec:
|
||||
ports:
|
||||
- name: web
|
||||
port: 2746
|
||||
targetPort: 2746
|
||||
selector:
|
||||
app: argo-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: workflow-controller-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 9090
|
||||
protocol: TCP
|
||||
targetPort: 9090
|
||||
selector:
|
||||
app: workflow-controller
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: argo-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: argo-server
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: argo-server
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- server
|
||||
- --namespaced
|
||||
image: argoproj/argocli:v2.12.5
|
||||
name: argo-server
|
||||
ports:
|
||||
- containerPort: 2746
|
||||
name: web
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 2746
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
volumeMounts:
|
||||
- mountPath: /tmp
|
||||
name: tmp
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: argo-server
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: tmp
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: workflow-controller
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: workflow-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: workflow-controller
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- --configmap
|
||||
- workflow-controller-configmap
|
||||
- --executor-image
|
||||
- argoproj/argoexec:v2.12.5
|
||||
- --namespaced
|
||||
command:
|
||||
- workflow-controller
|
||||
image: argoproj/workflow-controller:v2.12.5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /metrics
|
||||
port: metrics
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
name: workflow-controller
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
name: metrics
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: argo
|
||||
@@ -11,4 +11,4 @@ version: 0.1.0
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: "1.0"
|
||||
appVersion: "1.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
dependencies:
|
||||
- name: kube-prometheus-stack
|
||||
version: 9.4.10
|
||||
version: 40.5.0
|
||||
repository: https://prometheus-community.github.io/helm-charts
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#namePrefix: kustomize-
|
||||
|
||||
resources:
|
||||
- namespace-install.yaml
|
||||
- https://github.com/argoproj/argo-workflows/releases/download/v3.4.0/namespace-install.yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
@@ -1,417 +0,0 @@
|
||||
# This is an auto-generated file. DO NOT EDIT
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: clusterworkflowtemplates.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: ClusterWorkflowTemplate
|
||||
listKind: ClusterWorkflowTemplateList
|
||||
plural: clusterworkflowtemplates
|
||||
shortNames:
|
||||
- clusterwftmpl
|
||||
- cwft
|
||||
singular: clusterworkflowtemplate
|
||||
scope: Cluster
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: cronworkflows.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: CronWorkflow
|
||||
listKind: CronWorkflowList
|
||||
plural: cronworkflows
|
||||
shortNames:
|
||||
- cwf
|
||||
- cronwf
|
||||
singular: cronworkflow
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workfloweventbindings.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: WorkflowEventBinding
|
||||
listKind: WorkflowEventBindingList
|
||||
plural: workfloweventbindings
|
||||
shortNames:
|
||||
- wfeb
|
||||
singular: workfloweventbinding
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workflows.argoproj.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.phase
|
||||
description: Status of the workflow
|
||||
name: Status
|
||||
type: string
|
||||
- JSONPath: .status.startedAt
|
||||
description: When the workflow was started
|
||||
format: date-time
|
||||
name: Age
|
||||
type: date
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: Workflow
|
||||
listKind: WorkflowList
|
||||
plural: workflows
|
||||
shortNames:
|
||||
- wf
|
||||
singular: workflow
|
||||
scope: Namespaced
|
||||
subresources: {}
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: workflowtemplates.argoproj.io
|
||||
spec:
|
||||
group: argoproj.io
|
||||
names:
|
||||
kind: WorkflowTemplate
|
||||
listKind: WorkflowTemplateList
|
||||
plural: workflowtemplates
|
||||
shortNames:
|
||||
- wftmpl
|
||||
singular: workflowtemplate
|
||||
scope: Namespaced
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: argo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: argo-server
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: argo-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
- workflows/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- create
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflowtemplates
|
||||
- workflowtemplates/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- cronworkflows
|
||||
- cronworkflows/finalizers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- policy
|
||||
resources:
|
||||
- poddisruptionbudgets
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: argo-server-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- list
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- argoproj.io
|
||||
resources:
|
||||
- workflows
|
||||
- workfloweventbindings
|
||||
- workflowtemplates
|
||||
- cronworkflows
|
||||
- cronworkflows/finalizers
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: argo-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: argo-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: argo
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: argo-server-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: argo-server-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: argo-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: workflow-controller-configmap
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: argo-server
|
||||
spec:
|
||||
ports:
|
||||
- name: web
|
||||
port: 2746
|
||||
targetPort: 2746
|
||||
selector:
|
||||
app: argo-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: workflow-controller-metrics
|
||||
spec:
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 9090
|
||||
protocol: TCP
|
||||
targetPort: 9090
|
||||
selector:
|
||||
app: workflow-controller
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: argo-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: argo-server
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: argo-server
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- server
|
||||
- --namespaced
|
||||
image: argoproj/argocli:v2.12.5
|
||||
name: argo-server
|
||||
ports:
|
||||
- containerPort: 2746
|
||||
name: web
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 2746
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
volumeMounts:
|
||||
- mountPath: /tmp
|
||||
name: tmp
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: argo-server
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: tmp
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: workflow-controller
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: workflow-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: workflow-controller
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- --configmap
|
||||
- workflow-controller-configmap
|
||||
- --executor-image
|
||||
- argoproj/argoexec:v2.12.5
|
||||
- --namespaced
|
||||
command:
|
||||
- workflow-controller
|
||||
image: argoproj/workflow-controller:v2.12.5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /metrics
|
||||
port: metrics
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
name: workflow-controller
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
name: metrics
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: argo
|
||||
@@ -1 +1,14 @@
|
||||
apiVersion: v2
|
||||
name: helm-prometheus-operator
|
||||
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: "1.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
dependencies:
|
||||
- name: kube-prometheus-stack
|
||||
version: 9.4.10
|
||||
version: 40.5.0
|
||||
repository: https://prometheus-community.github.io/helm-charts
|
||||
|
||||
@@ -2,6 +2,7 @@ apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: cluster-addons
|
||||
namespace: argocd
|
||||
spec:
|
||||
generators:
|
||||
- git:
|
||||
@@ -15,7 +16,7 @@ spec:
|
||||
metadata:
|
||||
name: '{{path.basename}}'
|
||||
spec:
|
||||
project: default
|
||||
project: "my-project"
|
||||
source:
|
||||
repoURL: https://github.com/argoproj/argo-cd.git
|
||||
targetRevision: HEAD
|
||||
@@ -23,3 +24,6 @@ spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: '{{path.basename}}'
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
|
||||
@@ -2,6 +2,7 @@ apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: cluster-addons
|
||||
namespace: argocd
|
||||
spec:
|
||||
generators:
|
||||
- git:
|
||||
@@ -13,7 +14,7 @@ spec:
|
||||
metadata:
|
||||
name: '{{path.basename}}'
|
||||
spec:
|
||||
project: default
|
||||
project: "my-project"
|
||||
source:
|
||||
repoURL: https://github.com/argoproj/argo-cd.git
|
||||
targetRevision: HEAD
|
||||
@@ -21,3 +22,6 @@ spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: '{{path.basename}}'
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
|
||||
@@ -101,6 +101,15 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
|
||||
if scmError != nil {
|
||||
return nil, fmt.Errorf("error initializing Bitbucket Server service: %v", scmError)
|
||||
}
|
||||
} else if providerConfig.Bitbucket != nil {
|
||||
appPassword, err := g.getSecretRef(ctx, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching Bitbucket cloud appPassword: %v", err)
|
||||
}
|
||||
provider, err = scm_provider.NewBitBucketCloudProvider(ctx, providerConfig.Bitbucket.Owner, providerConfig.Bitbucket.User, appPassword, providerConfig.Bitbucket.AllBranches)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing Bitbucket cloud service: %v", err)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("no SCM provider implementation configured")
|
||||
}
|
||||
|
||||
@@ -2,13 +2,253 @@ package pull_request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
fmt.Println(r.RequestURI)
|
||||
switch r.RequestURI {
|
||||
case "/api/v1/version":
|
||||
_, err := io.WriteString(w, `{"version":"1.17.0+dev-452-g1f0541780"}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v1/repos/test-argocd/pr-test/pulls?limit=0&page=1&state=open":
|
||||
_, err := io.WriteString(w, `[{
|
||||
"id": 50721,
|
||||
"url": "https://gitea.com/test-argocd/pr-test/pulls/1",
|
||||
"number": 1,
|
||||
"user": {
|
||||
"id": 4476,
|
||||
"login": "graytshirt",
|
||||
"full_name": "Dan",
|
||||
"email": "graytshirt@noreply.gitea.io",
|
||||
"avatar_url": "https://secure.gravatar.com/avatar/2446c67bcd59d71f6ae3cf376ec2ae37?d=identicon",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2020-04-07T01:14:36+08:00",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 4,
|
||||
"starred_repos_count": 1,
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"title": "add an empty file",
|
||||
"body": "",
|
||||
"labels": [],
|
||||
"milestone": null,
|
||||
"assignee": null,
|
||||
"assignees": null,
|
||||
"state": "open",
|
||||
"is_locked": false,
|
||||
"comments": 0,
|
||||
"html_url": "https://gitea.com/test-argocd/pr-test/pulls/1",
|
||||
"diff_url": "https://gitea.com/test-argocd/pr-test/pulls/1.diff",
|
||||
"patch_url": "https://gitea.com/test-argocd/pr-test/pulls/1.patch",
|
||||
"mergeable": true,
|
||||
"merged": false,
|
||||
"merged_at": null,
|
||||
"merge_commit_sha": null,
|
||||
"merged_by": null,
|
||||
"base": {
|
||||
"label": "main",
|
||||
"ref": "main",
|
||||
"sha": "72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"repo_id": 21618,
|
||||
"repo": {
|
||||
"id": 21618,
|
||||
"owner": {
|
||||
"id": 31480,
|
||||
"login": "test-argocd",
|
||||
"full_name": "",
|
||||
"email": "",
|
||||
"avatar_url": "https://gitea.com/avatars/22d1b1d3f61abf95951c4a958731d848",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2022-04-06T02:28:06+08:00",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "test-argocd"
|
||||
},
|
||||
"name": "pr-test",
|
||||
"full_name": "test-argocd/pr-test",
|
||||
"description": "",
|
||||
"empty": false,
|
||||
"private": false,
|
||||
"fork": false,
|
||||
"template": false,
|
||||
"parent": null,
|
||||
"mirror": false,
|
||||
"size": 28,
|
||||
"language": "",
|
||||
"languages_url": "https://gitea.com/api/v1/repos/test-argocd/pr-test/languages",
|
||||
"html_url": "https://gitea.com/test-argocd/pr-test",
|
||||
"ssh_url": "git@gitea.com:test-argocd/pr-test.git",
|
||||
"clone_url": "https://gitea.com/test-argocd/pr-test.git",
|
||||
"original_url": "",
|
||||
"website": "",
|
||||
"stars_count": 0,
|
||||
"forks_count": 0,
|
||||
"watchers_count": 1,
|
||||
"open_issues_count": 0,
|
||||
"open_pr_counter": 1,
|
||||
"release_counter": 0,
|
||||
"default_branch": "main",
|
||||
"archived": false,
|
||||
"created_at": "2022-04-06T02:32:09+08:00",
|
||||
"updated_at": "2022-04-06T02:33:12+08:00",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"has_issues": true,
|
||||
"internal_tracker": {
|
||||
"enable_time_tracker": true,
|
||||
"allow_only_contributors_to_track_time": true,
|
||||
"enable_issue_dependencies": true
|
||||
},
|
||||
"has_wiki": true,
|
||||
"has_pull_requests": true,
|
||||
"has_projects": true,
|
||||
"ignore_whitespace_conflicts": false,
|
||||
"allow_merge_commits": true,
|
||||
"allow_rebase": true,
|
||||
"allow_rebase_explicit": true,
|
||||
"allow_squash_merge": true,
|
||||
"default_merge_style": "merge",
|
||||
"avatar_url": "",
|
||||
"internal": false,
|
||||
"mirror_interval": "",
|
||||
"mirror_updated": "0001-01-01T00:00:00Z",
|
||||
"repo_transfer": null
|
||||
}
|
||||
},
|
||||
"head": {
|
||||
"label": "test",
|
||||
"ref": "test",
|
||||
"sha": "7bbaf62d92ddfafd9cc8b340c619abaec32bc09f",
|
||||
"repo_id": 21618,
|
||||
"repo": {
|
||||
"id": 21618,
|
||||
"owner": {
|
||||
"id": 31480,
|
||||
"login": "test-argocd",
|
||||
"full_name": "",
|
||||
"email": "",
|
||||
"avatar_url": "https://gitea.com/avatars/22d1b1d3f61abf95951c4a958731d848",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2022-04-06T02:28:06+08:00",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "test-argocd"
|
||||
},
|
||||
"name": "pr-test",
|
||||
"full_name": "test-argocd/pr-test",
|
||||
"description": "",
|
||||
"empty": false,
|
||||
"private": false,
|
||||
"fork": false,
|
||||
"template": false,
|
||||
"parent": null,
|
||||
"mirror": false,
|
||||
"size": 28,
|
||||
"language": "",
|
||||
"languages_url": "https://gitea.com/api/v1/repos/test-argocd/pr-test/languages",
|
||||
"html_url": "https://gitea.com/test-argocd/pr-test",
|
||||
"ssh_url": "git@gitea.com:test-argocd/pr-test.git",
|
||||
"clone_url": "https://gitea.com/test-argocd/pr-test.git",
|
||||
"original_url": "",
|
||||
"website": "",
|
||||
"stars_count": 0,
|
||||
"forks_count": 0,
|
||||
"watchers_count": 1,
|
||||
"open_issues_count": 0,
|
||||
"open_pr_counter": 1,
|
||||
"release_counter": 0,
|
||||
"default_branch": "main",
|
||||
"archived": false,
|
||||
"created_at": "2022-04-06T02:32:09+08:00",
|
||||
"updated_at": "2022-04-06T02:33:12+08:00",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"has_issues": true,
|
||||
"internal_tracker": {
|
||||
"enable_time_tracker": true,
|
||||
"allow_only_contributors_to_track_time": true,
|
||||
"enable_issue_dependencies": true
|
||||
},
|
||||
"has_wiki": true,
|
||||
"has_pull_requests": true,
|
||||
"has_projects": true,
|
||||
"ignore_whitespace_conflicts": false,
|
||||
"allow_merge_commits": true,
|
||||
"allow_rebase": true,
|
||||
"allow_rebase_explicit": true,
|
||||
"allow_squash_merge": true,
|
||||
"default_merge_style": "merge",
|
||||
"avatar_url": "",
|
||||
"internal": false,
|
||||
"mirror_interval": "",
|
||||
"mirror_updated": "0001-01-01T00:00:00Z",
|
||||
"repo_transfer": null
|
||||
}
|
||||
},
|
||||
"merge_base": "72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"due_date": null,
|
||||
"created_at": "2022-04-06T02:34:24+08:00",
|
||||
"updated_at": "2022-04-06T02:34:24+08:00",
|
||||
"closed_at": null
|
||||
}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGiteaList(t *testing.T) {
|
||||
host, err := NewGiteaService(context.Background(), "", "https://gitea.com", "test-argocd", "pr-test", false)
|
||||
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)
|
||||
assert.Nil(t, err)
|
||||
prs, err := host.List(context.Background())
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -2,13 +2,262 @@ package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/testdata"
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
)
|
||||
|
||||
func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.RequestURI {
|
||||
case "/api/v1/version":
|
||||
_, err := io.WriteString(w, `{"version":"1.17.0+dev-452-g1f0541780"}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v1/orgs/test-argocd/repos?limit=0&page=1":
|
||||
_, err := io.WriteString(w, `[{
|
||||
"id": 21618,
|
||||
"owner": {
|
||||
"id": 31480,
|
||||
"login": "test-argocd",
|
||||
"full_name": "",
|
||||
"email": "",
|
||||
"avatar_url": "https://gitea.com/avatars/22d1b1d3f61abf95951c4a958731d848",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "0001-01-01T00:00:00Z",
|
||||
"created": "2022-04-06T02:28:06+08:00",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "test-argocd"
|
||||
},
|
||||
"name": "pr-test",
|
||||
"full_name": "test-argocd/pr-test",
|
||||
"description": "",
|
||||
"empty": false,
|
||||
"private": false,
|
||||
"fork": false,
|
||||
"template": false,
|
||||
"parent": null,
|
||||
"mirror": false,
|
||||
"size": 28,
|
||||
"language": "",
|
||||
"languages_url": "https://gitea.com/api/v1/repos/test-argocd/pr-test/languages",
|
||||
"html_url": "https://gitea.com/test-argocd/pr-test",
|
||||
"ssh_url": "git@gitea.com:test-argocd/pr-test.git",
|
||||
"clone_url": "https://gitea.com/test-argocd/pr-test.git",
|
||||
"original_url": "",
|
||||
"website": "",
|
||||
"stars_count": 0,
|
||||
"forks_count": 0,
|
||||
"watchers_count": 1,
|
||||
"open_issues_count": 0,
|
||||
"open_pr_counter": 1,
|
||||
"release_counter": 0,
|
||||
"default_branch": "main",
|
||||
"archived": false,
|
||||
"created_at": "2022-04-06T02:32:09+08:00",
|
||||
"updated_at": "2022-04-06T02:33:12+08:00",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"has_issues": true,
|
||||
"internal_tracker": {
|
||||
"enable_time_tracker": true,
|
||||
"allow_only_contributors_to_track_time": true,
|
||||
"enable_issue_dependencies": true
|
||||
},
|
||||
"has_wiki": true,
|
||||
"has_pull_requests": true,
|
||||
"has_projects": true,
|
||||
"ignore_whitespace_conflicts": false,
|
||||
"allow_merge_commits": true,
|
||||
"allow_rebase": true,
|
||||
"allow_rebase_explicit": true,
|
||||
"allow_squash_merge": true,
|
||||
"default_merge_style": "merge",
|
||||
"avatar_url": "",
|
||||
"internal": false,
|
||||
"mirror_interval": "",
|
||||
"mirror_updated": "0001-01-01T00:00:00Z",
|
||||
"repo_transfer": null
|
||||
}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v1/repos/test-argocd/pr-test/branches/main":
|
||||
_, err := io.WriteString(w, `{
|
||||
"name": "main",
|
||||
"commit": {
|
||||
"id": "72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"message": "initial commit\n",
|
||||
"url": "https://gitea.com/test-argocd/pr-test/commit/72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"author": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"committer": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "gpg.error.no_gpg_keys_found",
|
||||
"signature": "-----BEGIN PGP SIGNATURE-----\n\niQEzBAABCAAdFiEEXYAkwEBRpXzXgHFWlgCr7m50zBMFAmJMiqUACgkQlgCr7m50\nzBPSmQgAiVVEIxC42tuks4iGFNURrtYvypZAEIc+hJgt2kBpmdCrAphYPeAj+Wtr\n9KT7dDscCZIba2wx39HEXO2S7wNCXESvAzrA8rdfbXjR4L2miZ1urfBkEoqK5i/F\noblWGuAyjurX4KPa2ARROd0H4AXxt6gNAXaFPgZO+xXCyNKZfad/lkEP1AiPRknD\nvTTMbEkIzFHK9iVwZ9DORGpfF1wnLzxWmMfhYatZnBgFNnoeJNtFhCJo05rHBgqc\nqVZWXt1iF7nysBoXSzyx1ZAsmBr/Qerkuj0nonh0aPVa6NKJsdmeJyPX4zXXoi6E\ne/jpxX2UQJkpFezg3IjUpvE5FvIiYg==\n=3Af2\n-----END PGP SIGNATURE-----\n",
|
||||
"signer": null,
|
||||
"payload": "tree 64d47c7fc6e31dcf00654223ec4ab749dd0a464e\nauthor Dan Molik \u003cdan@danmolik.com\u003e 1649183391 -0400\ncommitter Dan Molik \u003cdan@danmolik.com\u003e 1649183391 -0400\n\ninitial commit\n"
|
||||
},
|
||||
"timestamp": "2022-04-05T14:29:51-04:00",
|
||||
"added": null,
|
||||
"removed": null,
|
||||
"modified": null
|
||||
},
|
||||
"protected": false,
|
||||
"required_approvals": 0,
|
||||
"enable_status_check": false,
|
||||
"status_check_contexts": [],
|
||||
"user_can_push": false,
|
||||
"user_can_merge": false,
|
||||
"effective_branch_protection_name": ""
|
||||
}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v1/repos/test-argocd/pr-test/branches?limit=0&page=1":
|
||||
_, err := io.WriteString(w, `[{
|
||||
"name": "main",
|
||||
"commit": {
|
||||
"id": "72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"message": "initial commit\n",
|
||||
"url": "https://gitea.com/test-argocd/pr-test/commit/72687815ccba81ef014a96201cc2e846a68789d8",
|
||||
"author": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"committer": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "gpg.error.no_gpg_keys_found",
|
||||
"signature": "-----BEGIN PGP SIGNATURE-----\n\niQEzBAABCAAdFiEEXYAkwEBRpXzXgHFWlgCr7m50zBMFAmJMiqUACgkQlgCr7m50\nzBPSmQgAiVVEIxC42tuks4iGFNURrtYvypZAEIc+hJgt2kBpmdCrAphYPeAj+Wtr\n9KT7dDscCZIba2wx39HEXO2S7wNCXESvAzrA8rdfbXjR4L2miZ1urfBkEoqK5i/F\noblWGuAyjurX4KPa2ARROd0H4AXxt6gNAXaFPgZO+xXCyNKZfad/lkEP1AiPRknD\nvTTMbEkIzFHK9iVwZ9DORGpfF1wnLzxWmMfhYatZnBgFNnoeJNtFhCJo05rHBgqc\nqVZWXt1iF7nysBoXSzyx1ZAsmBr/Qerkuj0nonh0aPVa6NKJsdmeJyPX4zXXoi6E\ne/jpxX2UQJkpFezg3IjUpvE5FvIiYg==\n=3Af2\n-----END PGP SIGNATURE-----\n",
|
||||
"signer": null,
|
||||
"payload": "tree 64d47c7fc6e31dcf00654223ec4ab749dd0a464e\nauthor Dan Molik \u003cdan@danmolik.com\u003e 1649183391 -0400\ncommitter Dan Molik \u003cdan@danmolik.com\u003e 1649183391 -0400\n\ninitial commit\n"
|
||||
},
|
||||
"timestamp": "2022-04-05T14:29:51-04:00",
|
||||
"added": null,
|
||||
"removed": null,
|
||||
"modified": null
|
||||
},
|
||||
"protected": false,
|
||||
"required_approvals": 0,
|
||||
"enable_status_check": false,
|
||||
"status_check_contexts": [],
|
||||
"user_can_push": false,
|
||||
"user_can_merge": false,
|
||||
"effective_branch_protection_name": ""
|
||||
}, {
|
||||
"name": "test",
|
||||
"commit": {
|
||||
"id": "7bbaf62d92ddfafd9cc8b340c619abaec32bc09f",
|
||||
"message": "add an empty file\n",
|
||||
"url": "https://gitea.com/test-argocd/pr-test/commit/7bbaf62d92ddfafd9cc8b340c619abaec32bc09f",
|
||||
"author": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"committer": {
|
||||
"name": "Dan Molik",
|
||||
"email": "dan@danmolik.com",
|
||||
"username": "graytshirt"
|
||||
},
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "gpg.error.no_gpg_keys_found",
|
||||
"signature": "-----BEGIN PGP SIGNATURE-----\n\niQEzBAABCAAdFiEEXYAkwEBRpXzXgHFWlgCr7m50zBMFAmJMiugACgkQlgCr7m50\nzBN+7wgAkCHD3KfX3Ffkqv2qPwqgHNYM1bA6Hmffzhv0YeD9jWCI3tp0JulP4iFZ\ncQ7jqx9xP9tCQMSFCaijLRHaE6Js1xrVtf0OKRkbpdlvkyrIM3sQhqyQgAsISrDG\nLzSqeoQQjglzeWESYh2Tjn1CgqQNKjI6LLepSwvF1pIeV4pJpJobaEbIfTgStdzM\nWEk8o0I+EZaYqK0C0vU9N0LK/LR/jnlaHsb4OUjvk+S7lRjZwBkrsg7P/QsqtCVd\nw5nkxDiCx1J58zKMnQ7ZinJEK9A5WYdnMYc6aBn7ARgZrblXPPBkkKUhEv3ZSPeW\nKv9i4GQy838xkVSTFkHNj1+a5o6zEA==\n=JiFw\n-----END PGP SIGNATURE-----\n",
|
||||
"signer": null,
|
||||
"payload": "tree cdddf3e1d6a8a7e6899a044d0e1bc73bf798e2f5\nparent 72687815ccba81ef014a96201cc2e846a68789d8\nauthor Dan Molik \u003cdan@danmolik.com\u003e 1649183458 -0400\ncommitter Dan Molik \u003cdan@danmolik.com\u003e 1649183458 -0400\n\nadd an empty file\n"
|
||||
},
|
||||
"timestamp": "2022-04-05T14:30:58-04:00",
|
||||
"added": null,
|
||||
"removed": null,
|
||||
"modified": null
|
||||
},
|
||||
"protected": false,
|
||||
"required_approvals": 0,
|
||||
"enable_status_check": false,
|
||||
"status_check_contexts": [],
|
||||
"user_can_push": false,
|
||||
"user_can_merge": false,
|
||||
"effective_branch_protection_name": ""
|
||||
}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v1/repos/gitea/go-sdk/contents/README.md?ref=master":
|
||||
_, err := io.WriteString(w, `{
|
||||
"name": "README.md",
|
||||
"path": "README.md",
|
||||
"sha": "3605625ef3f80dc092167b54e3f55eb0663d729f",
|
||||
"last_commit_sha": "6b6fdd91ce769bb4641084e15f76554fb841bf27",
|
||||
"type": "file",
|
||||
"size": 1673,
|
||||
"encoding": "base64",
|
||||
"content": "IyBHaXRlYSBTREsgZm9yIEdvCgpbIVtMaWNlbnNlOiBNSVRdKGh0dHBzOi8vaW1nLnNoaWVsZHMuaW8vYmFkZ2UvTGljZW5zZS1NSVQtYmx1ZS5zdmcpXShodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVCkgWyFbUmVsZWFzZV0oaHR0cHM6Ly9yYXN0ZXIuc2hpZWxkcy5pby9iYWRnZS9keW5hbWljL2pzb24uc3ZnP2xhYmVsPXJlbGVhc2UmdXJsPWh0dHBzOi8vZ2l0ZWEuY29tL2FwaS92MS9yZXBvcy9naXRlYS9nby1zZGsvcmVsZWFzZXMmcXVlcnk9JFswXS50YWdfbmFtZSldKGh0dHBzOi8vZ2l0ZWEuY29tL2dpdGVhL2dvLXNkay9yZWxlYXNlcykgWyFbQnVpbGQgU3RhdHVzXShodHRwczovL2Ryb25lLmdpdGVhLmNvbS9hcGkvYmFkZ2VzL2dpdGVhL2dvLXNkay9zdGF0dXMuc3ZnKV0oaHR0cHM6Ly9kcm9uZS5naXRlYS5jb20vZ2l0ZWEvZ28tc2RrKSBbIVtKb2luIHRoZSBjaGF0IGF0IGh0dHBzOi8vaW1nLnNoaWVsZHMuaW8vZGlzY29yZC8zMjI1Mzg5NTQxMTkxODQzODQuc3ZnXShodHRwczovL2ltZy5zaGllbGRzLmlvL2Rpc2NvcmQvMzIyNTM4OTU0MTE5MTg0Mzg0LnN2ZyldKGh0dHBzOi8vZGlzY29yZC5nZy9HaXRlYSkgWyFbXShodHRwczovL2ltYWdlcy5taWNyb2JhZGdlci5jb20vYmFkZ2VzL2ltYWdlL2dpdGVhL2dpdGVhLnN2ZyldKGh0dHA6Ly9taWNyb2JhZGdlci5jb20vaW1hZ2VzL2dpdGVhL2dpdGVhICJHZXQgeW91ciBvd24gaW1hZ2UgYmFkZ2Ugb24gbWljcm9iYWRnZXIuY29tIikgWyFbR28gUmVwb3J0IENhcmRdKGh0dHBzOi8vZ29yZXBvcnRjYXJkLmNvbS9iYWRnZS9jb2RlLmdpdGVhLmlvL3NkayldKGh0dHBzOi8vZ29yZXBvcnRjYXJkLmNvbS9yZXBvcnQvY29kZS5naXRlYS5pby9zZGspIFshW0dvRG9jXShodHRwczovL2dvZG9jLm9yZy9jb2RlLmdpdGVhLmlvL3Nkay9naXRlYT9zdGF0dXMuc3ZnKV0oaHR0cHM6Ly9nb2RvYy5vcmcvY29kZS5naXRlYS5pby9zZGsvZ2l0ZWEpCgpUaGlzIHByb2plY3QgYWN0cyBhcyBhIGNsaWVudCBTREsgaW1wbGVtZW50YXRpb24gd3JpdHRlbiBpbiBHbyB0byBpbnRlcmFjdCB3aXRoIHRoZSBHaXRlYSBBUEkgaW1wbGVtZW50YXRpb24uIEZvciBmdXJ0aGVyIGluZm9ybWF0aW9ucyB0YWtlIGEgbG9vayBhdCB0aGUgY3VycmVudCBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9nb2RvYy5vcmcvY29kZS5naXRlYS5pby9zZGsvZ2l0ZWEpLgoKTm90ZTogZnVuY3Rpb24gYXJndW1lbnRzIGFyZSBlc2NhcGVkIGJ5IHRoZSBTREsuCgojIyBVc2UgaXQKCmBgYGdvCmltcG9ydCAiY29kZS5naXRlYS5pby9zZGsvZ2l0ZWEiCmBgYAoKIyMgVmVyc2lvbiBSZXF1aXJlbWVudHMKICogZ28gPj0gMS4xMwogKiBnaXRlYSA+PSAxLjExCgojIyBDb250cmlidXRpbmcKCkZvcmsgLT4gUGF0Y2ggLT4gUHVzaCAtPiBQdWxsIFJlcXVlc3QKCiMjIEF1dGhvcnMKCiogW01haW50YWluZXJzXShodHRwczovL2dpdGh1Yi5jb20vb3Jncy9nby1naXRlYS9wZW9wbGUpCiogW0NvbnRyaWJ1dG9yc10oaHR0cHM6Ly9naXRodWIuY29tL2dvLWdpdGVhL2dvLXNkay9ncmFwaHMvY29udHJpYnV0b3JzKQoKIyMgTGljZW5zZQoKVGhpcyBwcm9qZWN0IGlzIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBbTElDRU5TRV0oTElDRU5TRSkgZmlsZSBmb3IgdGhlIGZ1bGwgbGljZW5zZSB0ZXh0Lgo=",
|
||||
"target": null,
|
||||
"url": "https://gitea.com/api/v1/repos/gitea/go-sdk/contents/README.md?ref=master",
|
||||
"html_url": "https://gitea.com/gitea/go-sdk/src/branch/master/README.md",
|
||||
"git_url": "https://gitea.com/api/v1/repos/gitea/go-sdk/git/blobs/3605625ef3f80dc092167b54e3f55eb0663d729f",
|
||||
"download_url": "https://gitea.com/gitea/go-sdk/raw/branch/master/README.md",
|
||||
"submodule_git_url": null,
|
||||
"_links": {
|
||||
"self": "https://gitea.com/api/v1/repos/gitea/go-sdk/contents/README.md?ref=master",
|
||||
"git": "https://gitea.com/api/v1/repos/gitea/go-sdk/git/blobs/3605625ef3f80dc092167b54e3f55eb0663d729f",
|
||||
"html": "https://gitea.com/gitea/go-sdk/src/branch/master/README.md"
|
||||
}
|
||||
}
|
||||
`)
|
||||
require.NoError(t, err)
|
||||
case "/api/v1/repos/gitea/go-sdk/contents/gitea?ref=master":
|
||||
_, err := io.WriteString(w, testdata.ReposGiteaGoSdkContentsGiteaResponse)
|
||||
require.NoError(t, err)
|
||||
case "/api/v1/repos/gitea/go-sdk/contents/notathing?ref=master":
|
||||
w.WriteHeader(404)
|
||||
_, err := io.WriteString(w, `{"errors":["object does not exist [id: , rel_path: notathing]"],"message":"GetContentsOrList","url":"https://gitea.com/api/swagger"}`)
|
||||
require.NoError(t, err)
|
||||
default:
|
||||
_, err := io.WriteString(w, `[]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestGiteaListRepos(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, proto, url string
|
||||
@@ -17,28 +266,28 @@ func TestGiteaListRepos(t *testing.T) {
|
||||
filters []v1alpha1.SCMProviderGeneratorFilter
|
||||
}{
|
||||
{
|
||||
name: "blank protocol",
|
||||
name: "blank protocol",
|
||||
allBranches: false,
|
||||
url: "git@gitea.com:test-argocd/pr-test.git",
|
||||
branches: []string{"main"},
|
||||
url: "git@gitea.com:test-argocd/pr-test.git",
|
||||
branches: []string{"main"},
|
||||
},
|
||||
{
|
||||
name: "ssh protocol",
|
||||
name: "ssh protocol",
|
||||
allBranches: false,
|
||||
proto: "ssh",
|
||||
url: "git@gitea.com:test-argocd/pr-test.git",
|
||||
proto: "ssh",
|
||||
url: "git@gitea.com:test-argocd/pr-test.git",
|
||||
},
|
||||
{
|
||||
name: "https protocol",
|
||||
name: "https protocol",
|
||||
allBranches: false,
|
||||
proto: "https",
|
||||
url: "https://gitea.com/test-argocd/pr-test",
|
||||
proto: "https",
|
||||
url: "https://gitea.com/test-argocd/pr-test",
|
||||
},
|
||||
{
|
||||
name: "other protocol",
|
||||
name: "other protocol",
|
||||
allBranches: false,
|
||||
proto: "other",
|
||||
hasError: true,
|
||||
proto: "other",
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
name: "all branches",
|
||||
@@ -47,15 +296,17 @@ func TestGiteaListRepos(t *testing.T) {
|
||||
branches: []string{"main"},
|
||||
},
|
||||
}
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
giteaMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGiteaProvider(context.Background(), "test-argocd", "", "https://gitea.com/", c.allBranches, false)
|
||||
provider, _ := NewGiteaProvider(context.Background(), "test-argocd", "", ts.URL, c.allBranches, false)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
assert.NotNil(t, err)
|
||||
} else {
|
||||
checkRateLimit(t, err)
|
||||
assert.Nil(t, err)
|
||||
// Just check that this one project shows up. Not a great test but better thing nothing?
|
||||
repos := []*Repository{}
|
||||
@@ -77,22 +328,32 @@ func TestGiteaListRepos(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGiteaHasPath(t *testing.T) {
|
||||
host, _ := NewGiteaProvider(context.Background(), "gitea", "", "https://gitea.com/", false, false)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
giteaMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGiteaProvider(context.Background(), "gitea", "", ts.URL, false, false)
|
||||
repo := &Repository{
|
||||
Organization: "gitea",
|
||||
Repository: "go-sdk",
|
||||
Branch: "master",
|
||||
}
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "README.md")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
// directory
|
||||
ok, err = host.RepoHasPath(context.Background(), repo, "gitea")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, ok)
|
||||
t.Run("file exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "README.md")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
ok, err = host.RepoHasPath(context.Background(), repo, "notathing")
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, ok)
|
||||
t.Run("directory exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "gitea")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("does not exists", func(t *testing.T) {
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "notathing")
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, ok)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -11,27 +12,192 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
)
|
||||
|
||||
func checkRateLimit(t *testing.T, err error) {
|
||||
// Check if we've hit a rate limit, don't fail the test if so.
|
||||
if err != nil && (strings.Contains(err.Error(), "rate limit exceeded") ||
|
||||
(strings.Contains(err.Error(), "API rate limit") && strings.Contains(err.Error(), "still exceeded"))) {
|
||||
|
||||
// GitHub Actions add this environment variable to indicate branch ref you are running on
|
||||
githubRef := os.Getenv("GITHUB_REF")
|
||||
|
||||
// Only report rate limit errors as errors, when:
|
||||
// - We are running in a GitHub action
|
||||
// - AND, we are running that action on the 'master' or 'release-*' branch
|
||||
// (unfortunately, for PRs, we don't have access to GitHub secrets that would allow us to embed a token)
|
||||
failOnRateLimitErrors := os.Getenv("CI") != "" && (strings.Contains(githubRef, "/master") || strings.Contains(githubRef, "/release-"))
|
||||
|
||||
t.Logf("Got a rate limit error, consider setting $GITHUB_TOKEN to increase your GitHub API rate limit: %v\n", err)
|
||||
if failOnRateLimitErrors {
|
||||
t.FailNow()
|
||||
} else {
|
||||
t.SkipNow()
|
||||
func githubMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.RequestURI {
|
||||
case "/api/v3/orgs/argoproj/repos?per_page=100":
|
||||
_, err := io.WriteString(w, `[
|
||||
{
|
||||
"id": 1296269,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
|
||||
"name": "argo-cd",
|
||||
"full_name": "argoproj/argo-cd",
|
||||
"owner": {
|
||||
"login": "argoproj",
|
||||
"id": 1,
|
||||
"node_id": "MDQ6VXNlcjE=",
|
||||
"avatar_url": "https://github.com/images/error/argoproj_happy.gif",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/argoproj",
|
||||
"html_url": "https://github.com/argoproj",
|
||||
"followers_url": "https://api.github.com/users/argoproj/followers",
|
||||
"following_url": "https://api.github.com/users/argoproj/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/argoproj/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/argoproj/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/argoproj/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/argoproj/orgs",
|
||||
"repos_url": "https://api.github.com/users/argoproj/repos",
|
||||
"events_url": "https://api.github.com/users/argoproj/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/argoproj/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"private": false,
|
||||
"html_url": "https://github.com/argoproj/argo-cd",
|
||||
"description": "This your first repo!",
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/argoproj/argo-cd",
|
||||
"archive_url": "https://api.github.com/repos/argoproj/argo-cd/{archive_format}{/ref}",
|
||||
"assignees_url": "https://api.github.com/repos/argoproj/argo-cd/assignees{/user}",
|
||||
"blobs_url": "https://api.github.com/repos/argoproj/argo-cd/git/blobs{/sha}",
|
||||
"branches_url": "https://api.github.com/repos/argoproj/argo-cd/branches{/branch}",
|
||||
"collaborators_url": "https://api.github.com/repos/argoproj/argo-cd/collaborators{/collaborator}",
|
||||
"comments_url": "https://api.github.com/repos/argoproj/argo-cd/comments{/number}",
|
||||
"commits_url": "https://api.github.com/repos/argoproj/argo-cd/commits{/sha}",
|
||||
"compare_url": "https://api.github.com/repos/argoproj/argo-cd/compare/{base}...{head}",
|
||||
"contents_url": "https://api.github.com/repos/argoproj/argo-cd/contents/{path}",
|
||||
"contributors_url": "https://api.github.com/repos/argoproj/argo-cd/contributors",
|
||||
"deployments_url": "https://api.github.com/repos/argoproj/argo-cd/deployments",
|
||||
"downloads_url": "https://api.github.com/repos/argoproj/argo-cd/downloads",
|
||||
"events_url": "https://api.github.com/repos/argoproj/argo-cd/events",
|
||||
"forks_url": "https://api.github.com/repos/argoproj/argo-cd/forks",
|
||||
"git_commits_url": "https://api.github.com/repos/argoproj/argo-cd/git/commits{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/argoproj/argo-cd/git/refs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/argoproj/argo-cd/git/tags{/sha}",
|
||||
"git_url": "git:github.com/argoproj/argo-cd.git",
|
||||
"issue_comment_url": "https://api.github.com/repos/argoproj/argo-cd/issues/comments{/number}",
|
||||
"issue_events_url": "https://api.github.com/repos/argoproj/argo-cd/issues/events{/number}",
|
||||
"issues_url": "https://api.github.com/repos/argoproj/argo-cd/issues{/number}",
|
||||
"keys_url": "https://api.github.com/repos/argoproj/argo-cd/keys{/key_id}",
|
||||
"labels_url": "https://api.github.com/repos/argoproj/argo-cd/labels{/name}",
|
||||
"languages_url": "https://api.github.com/repos/argoproj/argo-cd/languages",
|
||||
"merges_url": "https://api.github.com/repos/argoproj/argo-cd/merges",
|
||||
"milestones_url": "https://api.github.com/repos/argoproj/argo-cd/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/argoproj/argo-cd/notifications{?since,all,participating}",
|
||||
"pulls_url": "https://api.github.com/repos/argoproj/argo-cd/pulls{/number}",
|
||||
"releases_url": "https://api.github.com/repos/argoproj/argo-cd/releases{/id}",
|
||||
"ssh_url": "git@github.com:argoproj/argo-cd.git",
|
||||
"stargazers_url": "https://api.github.com/repos/argoproj/argo-cd/stargazers",
|
||||
"statuses_url": "https://api.github.com/repos/argoproj/argo-cd/statuses/{sha}",
|
||||
"subscribers_url": "https://api.github.com/repos/argoproj/argo-cd/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/argoproj/argo-cd/subscription",
|
||||
"tags_url": "https://api.github.com/repos/argoproj/argo-cd/tags",
|
||||
"teams_url": "https://api.github.com/repos/argoproj/argo-cd/teams",
|
||||
"trees_url": "https://api.github.com/repos/argoproj/argo-cd/git/trees{/sha}",
|
||||
"clone_url": "https://github.com/argoproj/argo-cd.git",
|
||||
"mirror_url": "git:git.example.com/argoproj/argo-cd",
|
||||
"hooks_url": "https://api.github.com/repos/argoproj/argo-cd/hooks",
|
||||
"svn_url": "https://svn.github.com/argoproj/argo-cd",
|
||||
"homepage": "https://github.com",
|
||||
"language": null,
|
||||
"forks_count": 9,
|
||||
"stargazers_count": 80,
|
||||
"watchers_count": 80,
|
||||
"size": 108,
|
||||
"default_branch": "master",
|
||||
"open_issues_count": 0,
|
||||
"is_template": false,
|
||||
"topics": [
|
||||
"argoproj",
|
||||
"atom",
|
||||
"electron",
|
||||
"api"
|
||||
],
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": false,
|
||||
"has_downloads": true,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"visibility": "public",
|
||||
"pushed_at": "2011-01-26T19:06:43Z",
|
||||
"created_at": "2011-01-26T19:01:12Z",
|
||||
"updated_at": "2011-01-26T19:14:43Z",
|
||||
"permissions": {
|
||||
"admin": false,
|
||||
"push": false,
|
||||
"pull": true
|
||||
},
|
||||
"template_repository": null
|
||||
}
|
||||
]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v3/repos/argoproj/argo-cd/branches?per_page=100":
|
||||
_, err := io.WriteString(w, `[
|
||||
{
|
||||
"name": "master",
|
||||
"commit": {
|
||||
"sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc",
|
||||
"url": "https://api.github.com/repos/argoproj/argo-cd/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc"
|
||||
},
|
||||
"protected": true,
|
||||
"protection": {
|
||||
"required_status_checks": {
|
||||
"enforcement_level": "non_admins",
|
||||
"contexts": [
|
||||
"ci-test",
|
||||
"linter"
|
||||
]
|
||||
}
|
||||
},
|
||||
"protection_url": "https://api.github.com/repos/argoproj/hello-world/branches/master/protection"
|
||||
}
|
||||
]
|
||||
`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v3/repos/argoproj/argo-cd/contents/pkg?ref=master":
|
||||
_, err := io.WriteString(w, `{
|
||||
"type": "file",
|
||||
"encoding": "base64",
|
||||
"size": 5362,
|
||||
"name": "pkg/",
|
||||
"path": "pkg/",
|
||||
"content": "encoded content ...",
|
||||
"sha": "3d21ec53a331a6f037a91c368710b99387d012c1",
|
||||
"url": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
|
||||
"git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
|
||||
"html_url": "https://github.com/octokit/octokit.rb/blob/master/README.md",
|
||||
"download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/README.md",
|
||||
"_links": {
|
||||
"git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
|
||||
"self": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
|
||||
"html": "https://github.com/octokit/octokit.rb/blob/master/README.md"
|
||||
}
|
||||
}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v3/repos/argoproj/argo-cd/branches/master":
|
||||
_, err := io.WriteString(w, `{
|
||||
"name": "master",
|
||||
"commit": {
|
||||
"sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc",
|
||||
"url": "https://api.github.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc"
|
||||
},
|
||||
"protected": true,
|
||||
"protection": {
|
||||
"required_status_checks": {
|
||||
"enforcement_level": "non_admins",
|
||||
"contexts": [
|
||||
"ci-test",
|
||||
"linter"
|
||||
]
|
||||
}
|
||||
},
|
||||
"protection_url": "https://api.github.com/repos/octocat/hello-world/branches/master/protection"
|
||||
}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
default:
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,18 +232,20 @@ func TestGithubListRepos(t *testing.T) {
|
||||
name: "all branches",
|
||||
allBranches: true,
|
||||
url: "git@github.com:argoproj/argo-cd.git",
|
||||
branches: []string{"master", "release-0.11"},
|
||||
branches: []string{"master"},
|
||||
},
|
||||
}
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
githubMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGithubProvider(context.Background(), "argoproj", "", "", c.allBranches)
|
||||
provider, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, c.allBranches)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
checkRateLimit(t, err)
|
||||
assert.NoError(t, err)
|
||||
// Just check that this one project shows up. Not a great test but better thing nothing?
|
||||
repos := []*Repository{}
|
||||
@@ -99,25 +267,31 @@ func TestGithubListRepos(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGithubHasPath(t *testing.T) {
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", "", false)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
githubMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false)
|
||||
repo := &Repository{
|
||||
Organization: "argoproj",
|
||||
Repository: "argo-cd",
|
||||
Branch: "master",
|
||||
}
|
||||
ok, err := host.RepoHasPath(context.Background(), repo, "pkg/")
|
||||
checkRateLimit(t, err)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, ok)
|
||||
|
||||
ok, err = host.RepoHasPath(context.Background(), repo, "notathing/")
|
||||
checkRateLimit(t, err)
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, ok)
|
||||
}
|
||||
|
||||
func TestGithubGetBranches(t *testing.T) {
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", "", false)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
githubMockHandler(t)(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
host, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, false)
|
||||
repo := &Repository{
|
||||
Organization: "argoproj",
|
||||
Repository: "argo-cd",
|
||||
@@ -125,19 +299,26 @@ func TestGithubGetBranches(t *testing.T) {
|
||||
}
|
||||
repos, err := host.GetBranches(context.Background(), repo)
|
||||
if err != nil {
|
||||
checkRateLimit(t, err)
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Equal(t, repos[0].Branch, "master")
|
||||
}
|
||||
// Get all branches
|
||||
//Branch Doesn't exists instead of error will return no error
|
||||
repo2 := &Repository{
|
||||
Organization: "argoproj",
|
||||
Repository: "applicationset",
|
||||
Branch: "main",
|
||||
}
|
||||
_, err = host.GetBranches(context.Background(), repo2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get all branches
|
||||
host.allBranches = true
|
||||
repos, err = host.GetBranches(context.Background(), repo)
|
||||
if err != nil {
|
||||
checkRateLimit(t, err)
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
// considering master and one release branch to always exist.
|
||||
assert.Greater(t, len(repos), 1)
|
||||
// considering master branch to exist.
|
||||
assert.Equal(t, len(repos), 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package scm_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -9,6 +13,275 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
|
||||
)
|
||||
|
||||
func gitlabMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.RequestURI {
|
||||
case "/api/v4":
|
||||
fmt.Println("here1")
|
||||
case "/api/v4/groups/test-argocd-proton/projects?include_subgroups=false&per_page=100":
|
||||
fmt.Println("here")
|
||||
_, err := io.WriteString(w, `[{
|
||||
"id": 27084533,
|
||||
"description": "",
|
||||
"name": "argocd",
|
||||
"name_with_namespace": "test argocd proton / argocd",
|
||||
"path": "argocd",
|
||||
"path_with_namespace": "test-argocd-proton/argocd",
|
||||
"created_at": "2021-06-01T17:30:44.724Z",
|
||||
"default_branch": "master",
|
||||
"tag_list": [],
|
||||
"topics": [],
|
||||
"ssh_url_to_repo": "git@gitlab.com:test-argocd-proton/argocd.git",
|
||||
"http_url_to_repo": "https://gitlab.com/test-argocd-proton/argocd.git",
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd",
|
||||
"readme_url": null,
|
||||
"avatar_url": null,
|
||||
"forks_count": 0,
|
||||
"star_count": 0,
|
||||
"last_activity_at": "2021-06-04T08:19:51.656Z",
|
||||
"namespace": {
|
||||
"id": 12258515,
|
||||
"name": "test argocd proton",
|
||||
"path": "test-argocd-proton",
|
||||
"kind": "gro* Connection #0 to host gitlab.com left intact up ",
|
||||
"full_path ": "test - argocd - proton ",
|
||||
"parent_id ": null,
|
||||
"avatar_url ": null,
|
||||
"web_url ": "https: //gitlab.com/groups/test-argocd-proton"
|
||||
},
|
||||
"container_registry_image_prefix": "registry.gitlab.com/test-argocd-proton/argocd",
|
||||
"_links": {
|
||||
"self": "https://gitlab.com/api/v4/projects/27084533",
|
||||
"issues": "https://gitlab.com/api/v4/projects/27084533/issues",
|
||||
"merge_requests": "https://gitlab.com/api/v4/projects/27084533/merge_requests",
|
||||
"repo_branches": "https://gitlab.com/api/v4/projects/27084533/repository/branches",
|
||||
"labels": "https://gitlab.com/api/v4/projects/27084533/labels",
|
||||
"events": "https://gitlab.com/api/v4/projects/27084533/events",
|
||||
"members": "https://gitlab.com/api/v4/projects/27084533/members",
|
||||
"cluster_agents": "https://gitlab.com/api/v4/projects/27084533/cluster_agents"
|
||||
},
|
||||
"packages_enabled": true,
|
||||
"empty_repo": false,
|
||||
"archived": false,
|
||||
"visibility": "public",
|
||||
"resolve_outdated_diff_discussions": false,
|
||||
"container_expiration_policy": {
|
||||
"cadence": "1d",
|
||||
"enabled": false,
|
||||
"keep_n": 10,
|
||||
"older_than": "90d",
|
||||
"name_regex": ".*",
|
||||
"name_regex_keep": null,
|
||||
"next_run_at": "2021-06-02T17:30:44.740Z"
|
||||
},
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"jobs_enabled": true,
|
||||
"snippets_enabled": true,
|
||||
"container_registry_enabled": true,
|
||||
"service_desk_enabled": true,
|
||||
"can_create_merge_request_in": false,
|
||||
"issues_access_level": "enabled",
|
||||
"repository_access_level": "enabled",
|
||||
"merge_requests_access_level": "enabled",
|
||||
"forking_access_level": "enabled",
|
||||
"wiki_access_level": "enabled",
|
||||
"builds_access_level": "enabled",
|
||||
"snippets_access_level": "enabled",
|
||||
"pages_access_level": "enabled",
|
||||
"operations_access_level": "enabled",
|
||||
"analytics_access_level": "enabled",
|
||||
"container_registry_access_level": "enabled",
|
||||
"security_and_compliance_access_level": "private",
|
||||
"emails_disabled": null,
|
||||
"shared_runners_enabled": true,
|
||||
"lfs_enabled": true,
|
||||
"creator_id": 2378866,
|
||||
"import_status": "none",
|
||||
"open_issues_count": 0,
|
||||
"ci_default_git_depth": 50,
|
||||
"ci_forward_deployment_enabled": true,
|
||||
"ci_job_token_scope_enabled": false,
|
||||
"public_jobs": true,
|
||||
"build_timeout": 3600,
|
||||
"auto_cancel_pending_pipelines": "enabled",
|
||||
"ci_config_path": "",
|
||||
"shared_with_groups": [],
|
||||
"only_allow_merge_if_pipeline_succeeds": false,
|
||||
"allow_merge_on_skipped_pipeline": null,
|
||||
"restrict_user_defined_variables": false,
|
||||
"request_access_enabled": true,
|
||||
"only_allow_merge_if_all_discussions_are_resolved": false,
|
||||
"remove_source_branch_after_merge": true,
|
||||
"printing_merge_request_link_enabled": true,
|
||||
"merge_method": "merge",
|
||||
"squash_option": "default_off",
|
||||
"suggestion_commit_message": null,
|
||||
"merge_commit_template": null,
|
||||
"squash_commit_template": null,
|
||||
"auto_devops_enabled": false,
|
||||
"auto_devops_deploy_strategy": "continuous",
|
||||
"autoclose_referenced_issues": true,
|
||||
"keep_latest_artifact": true,
|
||||
"runner_token_expiration_interval": null,
|
||||
"approvals_before_merge": 0,
|
||||
"mirror": false,
|
||||
"external_authorization_classification_label": "",
|
||||
"marked_for_deletion_at": null,
|
||||
"marked_for_deletion_on": null,
|
||||
"requirements_enabled": true,
|
||||
"requirements_access_level": "enabled",
|
||||
"security_and_compliance_enabled": false,
|
||||
"compliance_frameworks": [],
|
||||
"issues_template": null,
|
||||
"merge_requests_template": null,
|
||||
"merge_pipelines_enabled": false,
|
||||
"merge_trains_enabled": false
|
||||
}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/27084533/repository/branches/master":
|
||||
fmt.Println("returning")
|
||||
_, err := io.WriteString(w, `{
|
||||
"name": "master",
|
||||
"commit": {
|
||||
"id": "8898d7999fc99dd0fd578650b58b244fc63f6b53",
|
||||
"short_id": "8898d799",
|
||||
"created_at": "2021-06-04T08:24:44.000+00:00",
|
||||
"parent_ids": ["3c9d50be1ef949ad28674e238c7e12a17b1e9706", "56482e001731640b4123cf177e51c696f08a3005"],
|
||||
"title": "Merge branch 'pipeline-1317911429' into 'master'",
|
||||
"message": "Merge branch 'pipeline-1317911429' into 'master'\n\n[testapp-ci] manifests/demo/test-app.yaml: release v1.1.0\n\nSee merge request test-argocd-proton/argocd!3",
|
||||
"author_name": "Martin Vozník",
|
||||
"author_email": "martin@voznik.cz",
|
||||
"authored_date": "2021-06-04T08:24:44.000+00:00",
|
||||
"committer_name": "Martin Vozník",
|
||||
"committer_email": "martin@voznik.cz",
|
||||
"committed_date": "2021-06-04T08:24:44.000+00:00",
|
||||
"trailers": {},
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/commit/8898d7999fc99dd0fd578650b58b244fc63f6b53"
|
||||
},
|
||||
"merged": false,
|
||||
"protected": true,
|
||||
"developers_can_push": false,
|
||||
"developers_can_merge": false,
|
||||
"can_push": false,
|
||||
"default": true,
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/tree/master"
|
||||
}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/27084533/repository/branches?per_page=100":
|
||||
_, err := io.WriteString(w, `[{
|
||||
"name": "master",
|
||||
"commit": {
|
||||
"id": "8898d7999fc99dd0fd578650b58b244fc63f6b53",
|
||||
"short_id": "8898d799",
|
||||
"created_at": "2021-06-04T08:24:44.000+00:00",
|
||||
"parent_ids": null,
|
||||
"title": "Merge branch 'pipeline-1317911429' into 'master'",
|
||||
"message": "Merge branch 'pipeline-1317911429' into 'master'",
|
||||
"author_name": "Martin Vozník",
|
||||
"author_email": "martin@voznik.cz",
|
||||
"authored_date": "2021-06-04T08:24:44.000+00:00",
|
||||
"committer_name": "Martin Vozník",
|
||||
"committer_email": "martin@voznik.cz",
|
||||
"committed_date": "2021-06-04T08:24:44.000+00:00",
|
||||
"trailers": null,
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/commit/8898d7999fc99dd0fd578650b58b244fc63f6b53"
|
||||
},
|
||||
"merged": false,
|
||||
"protected": true,
|
||||
"developers_can_push": false,
|
||||
"developers_can_merge": false,
|
||||
"can_push": false,
|
||||
"default": true,
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/tree/master"
|
||||
}, {
|
||||
"name": "pipeline-1310077506",
|
||||
"commit": {
|
||||
"id": "0f92540e5f396ba960adea4ed0aa905baf3f73d1",
|
||||
"short_id": "0f92540e",
|
||||
"created_at": "2021-06-01T18:39:59.000+00:00",
|
||||
"parent_ids": null,
|
||||
"title": "[testapp-ci] manifests/demo/test-app.yaml: release v1.0.1",
|
||||
"message": "[testapp-ci] manifests/demo/test-app.yaml: release v1.0.1",
|
||||
"author_name": "ci-test-app",
|
||||
"author_email": "mvoznik+cicd@protonmail.com",
|
||||
"authored_date": "2021-06-01T18:39:59.000+00:00",
|
||||
"committer_name": "ci-test-app",
|
||||
"committer_email": "mvoznik+cicd@protonmail.com",
|
||||
"committed_date": "2021-06-01T18:39:59.000+00:00",
|
||||
"trailers": null,
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/commit/0f92540e5f396ba960adea4ed0aa905baf3f73d1"
|
||||
},
|
||||
"merged": false,
|
||||
"protected": false,
|
||||
"developers_can_push": false,
|
||||
"developers_can_merge": false,
|
||||
"can_push": false,
|
||||
"default": false,
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd/-/tree/pipeline-1310077506"
|
||||
}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/test-argocd-proton%2Fargocd":
|
||||
fmt.Println("auct")
|
||||
_, err := io.WriteString(w, `{
|
||||
"id": 27084533,
|
||||
"description": "",
|
||||
"name": "argocd",
|
||||
"name_with_namespace": "test argocd proton / argocd",
|
||||
"path": "argocd",
|
||||
"path_with_namespace": "test-argocd-proton/argocd",
|
||||
"created_at": "2021-06-01T17:30:44.724Z",
|
||||
"default_branch": "master",
|
||||
"tag_list": [],
|
||||
"topics": [],
|
||||
"ssh_url_to_repo": "git@gitlab.com:test-argocd-proton/argocd.git",
|
||||
"http_url_to_repo": "https://gitlab.com/test-argocd-proton/argocd.git",
|
||||
"web_url": "https://gitlab.com/test-argocd-proton/argocd",
|
||||
"readme_url": null,
|
||||
"avatar_url": null,
|
||||
"forks_count": 0,
|
||||
"star_count": 0,
|
||||
"last_activity_at": "2021-06-04T08:19:51.656Z",
|
||||
"namespace": {
|
||||
"id": 12258515,
|
||||
"name": "test argocd proton",
|
||||
"path": "test-argocd-proton",
|
||||
"kind": "group",
|
||||
"full_path": "test-argocd-proton",
|
||||
"parent_id": null,
|
||||
"avatar_url": null,
|
||||
"web_url": "https://gitlab.com/groups/test-argocd-proton"
|
||||
}
|
||||
}`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/27084533/repository/tree?path=argocd&ref=master":
|
||||
_, err := io.WriteString(w, `[{"id":"ca14f2a3718159c74572a5325fb4bfb0662a2d3e","name":"ingress.yaml","type":"blob","path":"argocd/ingress.yaml","mode":"100644"},{"id":"de2a53a73b1550b3e0f4d37ea0a6d878bf9c5096","name":"install.yaml","type":"blob","path":"argocd/install.yaml","mode":"100644"}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
case "/api/v4/projects/27084533/repository/tree?path=.&ref=master":
|
||||
_, err := io.WriteString(w, `[{"id":"f2bf99fa8f7a27df9c43d2dffc8c8cd747f3181a","name":"argocd","type":"tree","path":"argocd","mode":"040000"},{"id":"68a3125232e01c1583a6a6299534ce10c5e7dd83","name":"manifests","type":"tree","path":"manifests","mode":"040000"}]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
default:
|
||||
_, err := io.WriteString(w, `[]`)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestGitlabListRepos(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, proto, url string
|
||||
@@ -40,18 +313,19 @@ func TestGitlabListRepos(t *testing.T) {
|
||||
name: "all branches",
|
||||
allBranches: true,
|
||||
url: "git@gitlab.com:test-argocd-proton/argocd.git",
|
||||
branches: []string{"master", "pipeline-1310077506"},
|
||||
branches: []string{"master"},
|
||||
},
|
||||
}
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gitlabMockHandler(t)(w, r)
|
||||
}))
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
provider, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", "", c.allBranches, c.includeSubgroups)
|
||||
provider, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups)
|
||||
rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto)
|
||||
if c.hasError {
|
||||
assert.NotNil(t, err)
|
||||
} else {
|
||||
checkRateLimit(t, err)
|
||||
assert.Nil(t, err)
|
||||
// Just check that this one project shows up. Not a great test but better thing nothing?
|
||||
repos := []*Repository{}
|
||||
@@ -73,7 +347,10 @@ func TestGitlabListRepos(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGitlabHasPath(t *testing.T) {
|
||||
host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", "", false, true)
|
||||
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)
|
||||
repo := &Repository{
|
||||
Organization: "test-argocd-proton",
|
||||
Repository: "argocd",
|
||||
|
||||
6
applicationset/services/scm_provider/testdata/data.go
vendored
Normal file
6
applicationset/services/scm_provider/testdata/data.go
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package testdata
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed repos_gitea_go-sdk_contents_gitea.json
|
||||
var ReposGiteaGoSdkContentsGiteaResponse string
|
||||
2039
applicationset/services/scm_provider/testdata/repos_gitea_go-sdk_contents_gitea.json
vendored
Normal file
2039
applicationset/services/scm_provider/testdata/repos_gitea_go-sdk_contents_gitea.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -36,11 +36,12 @@ import (
|
||||
// NewLoginCommand returns a new instance of `argocd login` command
|
||||
func NewLoginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
var (
|
||||
ctxName string
|
||||
username string
|
||||
password string
|
||||
sso bool
|
||||
ssoPort int
|
||||
ctxName string
|
||||
username string
|
||||
password string
|
||||
sso bool
|
||||
ssoPort int
|
||||
skipTestTLS bool
|
||||
)
|
||||
var command = &cobra.Command{
|
||||
Use: "login SERVER",
|
||||
@@ -68,22 +69,25 @@ argocd login cd.argoproj.io --core`,
|
||||
server = "kubernetes"
|
||||
} else {
|
||||
server = args[0]
|
||||
dialTime := 30 * time.Second
|
||||
tlsTestResult, err := grpc_util.TestTLS(server, dialTime)
|
||||
errors.CheckError(err)
|
||||
if !tlsTestResult.TLS {
|
||||
if !globalClientOpts.PlainText {
|
||||
if !cli.AskToProceed("WARNING: server is not configured with TLS. Proceed (y/n)? ") {
|
||||
os.Exit(1)
|
||||
|
||||
if !skipTestTLS {
|
||||
dialTime := 30 * time.Second
|
||||
tlsTestResult, err := grpc_util.TestTLS(server, dialTime)
|
||||
errors.CheckError(err)
|
||||
if !tlsTestResult.TLS {
|
||||
if !globalClientOpts.PlainText {
|
||||
if !cli.AskToProceed("WARNING: server is not configured with TLS. Proceed (y/n)? ") {
|
||||
os.Exit(1)
|
||||
}
|
||||
globalClientOpts.PlainText = true
|
||||
}
|
||||
globalClientOpts.PlainText = true
|
||||
}
|
||||
} else if tlsTestResult.InsecureErr != nil {
|
||||
if !globalClientOpts.Insecure {
|
||||
if !cli.AskToProceed(fmt.Sprintf("WARNING: server certificate had error: %s. Proceed insecurely (y/n)? ", tlsTestResult.InsecureErr)) {
|
||||
os.Exit(1)
|
||||
} else if tlsTestResult.InsecureErr != nil {
|
||||
if !globalClientOpts.Insecure {
|
||||
if !cli.AskToProceed(fmt.Sprintf("WARNING: server certificate had error: %s. Proceed insecurely (y/n)? ", tlsTestResult.InsecureErr)) {
|
||||
os.Exit(1)
|
||||
}
|
||||
globalClientOpts.Insecure = true
|
||||
}
|
||||
globalClientOpts.Insecure = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,6 +179,8 @@ argocd login cd.argoproj.io --core`,
|
||||
command.Flags().StringVar(&password, "password", "", "the password of an account to authenticate")
|
||||
command.Flags().BoolVar(&sso, "sso", false, "perform SSO login")
|
||||
command.Flags().IntVar(&ssoPort, "sso-port", DefaultSSOLocalPort, "port to run local OAuth2 login application")
|
||||
command.Flags().
|
||||
BoolVar(&skipTestTLS, "skip-test-tls", false, "Skip testing whether the server is configured with TLS (this can help when the command hangs for no apparent reason)")
|
||||
return command
|
||||
}
|
||||
|
||||
@@ -190,7 +196,13 @@ func userDisplayName(claims jwt.MapClaims) string {
|
||||
|
||||
// oauth2Login opens a browser, runs a temporary HTTP server to delegate OAuth2 login flow and
|
||||
// returns the JWT token and a refresh token (if supported)
|
||||
func oauth2Login(ctx context.Context, port int, oidcSettings *settingspkg.OIDCConfig, oauth2conf *oauth2.Config, provider *oidc.Provider) (string, string) {
|
||||
func oauth2Login(
|
||||
ctx context.Context,
|
||||
port int,
|
||||
oidcSettings *settingspkg.OIDCConfig,
|
||||
oauth2conf *oauth2.Config,
|
||||
provider *oidc.Provider,
|
||||
) (string, string) {
|
||||
oauth2conf.RedirectURL = fmt.Sprintf("http://localhost:%d/auth/callback", port)
|
||||
oidcConf, err := oidcutil.ParseConfig(provider)
|
||||
errors.CheckError(err)
|
||||
@@ -216,7 +228,10 @@ func oauth2Login(ctx context.Context, port int, oidcSettings *settingspkg.OIDCCo
|
||||
}
|
||||
|
||||
// PKCE implementation of https://tools.ietf.org/html/rfc7636
|
||||
codeVerifier, err := rand.StringFromCharset(43, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~")
|
||||
codeVerifier, err := rand.StringFromCharset(
|
||||
43,
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
|
||||
)
|
||||
errors.CheckError(err)
|
||||
codeChallengeHash := sha256.Sum256([]byte(codeVerifier))
|
||||
codeChallenge := base64.RawURLEncoding.EncodeToString(codeChallengeHash[:])
|
||||
|
||||
2
cmd/argocd/commands/testdata/config
vendored
2
cmd/argocd/commands/testdata/config
vendored
@@ -28,4 +28,4 @@ current-context: localhost:8080
|
||||
users:
|
||||
- name: argocd1.example.com:443
|
||||
- name: argocd2.example.com:443
|
||||
- name: localhost:8080
|
||||
- name: localhost:8080
|
||||
@@ -25,8 +25,6 @@ type PluginConfigSpec struct {
|
||||
Init Command `json:"init,omitempty"`
|
||||
Generate Command `json:"generate"`
|
||||
Discover Discover `json:"discover"`
|
||||
AllowConcurrency bool `json:"allowConcurrency"`
|
||||
LockRepo bool `json:"lockRepo"`
|
||||
}
|
||||
|
||||
//Discover holds find and fileName
|
||||
|
||||
@@ -11,5 +11,3 @@ spec:
|
||||
discover:
|
||||
find:
|
||||
glob: "**/*/main.jsonnet"
|
||||
allowConcurrency: false
|
||||
lockRepo: false
|
||||
@@ -12,5 +12,3 @@ spec:
|
||||
find:
|
||||
command: [sh, -c, find . -name kustomization.yaml]
|
||||
glob: "**/*/kustomization.yaml"
|
||||
allowConcurrency: true
|
||||
lockRepo: false
|
||||
@@ -12,5 +12,3 @@ spec:
|
||||
find:
|
||||
command: [sh, -c, find . -name kustomization.yaml]
|
||||
glob: "**/*/kustomization.yaml"
|
||||
allowConcurrency: true
|
||||
lockRepo: false
|
||||
@@ -494,7 +494,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
|
||||
}
|
||||
gvk := obj.GroupVersionKind()
|
||||
|
||||
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, appLabelKey, trackingMethod)
|
||||
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), appLabelKey, trackingMethod)
|
||||
|
||||
resState := v1alpha1.ResourceStatus{
|
||||
Namespace: obj.GetNamespace(),
|
||||
@@ -674,12 +674,13 @@ func NewAppStateManager(
|
||||
}
|
||||
|
||||
// isSelfReferencedObj returns whether the given obj is managed by the application
|
||||
// according to the values in the tracking annotation. It returns true when all
|
||||
// of the properties in the annotation (name, namespace, group and kind) match
|
||||
// the properties of the inspected object, or if the tracking method used does
|
||||
// not provide the required properties for matching.
|
||||
func (m *appStateManager) isSelfReferencedObj(obj *unstructured.Unstructured, appLabelKey string, trackingMethod v1alpha1.TrackingMethod) bool {
|
||||
if obj == nil {
|
||||
// according to the values of the tracking id (aka app instance value) annotation.
|
||||
// It returns true when all of the properties of the tracking id (app name, namespace,
|
||||
// group and kind) match the properties of the live object, or if the tracking method
|
||||
// used does not provide the required properties for matching.
|
||||
// Reference: https://github.com/argoproj/argo-cd/issues/8683
|
||||
func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstructured, appName, appLabelKey string, trackingMethod v1alpha1.TrackingMethod) bool {
|
||||
if live == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -689,16 +690,42 @@ func (m *appStateManager) isSelfReferencedObj(obj *unstructured.Unstructured, ap
|
||||
return true
|
||||
}
|
||||
|
||||
// In order for us to assume obj to be managed by this application, the
|
||||
// values from the annotation have to match the properties from the live
|
||||
// object.
|
||||
appInstance := m.resourceTracking.GetAppInstance(obj, appLabelKey, trackingMethod)
|
||||
if appInstance != nil {
|
||||
return obj.GetNamespace() == appInstance.Namespace &&
|
||||
obj.GetName() == appInstance.Name &&
|
||||
obj.GetObjectKind().GroupVersionKind().Group == appInstance.Group &&
|
||||
obj.GetObjectKind().GroupVersionKind().Kind == appInstance.Kind
|
||||
// config != nil is the best-case scenario for constructing an accurate
|
||||
// Tracking ID. `config` is the "desired state" (from git/helm/etc.).
|
||||
// Using the desired state is important when there is an ApiGroup upgrade.
|
||||
// When upgrading, the comparison must be made with the new tracking ID.
|
||||
// Example:
|
||||
// live resource annotation will be:
|
||||
// ingress-app:extensions/Ingress:default/some-ingress
|
||||
// when it should be:
|
||||
// ingress-app:networking.k8s.io/Ingress:default/some-ingress
|
||||
// More details in: https://github.com/argoproj/argo-cd/pull/11012
|
||||
var aiv argo.AppInstanceValue
|
||||
if config != nil {
|
||||
aiv = argo.UnstructuredToAppInstanceValue(config, appName, "")
|
||||
return isSelfReferencedObj(live, aiv)
|
||||
}
|
||||
|
||||
// If config is nil then compare the live resource with the value
|
||||
// of the annotation. In this case, in order to validate if obj is
|
||||
// managed by this application, the values from the annotation have
|
||||
// to match the properties from the live object. Cluster scoped objects
|
||||
// carry the app's destination namespace in the tracking annotation,
|
||||
// but are unique in GVK + name combination.
|
||||
appInstance := m.resourceTracking.GetAppInstance(live, appLabelKey, trackingMethod)
|
||||
if appInstance != nil {
|
||||
return isSelfReferencedObj(live, *appInstance)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isSelfReferencedObj returns true if the given Tracking ID (`aiv`) matches
|
||||
// the given object. It returns false when the ID doesn't match. This sometimes
|
||||
// happens when a tracking label or annotation gets accidentally copied to a
|
||||
// different resource.
|
||||
func isSelfReferencedObj(obj *unstructured.Unstructured, aiv argo.AppInstanceValue) bool {
|
||||
return (obj.GetNamespace() == aiv.Namespace || obj.GetNamespace() == "") &&
|
||||
obj.GetName() == aiv.Name &&
|
||||
obj.GetObjectKind().GroupVersionKind().Group == aiv.Group &&
|
||||
obj.GetObjectKind().GroupVersionKind().Kind == aiv.Kind
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -852,6 +853,19 @@ func TestIsLiveResourceManaged(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
managedWrongAPIGroup := kube.MustToUnstructured(&networkingv1.Ingress{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "networking.k8s.io/v1",
|
||||
Kind: "Ingress",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "some-ingress",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:extensions/Ingress:default/some-ingress",
|
||||
},
|
||||
},
|
||||
})
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
@@ -870,30 +884,69 @@ func TestIsLiveResourceManaged(t *testing.T) {
|
||||
})
|
||||
|
||||
manager := ctrl.appStateManager.(*appStateManager)
|
||||
appName := "guestbook"
|
||||
|
||||
// Managed resource w/ annotations
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
t.Run("will return true if trackingid matches the resource", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
configObj := managedObj.DeepCopy()
|
||||
|
||||
// Managed resource w/ label
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
t.Run("will return true if tracked with label", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
configObj := managedObjWithLabel.DeepCopy()
|
||||
|
||||
// Wrong resource name
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong resource name and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// Wrong resource group
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong resource group and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// Wrong resource kind
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong kind and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// Wrong resource namespace
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong namespace and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// Nil resource
|
||||
assert.True(t, manager.isSelfReferencedObj(nil, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel))
|
||||
})
|
||||
t.Run("will return true if live is nil", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
|
||||
t.Run("will handle upgrade in desired state APIGroup", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
config := managedWrongAPIGroup.DeepCopy()
|
||||
delete(config.GetAnnotations(), common.AnnotationKeyAppInstance)
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
sync.WithResourcesFilter(func(key kube.ResourceKey, target *unstructured.Unstructured, live *unstructured.Unstructured) bool {
|
||||
return (len(syncOp.Resources) == 0 ||
|
||||
argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) &&
|
||||
m.isSelfReferencedObj(live, appLabelKey, trackingMethod)
|
||||
m.isSelfReferencedObj(live, target, app.GetName(), appLabelKey, trackingMethod)
|
||||
}),
|
||||
sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)),
|
||||
sync.WithNamespaceCreation(syncOp.SyncOptions.HasOption("CreateNamespace=true"), func(un *unstructured.Unstructured) bool {
|
||||
|
||||
@@ -63,7 +63,7 @@ or a randomly generated password stored in a secret (Argo CD 1.9 and later).
|
||||
## How to disable admin user?
|
||||
|
||||
Add `admin.enabled: "false"` to the `argocd-cm` ConfigMap (
|
||||
see [user management](operator-manual/user-management/index.md)).
|
||||
see [user management](./operator-manual/user-management/index.md)).
|
||||
|
||||
## Argo CD cannot deploy Helm Chart based applications without internet access, how can I solve it?
|
||||
|
||||
@@ -189,7 +189,7 @@ argocd ... --insecure
|
||||
## I have configured Dex via `dex.config` in `argocd-cm`, it still says Dex is unconfigured. Why?
|
||||
|
||||
Most likely you forgot to set the `url` in `argocd-cm` to point to your ArgoCD as well. See also
|
||||
[the docs](/operator-manual/user-management/#2-configure-argo-cd-for-sso).
|
||||
[the docs](./operator-manual/user-management/index.md#2-configure-argo-cd-for-sso).
|
||||
|
||||
## Why are `SealedSecret` resources reporting a `Status`?
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/st
|
||||
This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work.
|
||||
Do one of:
|
||||
|
||||
* Follow the [instructions to configure a certificate](./operator-manual/tls) (and ensure that the client OS trusts it).
|
||||
* Follow the [instructions to configure a certificate](operator-manual/tls.md) (and ensure that the client OS trusts it).
|
||||
* Configure the client OS to trust the self signed certificate.
|
||||
* Use the --insecure flag on all Argo CD CLI operations in this guide.
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ spec:
|
||||
valueFiles:
|
||||
- values-prod.yaml
|
||||
|
||||
# Ignore locally missing valueFiles when installing Helm chart. Defaults to false
|
||||
ignoreMissingValueFiles: false
|
||||
|
||||
# Values file as block file
|
||||
values: |
|
||||
ingress:
|
||||
@@ -61,6 +64,9 @@ spec:
|
||||
hosts:
|
||||
- mydomain.example.com
|
||||
|
||||
# Skip custom resource definition installation if chart contains custom resource definitions. Defaults to false
|
||||
skipCrds: false
|
||||
|
||||
# Optional Helm version to template with. If omitted it will fall back to look at the 'apiVersion' in Chart.yaml
|
||||
# and decide which Helm binary to use automatically. This field can be either 'v2' or 'v3'.
|
||||
version: v2
|
||||
@@ -99,10 +105,12 @@ spec:
|
||||
value: bar
|
||||
# Exclude contains a glob pattern to match paths against that should be explicitly excluded from being used during
|
||||
# manifest generation. This takes precedence over the `include` field.
|
||||
exclude: string
|
||||
# To match multiple patterns, wrap the patterns in {} and separate them with commas. For example: '{config.yaml,env-use2/*}'
|
||||
exclude: 'config.yaml'
|
||||
# Include contains a glob pattern to match paths against that should be explicitly included during manifest
|
||||
# generation. If this field is set, only matching manifests will be included.
|
||||
include: string
|
||||
# To match multiple patterns, wrap the patterns in {} and separate them with commas. For example: '{*.yml,*.yaml}'
|
||||
include: '*.yaml'
|
||||
|
||||
# plugin specific config
|
||||
plugin:
|
||||
|
||||
@@ -45,7 +45,7 @@ spec:
|
||||
- path: applicationset/examples/git-generator-directory/cluster-addons/*
|
||||
template:
|
||||
metadata:
|
||||
name: '{{path[0]}}'
|
||||
name: '{{path.basename}}'
|
||||
spec:
|
||||
project: "my-project"
|
||||
source:
|
||||
@@ -55,6 +55,9 @@ spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: '{{path.basename}}'
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
(*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/git-generator-directory).*)
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ metadata:
|
||||
spec:
|
||||
generators:
|
||||
- pullRequest:
|
||||
# When using a Pull Request generator, the ApplicationSet controller polls every `requeueAfterSeconds` interval (defaulting to every 30 minutes) to detect changes.
|
||||
requeueAfterSeconds: 1800
|
||||
# See below for provider specific options.
|
||||
github:
|
||||
# ...
|
||||
@@ -47,7 +49,7 @@ spec:
|
||||
# Labels is used to filter the PRs that you want to target. (optional)
|
||||
labels:
|
||||
- preview
|
||||
requeueAfterSeconds: 1800
|
||||
requeueAfterSeconds: 1800
|
||||
template:
|
||||
# ...
|
||||
```
|
||||
@@ -83,7 +85,7 @@ spec:
|
||||
key: token
|
||||
# many gitea deployments use TLS, but many are self-hosted and self-signed certificates
|
||||
insecure: true
|
||||
requeueAfterSeconds: 1800
|
||||
requeueAfterSeconds: 1800
|
||||
template:
|
||||
# ...
|
||||
```
|
||||
@@ -139,7 +141,7 @@ If you want to access a private repository, you must also provide the credential
|
||||
## Filters
|
||||
|
||||
Filters allow selecting which pull requests to generate for. Each filter can declare one or more conditions, all of which must pass. If multiple filters are present, any can match for a repository to be included. If no filters are specified, all pull requests will be processed.
|
||||
Currently, only a subset of filters is available when comparing with SCM provider filters.
|
||||
Currently, only a subset of filters is available when comparing with [SCM provider](Generators-SCM-Provider.md) filters.
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
@@ -148,7 +150,7 @@ metadata:
|
||||
name: myapps
|
||||
spec:
|
||||
generators:
|
||||
- scmProvider:
|
||||
- pullRequest:
|
||||
# ...
|
||||
# Include any pull request ending with "argocd". (optional)
|
||||
filters:
|
||||
@@ -159,6 +161,7 @@ spec:
|
||||
|
||||
* `branchMatch`: A regexp matched against source branch names.
|
||||
|
||||
[GitHub](#github) and [GitLab](#gitlab) also support a `labels` filter.
|
||||
|
||||
## Template
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
|
||||
## GitHub
|
||||
|
||||
The GitHub mode uses the GitHub API to scan and organization in either github.com or GitHub Enterprise.
|
||||
The GitHub mode uses the GitHub API to scan an organization in either github.com or GitHub Enterprise.
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
@@ -178,6 +178,42 @@ If you want to access a private repository, you must also provide the credential
|
||||
|
||||
Available clone protocols are `ssh` and `https`.
|
||||
|
||||
## Bitbucket Cloud
|
||||
|
||||
The Bitbucket mode uses the Bitbucket API V2 to scan a workspace in bitbucket.org.
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: myapps
|
||||
spec:
|
||||
generators:
|
||||
- scmProvider:
|
||||
bitbucket:
|
||||
# The workspace id (slug).
|
||||
owner: "example-owner"
|
||||
# The user to use for basic authentication with an app password.
|
||||
user: "example-user"
|
||||
# If true, scan every branch of every repository. If false, scan only the main branch. Defaults to false.
|
||||
allBranches: true
|
||||
# Reference to a Secret containing an app password.
|
||||
appPasswordRef:
|
||||
secretName: appPassword
|
||||
key: password
|
||||
template:
|
||||
# ...
|
||||
```
|
||||
|
||||
* `owner`: The workspace ID (slug) to use when looking up repositories.
|
||||
* `user`: The user to use for authentication to the Bitbucket API V2 at bitbucket.org.
|
||||
* `allBranches`: By default (false) the template will only be evaluated for the main branch of each repo. If this is true, every branch of every repository will be passed to the filters. If using this flag, you likely want to use a `branchMatch` filter.
|
||||
* `appPasswordRef`: A `Secret` name and key containing the bitbucket app password to use for requests.
|
||||
|
||||
This SCM provider does not yet support label filtering
|
||||
|
||||
Available clone protocols are `ssh` and `https`.
|
||||
|
||||
## Filters
|
||||
|
||||
Filters allow selecting which repositories to generate for. Each filter can declare one or more conditions, all of which must pass. If multiple filters are present, any can match for a repository to be included. If no filters are specified, all repositories will be processed.
|
||||
|
||||
@@ -61,7 +61,7 @@ number of allowed concurrent kubectl fork/execs.
|
||||
* The controller uses Kubernetes watch APIs to maintain lightweight Kubernetes cluster cache. This allows to avoid querying Kubernetes during app reconciliation and significantly improve
|
||||
performance. For performance reasons controller monitors and caches only preferred the version of a resource. During reconciliation, the controller might have to convert cached resource from
|
||||
preferred version into a version of the resource stored in Git. If `kubectl convert` fails because conversion is not supported then controller falls back to Kubernetes API query which slows down
|
||||
reconciliation. In this case advice user-preferred resource version in Git.
|
||||
reconciliation. In this case, we advise you to use the preferred resource version in Git.
|
||||
|
||||
* The controller polls Git every 3m by default. You can increase this duration using `timeout.reconciliation` setting in the `argocd-cm` ConfigMap. The value of `timeout.reconciliation` is a duration string e.g `60s`, `1m`, `1h` or `1d`.
|
||||
|
||||
@@ -126,20 +126,17 @@ If the manifest generation has no side effects then requests are processed in pa
|
||||
|
||||
### Webhook and Manifest Paths Annotation
|
||||
|
||||
Argo CD aggressively caches generated manifests and uses repository commit SHA as a cache key. A new commit to the Git repository invalidates cache for all applications configured in the repository
|
||||
that again negatively affect mono repositories with multiple applications. You might use [webhooks ⧉](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/webhook.md) and `argocd.argoproj.io/manifest-generate-paths` Application
|
||||
CRD annotation to solve this problem and improve performance.
|
||||
Argo CD aggressively caches generated manifests and uses the repository commit SHA as a cache key. A new commit to the Git repository invalidates the cache for all applications configured in the repository.
|
||||
This can negatively affect repositories with multiple applications. You can use [webhooks](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/webhook.md) and the `argocd.argoproj.io/manifest-generate-paths` Application CRD annotation to solve this problem and improve performance.
|
||||
|
||||
The `argocd.argoproj.io/manifest-generate-paths` contains a semicolon-separated list of paths within the Git repository that are used during manifest generation. The webhook compares paths specified in the annotation
|
||||
with the changed files specified in the webhook payload. If non of the changed files are located in the paths then webhook don't trigger application reconciliation and re-uses previously generated manifests cache for a new commit.
|
||||
The `argocd.argoproj.io/manifest-generate-paths` annotation contains a semicolon-separated list of paths within the Git repository that are used during manifest generation. The webhook compares paths specified in the annotation with the changed files specified in the webhook payload. If no modified files match the paths specified in `argocd.argoproj.io/manifest-generate-paths`, then the webhook will not trigger application reconciliation and the existing cache will be considered valid for the new commit.
|
||||
|
||||
Installations that use a different repo for each app are **not** subject to this behavior and will likely get no benefit from using these annotations.
|
||||
Installations that use a different repository for each application are **not** subject to this behavior and will likely get no benefit from using these annotations.
|
||||
|
||||
!!! note
|
||||
Application manifest paths annotation support depends on the git provider used for the Application. It is currently only supported for GitHub, GitLab, and Gogs based repos
|
||||
I'm using `.Second()` modifier to avoid distracting users who already rely on `--app-resync` flag.
|
||||
Application manifest paths annotation support depends on the git provider used for the Application. It is currently only supported for GitHub, GitLab, and Gogs based repos.
|
||||
|
||||
* **Relative path** The annotation might contains relative path. In this case the path is considered relative to the path specified in the application source:
|
||||
* **Relative path** The annotation might contain a relative path. In this case the path is considered relative to the path specified in the application source:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
@@ -157,7 +154,8 @@ spec:
|
||||
path: guestbook
|
||||
# ...
|
||||
```
|
||||
* **Absolute path** The annotation value might be an absolute path started from '/'. In this case path is considered as an absolute path within the Git repository:
|
||||
|
||||
* **Absolute path** The annotation value might be an absolute path starting with '/'. In this case path is considered as an absolute path within the Git repository:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
|
||||
@@ -9,7 +9,7 @@ Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoin
|
||||
|--------|:----:|-------------|
|
||||
| `argocd_app_info` | gauge | Information about Applications. It contains labels such as `sync_status` and `health_status` that reflect the application state in ArgoCD. |
|
||||
| `argocd_app_k8s_request_total` | counter | Number of kubernetes requests executed during application reconciliation |
|
||||
| `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section bellow about how to enable it. |
|
||||
| `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. |
|
||||
| `argocd_app_reconcile` | histogram | Application reconciliation performance. |
|
||||
| `argocd_app_sync_total` | counter | Counter for application sync history |
|
||||
| `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. |
|
||||
@@ -41,7 +41,7 @@ Some examples are:
|
||||
As the Application labels are specific to each company, this feature is disabled by default. To enable it, add the
|
||||
`--metrics-application-labels` flag to the ArgoCD application controller.
|
||||
|
||||
The example bellow will expose the ArgoCD Application labels `team-name` and `business-unit` to Prometheus:
|
||||
The example below will expose the ArgoCD Application labels `team-name` and `business-unit` to Prometheus:
|
||||
|
||||
containers:
|
||||
- command:
|
||||
|
||||
@@ -64,3 +64,23 @@ spec:
|
||||
# anywhere by Argo CD. It can be prematurely revoked by removing the entry from this list.
|
||||
jwtTokens:
|
||||
- iat: 1535390316
|
||||
|
||||
# Sync windows restrict when Applications may be synced. https://argo-cd.readthedocs.io/en/stable/user-guide/sync_windows/
|
||||
syncWindows:
|
||||
- kind: allow
|
||||
schedule: '10 1 * * *'
|
||||
duration: 1h
|
||||
applications:
|
||||
- '*-prod'
|
||||
manualSync: true
|
||||
- kind: deny
|
||||
schedule: '0 22 * * *'
|
||||
duration: 1h
|
||||
namespaces:
|
||||
- default
|
||||
- kind: allow
|
||||
schedule: '0 23 * * *'
|
||||
duration: 1h
|
||||
clusters:
|
||||
- in-cluster
|
||||
- cluster1
|
||||
|
||||
@@ -45,7 +45,7 @@ subresources of an application.
|
||||
#### The `action` action
|
||||
|
||||
The `action` action corresponds to either built-in resource customizations defined
|
||||
[in the Argo CD repository](https://github.com/argoproj/argo-cd/search?q=filename%3Aaction.lua+path%3Aresource_customizations),
|
||||
[in the Argo CD repository](https://github.com/argoproj/argo-cd/tree/master/resource_customizations),
|
||||
or to [custom resource actions](resource_actions.md#custom-resource-actions) defined by you.
|
||||
The `action` path is of the form `action/<api-group>/<Kind>/<action-name>`. For
|
||||
example, a resource customization path
|
||||
@@ -68,6 +68,10 @@ configures a custom role, named `org-admin`. The role is assigned to any user wh
|
||||
`your-github-org:your-team` group. All other users get the default policy of `role:readonly`,
|
||||
which cannot modify Argo CD settings.
|
||||
|
||||
!!! warning
|
||||
All authenticated users get _at least_ the permissions granted by the default policy. This access cannot be blocked
|
||||
by a `deny` rule. Instead, restrict the default policy and then grant permissions to individual roles as needed.
|
||||
|
||||
*ArgoCD ConfigMap `argocd-rbac-cm` Example:*
|
||||
|
||||
```yaml
|
||||
@@ -107,7 +111,7 @@ p, role:staging-db-admins, projects, get, staging-db-admins, allow
|
||||
g, db-admins, role:staging-db-admins
|
||||
```
|
||||
|
||||
This example defines a *role* called `staging-db-admins` with *eight permissions* that allow that role to perform the *actions* (`create`/`delete`/`get`/`override`/`sync`/`update` applications, `get` logs, `create` exec and `get` appprojects) against `*` (all) objects in the `staging-db-admins` Argo CD AppProject.
|
||||
This example defines a *role* called `staging-db-admins` with *nine permissions* that allow that role to perform the *actions* (`create`/`delete`/`get`/`override`/`sync`/`update` applications, `get` logs, `create` exec and `get` appprojects) against `*` (all) objects in the `staging-db-admins` Argo CD AppProject.
|
||||
|
||||
## Anonymous Access
|
||||
|
||||
|
||||
@@ -107,20 +107,26 @@ p, role:org-admin, *, create, my-proj/*, allow
|
||||
New:
|
||||
|
||||
```csv
|
||||
p, role: org-admin, clusters, create, my-proj/*, allow
|
||||
p, role: org-admin, projects, create, my-proj/*, allow
|
||||
p, role: org-admin, applications, create, my-proj/*, allow
|
||||
p, role: org-admin, repositories, create, my-proj/*, allow
|
||||
p, role: org-admin, certificates, create, my-proj/*, allow
|
||||
p, role: org-admin, accounts, create, my-proj/*, allow
|
||||
p, role: org-admin, gpgkeys, create, my-proj/*, allow
|
||||
p, role:org-admin, clusters, create, my-proj/*, allow
|
||||
p, role:org-admin, projects, create, my-proj/*, allow
|
||||
p, role:org-admin, applications, create, my-proj/*, allow
|
||||
p, role:org-admin, repositories, create, my-proj/*, allow
|
||||
p, role:org-admin, certificates, create, my-proj/*, allow
|
||||
p, role:org-admin, accounts, create, my-proj/*, allow
|
||||
p, role:org-admin, gpgkeys, create, my-proj/*, allow
|
||||
```
|
||||
|
||||
## Enable logs RBAC enforcement
|
||||
|
||||
2.4 introduced `logs` as a new RBAC resource. In 2.3, users with `applications, get` access automatically get logs
|
||||
access. In 2.5, you will have to explicitly grant `logs, get` access. Logs RBAC enforcement can be enabled with a flag
|
||||
in 2.4. We recommend enabling the flag now for an easier upgrade experience in 2.5.
|
||||
access. <del>In 2.5, you will have to explicitly grant `logs, get` access. Logs RBAC enforcement can be enabled with a flag
|
||||
in 2.4. We recommend enabling the flag now for an easier upgrade experience in 2.5.</del>
|
||||
|
||||
!!! important
|
||||
Logs RBAC enforcement **will not** be enabled by default in 2.5. This decision
|
||||
[was made](https://github.com/argoproj/argo-cd/issues/10551#issuecomment-1242303457) to avoid breaking logs access
|
||||
under [Project Roles](../../user-guide/projects.md#project-roles), which do not provide a mechanism to grant `logs`
|
||||
resource access.
|
||||
|
||||
To enabled logs RBAC enforcement, add this to your argocd-cm ConfigMap:
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/<v
|
||||
|
||||
<hr/>
|
||||
|
||||
* [v2.4 to v2.5](./2.4-2.5.md)
|
||||
* [v2.3 to v2.4](./2.3-2.4.md)
|
||||
* [v2.2 to v2.3](./2.2-2.3.md)
|
||||
* [v2.1 to v2.2](./2.1-2.2.md)
|
||||
|
||||
@@ -231,7 +231,7 @@ data:
|
||||
|
||||
### Requesting additional ID token claims
|
||||
|
||||
By default Dex only retrieves the profile and email scopes. In order to retrieve more more claims you
|
||||
By default Dex only retrieves the profile and email scopes. In order to retrieve more claims you
|
||||
can add them under the `scopes` entry in the Dex configuration. To enable group claims through Dex,
|
||||
`insecureEnableGroups` also needs to enabled. Group information is currently only refreshed at authentication
|
||||
time and support to refresh group information more dynamically can be tracked here: [dexidp/dex#1065](https://github.com/dexidp/dex/issues/1065).
|
||||
|
||||
@@ -168,7 +168,6 @@ spec:
|
||||
check:
|
||||
- command: [-f ./main.ts]
|
||||
glob: "main.ts"
|
||||
allowConcurrency: true # enables generating multiple manifests in parallel.
|
||||
```
|
||||
|
||||
#### Config Management Plugin API Server (cmp-server)
|
||||
@@ -320,6 +319,5 @@ spec:
|
||||
check:
|
||||
- command: [-f ./main.ts]
|
||||
glob: "main.ts"
|
||||
allowConcurrency: true # enables generating multiple manifests in parallel.
|
||||
```
|
||||
2. Something magically patches the relevant manifest to add the sidecar.
|
||||
|
||||
@@ -29,6 +29,7 @@ argocd login cd.argoproj.io --core
|
||||
-h, --help help for login
|
||||
--name string name to use for the context
|
||||
--password string the password of an account to authenticate
|
||||
--skip-test-tls Skip testing whether the server is configured with TLS (this can help when the command hangs for no apparent reason)
|
||||
--sso perform SSO login
|
||||
--sso-port int port to run local OAuth2 login application (default 8085)
|
||||
--username string the username of an account to authenticate
|
||||
|
||||
@@ -81,7 +81,7 @@ data:
|
||||
- '.webhooks[]?.clientConfig.caBundle'
|
||||
```
|
||||
|
||||
Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example bellow shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources.
|
||||
Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example below shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources.
|
||||
|
||||
```yaml
|
||||
data:
|
||||
@@ -90,7 +90,7 @@ data:
|
||||
- kube-controller-manager
|
||||
```
|
||||
|
||||
It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example bellow:
|
||||
It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example below:
|
||||
|
||||
```yaml
|
||||
data:
|
||||
|
||||
129
docs/user-guide/directory.md
Normal file
129
docs/user-guide/directory.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Directory
|
||||
|
||||
A directory-type application loads plain manifest files from `.yml`, `.yaml`, and `.json` files. A directory-type
|
||||
application may be created from the UI, CLI, or declaratively. This is the declarative syntax:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: guestbook
|
||||
spec:
|
||||
destination:
|
||||
namespace: default
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: guestbook
|
||||
repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||
targetRevision: HEAD
|
||||
```
|
||||
|
||||
It's unnecessary to explicitly add the `spec.source.directory` field except to add additional configuration options.
|
||||
Argo CD will automatically detect that the source repository/path contains plain manifest files.
|
||||
|
||||
## Enabling Recursive Resource Detection
|
||||
|
||||
By default, directory applications will only include the files from the root of the configured repository/path.
|
||||
|
||||
To enable recursive resource detection, set the `recurse` option.
|
||||
|
||||
```bash
|
||||
argocd app set guestbook --directory-recurse
|
||||
```
|
||||
|
||||
To do the same thing declaratively, use this syntax:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
spec:
|
||||
source:
|
||||
directory:
|
||||
recurse: true
|
||||
```
|
||||
|
||||
## Including/Excluding Files
|
||||
|
||||
### Including Only Certain Files
|
||||
|
||||
To include only certain files/directories in a directory application, set the `include` option. The value is a glob
|
||||
pattern.
|
||||
|
||||
For example, if you want to include only `.yaml` files, you can use this pattern:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-include "*.yaml"
|
||||
```
|
||||
|
||||
!!! note
|
||||
It is important to quote `*.yaml` so that the shell does not expand the pattern before sending it to Argo CD.
|
||||
|
||||
It is also possible to include multiple patterns. Wrap the patterns with `{}` and separate them with commas. To include
|
||||
`.yml` and `.yaml` files, use this pattern:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-include "{*.yml,*.yaml}"
|
||||
```
|
||||
|
||||
To include only a certain directory, use a pattern like this:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-include "some-directory/*"
|
||||
```
|
||||
|
||||
To accomplish the same thing declaratively, use this syntax:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
spec:
|
||||
source:
|
||||
directory:
|
||||
include: 'some-directory/*'
|
||||
```
|
||||
|
||||
### Excluding Certain Files
|
||||
|
||||
It is possible to exclude files matching a pattern from directory applications. For example, in a repository containing
|
||||
some manifests and also a non-manifest YAML file, you could exclude the config file like this:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-exclude "config.yaml"
|
||||
```
|
||||
|
||||
It is possible to exclude more than one pattern. For example, a config file and an irrelevant directory:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-exclude "{config.yaml,env-use2/*}"
|
||||
```
|
||||
|
||||
If both `include` and `exclude` are specified, then the Application will include all files which match the `include`
|
||||
pattern and do not match the `exclude` pattern. For example, consider this source repository:
|
||||
|
||||
```
|
||||
config.json
|
||||
deployment.yaml
|
||||
env-use2/
|
||||
configmap.yaml
|
||||
env-usw2/
|
||||
configmap.yaml
|
||||
```
|
||||
|
||||
To exclude `config.json` and the `env-usw2` directory, you could use this combination of patterns:
|
||||
|
||||
```shell
|
||||
argocd app set guestbook --directory-include "*.yaml" --directory-exclude "{config.json,env-usw2/*}"
|
||||
```
|
||||
|
||||
This would be the declarative syntax:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
spec:
|
||||
source:
|
||||
directory:
|
||||
exclude: '{config.json,env-usw2/*}'
|
||||
include: '*.yaml'
|
||||
```
|
||||
@@ -84,7 +84,7 @@ argocd app set <appName> --kustomize-version v3.5.4
|
||||
|
||||
## Build Environment
|
||||
|
||||
Kustomize does not support parameters and therefore cannot support the standard [build environment](build-environment.md).
|
||||
Kustomize apps have access to the [standard build environment](build-environment.md) which can be used in combination with a [config managment plugin](config-management-plugins.md) to alter the rendered manifests.
|
||||
|
||||
## Kustomizing Helm charts
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Sync Options
|
||||
|
||||
ArgoCD allows users to customize some aspects of how it syncs the desired state in the target cluster. Some Sync Options can defined as annotations in a specific resource. Most of the Sync Options are configured in the Application resource `spec.syncPolicy.syncOptions` attribute.
|
||||
Argo CD allows users to customize some aspects of how it syncs the desired state in the target cluster. Some Sync Options can defined as annotations in a specific resource. Most of the Sync Options are configured in the Application resource `spec.syncPolicy.syncOptions` attribute. Multiple Sync Options which are configured with the `argocd.argoproj.io/sync-options` annotation can be concatenated with a `,` in the annotation value; white spaces will be trimmed.
|
||||
|
||||
Below you can find details about each available Sync Option:
|
||||
|
||||
@@ -40,8 +40,8 @@ metadata:
|
||||
argocd.argoproj.io/sync-options: Validate=false
|
||||
```
|
||||
|
||||
If you want to exclude a whole class of objects globally, consider setting `resource.customizations` in [system level configuration](../user-guide/diffing.md#system-level-configuration).
|
||||
|
||||
If you want to exclude a whole class of objects globally, consider setting `resource.customizations` in [system level configuration](../user-guide/diffing.md#system-level-configuration).
|
||||
|
||||
## Skip Dry Run for new custom resources types
|
||||
|
||||
>v1.6
|
||||
@@ -64,9 +64,9 @@ The dry run will still be executed if the CRD is already present in the cluster.
|
||||
|
||||
## Selective Sync
|
||||
|
||||
Currently when syncing using auto sync ArgoCD applies every object in the application.
|
||||
Currently when syncing using auto sync Argo CD applies every object in the application.
|
||||
For applications containing thousands of objects this takes quite a long time and puts undue pressure on the api server.
|
||||
Turning on selective sync option which will sync only out-of-sync resources.
|
||||
Turning on selective sync option which will sync only out-of-sync resources.
|
||||
|
||||
You can add this option by following ways
|
||||
|
||||
@@ -81,7 +81,7 @@ spec:
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- ApplyOutOfSyncOnly=true
|
||||
```
|
||||
```
|
||||
|
||||
2) Set sync option via argocd cli
|
||||
|
||||
@@ -108,8 +108,8 @@ spec:
|
||||
|
||||
## Prune Last
|
||||
|
||||
This feature is to allow the ability for resource pruning to happen as a final, implicit wave of a sync operation,
|
||||
after the other resources have been deployed and become healthy, and after all other waves completed successfully.
|
||||
This feature is to allow the ability for resource pruning to happen as a final, implicit wave of a sync operation,
|
||||
after the other resources have been deployed and become healthy, and after all other waves completed successfully.
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
@@ -146,6 +146,10 @@ spec:
|
||||
|
||||
If the `Replace=true` sync option is set the ArgoCD will use `kubectl replace` or `kubectl create` command to apply changes.
|
||||
|
||||
!!! warning
|
||||
During the sync process, the resources will be synchronized using the 'kubectl replace/create' command.
|
||||
This sync option has the potential to be destructive and might lead to resources having to be recreated, which could cause an outage for your application.
|
||||
|
||||
This can also be configured at individual resource level.
|
||||
```yaml
|
||||
metadata:
|
||||
@@ -168,7 +172,7 @@ spec:
|
||||
|
||||
## Respect ignore difference configs
|
||||
|
||||
This sync option is used to enable ArgoCD to consider the configurations made in the `spec.ignoreDifferences` attribute also during the sync stage. By default, ArgoCD uses the `ignoreDifferences` config just for computing the diff between the live and desired state which defines if the application is synced or not. However during the sync stage, the desired state is applied as-is. The patch is calculated using a 3-way-merge between the live state the desired state and the `last-applied-configuration` annotation. This sometimes leads to an undesired results. This behavior can be changed by setting the `RespectIgnoreDifferences=true` sync option like in the example bellow:
|
||||
This sync option is used to enable Argo CD to consider the configurations made in the `spec.ignoreDifferences` attribute also during the sync stage. By default, Argo CD uses the `ignoreDifferences` config just for computing the diff between the live and desired state which defines if the application is synced or not. However during the sync stage, the desired state is applied as-is. The patch is calculated using a 3-way-merge between the live state the desired state and the `last-applied-configuration` annotation. This sometimes leads to an undesired results. This behavior can be changed by setting the `RespectIgnoreDifferences=true` sync option like in the example below:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
@@ -194,10 +198,16 @@ The example above shows how an ArgoCD Application can be configured so it will i
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
namespace: test
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: some-namespace
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
The example above shows how an Argo CD Application can be configured so it will create namespaces for the Application resources if the namespaces don't exist already. Without this either declared in the Application manifest or passed in the cli via `--sync-option CreateNamespace=true`, the Application will fail to sync if the resources' namespaces do not exist.
|
||||
|
||||
The example above shows how an Argo CD Application can be configured so it will create the namespace specified in `spec.destination.namespace` if it doesn't exist already. Without this either declared in the Application manifest or passed in the CLI via `--sync-option CreateNamespace=true`, the Application will fail to sync if the namespace doesn't exist.
|
||||
|
||||
Note that the namespace to be created must be informed in the `spec.destination.namespace` field of the Application resource. The `metadata.namespace` field in the Application's child manifests must match this value, or can be omitted, so resources are created in the proper destination.
|
||||
|
||||
@@ -20,6 +20,8 @@ For Helm, all versions are [Semantic Versions](https://semver.org/). As a result
|
||||
| Track minor releases (e.g. in QA) | Use a range | `1.*` or `>=1.0.0 <2.0.0` |
|
||||
| Use the latest (e.g. in local development) | Use star range | `*` or `>=0.0.0` |
|
||||
|
||||
**Note for OCI Helm repositories**: the only available strategy is "Pin to a version".
|
||||
|
||||
[Read about version ranges](https://www.telerik.com/blogs/the-mystical-magical-semver-ranges-used-by-npm-bower)
|
||||
|
||||
## Git
|
||||
|
||||
2
go.mod
2
go.mod
@@ -9,7 +9,7 @@ require (
|
||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible
|
||||
github.com/alicebob/miniredis/v2 v2.14.2
|
||||
github.com/argoproj/gitops-engine v0.7.1
|
||||
github.com/argoproj/gitops-engine v0.7.3
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
|
||||
github.com/aws/aws-sdk-go v1.38.49
|
||||
|
||||
4
go.sum
4
go.sum
@@ -146,8 +146,8 @@ github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc=
|
||||
github.com/argoproj/gitops-engine v0.7.1 h1:aqRcIyW+Fu2wGplPOwGjABTESzQs3VBvl9A4aj5JV1c=
|
||||
github.com/argoproj/gitops-engine v0.7.1/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
|
||||
github.com/argoproj/gitops-engine v0.7.3 h1:0ZlRTReAJG5Y1PviQ8ZIJq/+VowxWe2uFwoXqYcbtXU=
|
||||
github.com/argoproj/gitops-engine v0.7.3/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320 h1:XDjtTfccs4rSOT1n+i1zV9RpxQdKky1b4YBic16E0qY=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320/go.mod h1:R3zlopt+/juYlebQc9Jarn9vBQ2xZruWOWjUNkfGY9M=
|
||||
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
|
||||
|
||||
95
hack/generate-release-notes.sh
Executable file
95
hack/generate-release-notes.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$1" == "" ] || [ "$2" == "" ] || [ "$3" == "" ]; then
|
||||
cat <<-EOM
|
||||
USAGE:
|
||||
|
||||
generate-release-notes.sh NEW_REF OLD_REF NEW_VERSION
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
# For releasing a new minor version:
|
||||
generate-release-notes.sh release-2.5 release-2.4 v2.5.0-rc1 > /tmp/release.md
|
||||
|
||||
# For a patch release:
|
||||
generate-release-notes.sh release-2.4 v2.4.13 v2.4.14 > /tmp/release.md
|
||||
EOM
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function to_list_items() {
|
||||
sed 's/^/- /'
|
||||
}
|
||||
|
||||
function strip_last_word() {
|
||||
sed 's/ [^ ]*$//'
|
||||
}
|
||||
|
||||
function nonempty_line_count() {
|
||||
sed '/^\s*$/d' | wc -l | tr -d ' \n'
|
||||
}
|
||||
|
||||
function only_last_word() {
|
||||
awk 'NF>1{print $NF}'
|
||||
}
|
||||
|
||||
new_ref=$1
|
||||
old_ref=$2
|
||||
version=$3
|
||||
|
||||
cat <<-EOM
|
||||
## Quick Start
|
||||
|
||||
### Non-HA:
|
||||
|
||||
\`\`\`shell
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/$version/manifests/install.yaml
|
||||
\`\`\`
|
||||
|
||||
### HA:
|
||||
|
||||
\`\`\`shell
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/$version/manifests/ha/install.yaml
|
||||
\`\`\`
|
||||
|
||||
## Upgrading
|
||||
|
||||
If upgrading from a different minor version, be sure to read the [upgrading](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) documentation.
|
||||
|
||||
EOM
|
||||
|
||||
# Adapted from https://stackoverflow.com/a/67029088/684776
|
||||
less_log=$(git log --pretty="format:%s %ae" --cherry-pick --left-only --no-merges "$new_ref...$old_ref")
|
||||
more_log=$(git log --pretty="format:%s %ae" "$new_ref..$old_ref")
|
||||
|
||||
new_commits=$(diff --new-line-format="" --unchanged-line-format="" <(echo "$less_log") <(echo "$more_log") | grep -v "Merge pull request from GHSA")
|
||||
new_commits_no_email=$(echo "$new_commits" | strip_last_word)
|
||||
|
||||
contributors_num=$(echo "$new_commits" | only_last_word | sort -u | nonempty_line_count)
|
||||
|
||||
new_commits_num=$(echo "$new_commits" | nonempty_line_count)
|
||||
features_num=$(echo "$new_commits_no_email" | grep '^feat' | nonempty_line_count)
|
||||
fixes_num=$(echo "$new_commits_no_email" | grep '^fix' | nonempty_line_count)
|
||||
|
||||
previous_contributors=$(git log --pretty="format:%an %ae" "$old_ref" | sort -uf)
|
||||
all_contributors=$(git log --pretty="format:%an %ae" "$new_ref" | sort -uf)
|
||||
new_contributors=$(diff --new-line-format="" --unchanged-line-format="" <(echo "$all_contributors") <(echo "$previous_contributors"))
|
||||
new_contributors_num=$(echo "$new_contributors" | only_last_word | nonempty_line_count) # Count contributors by email
|
||||
new_contributors_names=$(echo "$new_contributors" | strip_last_word | to_list_items)
|
||||
|
||||
new_contributors_message=""
|
||||
if [ "$new_contributors_num" -gt 0 ]; then
|
||||
new_contributors_message=" ($new_contributors_num of them new)"
|
||||
fi
|
||||
|
||||
echo "## Changes"
|
||||
echo
|
||||
echo "This release includes $new_commits_num contributions from $contributors_num contributors$new_contributors_message with $features_num features and $fixes_num bug fixes."
|
||||
echo
|
||||
if [ "$new_contributors_num" -lt 20 ] && [ "$new_contributors_num" -gt 0 ]; then
|
||||
echo "A special thanks goes to the $new_contributors_num new contributors:"
|
||||
echo "$new_contributors_names"
|
||||
echo
|
||||
fi
|
||||
@@ -30,6 +30,7 @@ cleanup() {
|
||||
|
||||
if test "${NEW_TAG}" = "" -o "${GIT_REMOTE}" = ""; then
|
||||
echo "!! Usage: $0 <release tag> <remote> [path to release notes file]" >&2
|
||||
echo "You can use generate-release-notes.sh to generate the release notes file." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: dex
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
image: ghcr.io/dexidp/dex:v2.35.3
|
||||
imagePullPolicy: Always
|
||||
command: [/shared/argocd-dex, rundex]
|
||||
securityContext:
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.10
|
||||
newTag: v2.4.18
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -336,8 +336,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -682,8 +682,7 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management plugin
|
||||
specific options
|
||||
description: Plugin holds config management plugin specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1038,8 +1037,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1410,8 +1409,8 @@ spec:
|
||||
from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin
|
||||
specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -1754,8 +1753,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -2088,8 +2087,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -9385,7 +9384,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9615,7 +9614,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -9664,7 +9663,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -9851,7 +9850,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.10
|
||||
newTag: v2.4.18
|
||||
|
||||
@@ -335,8 +335,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -681,8 +681,7 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management plugin
|
||||
specific options
|
||||
description: Plugin holds config management plugin specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1037,8 +1036,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1409,8 +1408,8 @@ spec:
|
||||
from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin
|
||||
specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -1753,8 +1752,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -2087,8 +2086,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.10
|
||||
newTag: v2.4.18
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -336,8 +336,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -682,8 +682,7 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management plugin
|
||||
specific options
|
||||
description: Plugin holds config management plugin specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1038,8 +1037,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1410,8 +1409,8 @@ spec:
|
||||
from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin
|
||||
specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -1754,8 +1753,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -2088,8 +2087,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -10320,7 +10319,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -10392,7 +10391,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
image: ghcr.io/dexidp/dex:v2.35.3
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -10417,7 +10416,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -10457,7 +10456,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10714,7 +10713,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10763,7 +10762,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -11010,7 +11009,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -11218,7 +11217,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1244,7 +1244,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1316,7 +1316,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
image: ghcr.io/dexidp/dex:v2.35.3
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -1341,7 +1341,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1381,7 +1381,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1638,7 +1638,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1687,7 +1687,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1934,7 +1934,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2142,7 +2142,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -336,8 +336,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -682,8 +682,7 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management plugin
|
||||
specific options
|
||||
description: Plugin holds config management plugin specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1038,8 +1037,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable entries
|
||||
@@ -1410,8 +1409,8 @@ spec:
|
||||
from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin
|
||||
specific options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -1754,8 +1753,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -2088,8 +2087,8 @@ spec:
|
||||
and is only valid for applications sourced from Git.
|
||||
type: string
|
||||
plugin:
|
||||
description: ConfigManagementPlugin holds config management
|
||||
plugin specific options
|
||||
description: Plugin holds config management plugin specific
|
||||
options
|
||||
properties:
|
||||
env:
|
||||
description: Env is a list of environment variable
|
||||
@@ -9692,7 +9691,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9764,7 +9763,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
image: ghcr.io/dexidp/dex:v2.35.3
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -9789,7 +9788,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -9829,7 +9828,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10054,7 +10053,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10103,7 +10102,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -10346,7 +10345,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -10548,7 +10547,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -616,7 +616,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -688,7 +688,7 @@ spec:
|
||||
- command:
|
||||
- /shared/argocd-dex
|
||||
- rundex
|
||||
image: ghcr.io/dexidp/dex:v2.32.0
|
||||
image: ghcr.io/dexidp/dex:v2.35.3
|
||||
imagePullPolicy: Always
|
||||
name: dex
|
||||
ports:
|
||||
@@ -713,7 +713,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -753,7 +753,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -978,7 +978,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1027,7 +1027,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1270,7 +1270,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1472,7 +1472,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.10
|
||||
image: quay.io/argoproj/argocd:v2.4.18
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -119,6 +119,7 @@ nav:
|
||||
- user-guide/kustomize.md
|
||||
- user-guide/helm.md
|
||||
- user-guide/jsonnet.md
|
||||
- user-guide/directory.md
|
||||
- user-guide/config-management-plugins.md
|
||||
- user-guide/tool_detection.md
|
||||
- user-guide/projects.md
|
||||
|
||||
@@ -155,6 +155,10 @@ func (p *AppProject) ValidateProject() error {
|
||||
destKeys := make(map[string]bool)
|
||||
for _, dest := range p.Spec.Destinations {
|
||||
key := fmt.Sprintf("%s/%s", dest.Server, dest.Namespace)
|
||||
if dest.Server == "" && dest.Name != "" {
|
||||
// destination cluster set using name instead of server endpoint
|
||||
key = fmt.Sprintf("%s/%s", dest.Name, dest.Namespace)
|
||||
}
|
||||
if _, ok := destKeys[key]; ok {
|
||||
return status.Errorf(codes.InvalidArgument, "destination '%s' already added", key)
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ message ApplicationSource {
|
||||
// Directory holds path/directory specific options
|
||||
optional ApplicationSourceDirectory directory = 10;
|
||||
|
||||
// ConfigManagementPlugin holds config management plugin specific options
|
||||
// Plugin holds config management plugin specific options
|
||||
optional ApplicationSourcePlugin plugin = 11;
|
||||
|
||||
// Chart is a Helm chart name, and must be specified for applications sourced from a Helm repo.
|
||||
|
||||
@@ -638,7 +638,7 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSource(ref common.Reference
|
||||
},
|
||||
"plugin": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ConfigManagementPlugin holds config management plugin specific options",
|
||||
Description: "Plugin holds config management plugin specific options",
|
||||
Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSourcePlugin"),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -166,7 +166,7 @@ type ApplicationSource struct {
|
||||
Kustomize *ApplicationSourceKustomize `json:"kustomize,omitempty" protobuf:"bytes,8,opt,name=kustomize"`
|
||||
// Directory holds path/directory specific options
|
||||
Directory *ApplicationSourceDirectory `json:"directory,omitempty" protobuf:"bytes,10,opt,name=directory"`
|
||||
// ConfigManagementPlugin holds config management plugin specific options
|
||||
// Plugin holds config management plugin specific options
|
||||
Plugin *ApplicationSourcePlugin `json:"plugin,omitempty" protobuf:"bytes,11,opt,name=plugin"`
|
||||
// Chart is a Helm chart name, and must be specified for applications sourced from a Helm repo.
|
||||
Chart string `json:"chart,omitempty" protobuf:"bytes,12,opt,name=chart"`
|
||||
|
||||
@@ -260,11 +260,75 @@ func TestAppProject_RemoveGroupFromRole(t *testing.T) {
|
||||
func newTestProject() *AppProject {
|
||||
p := AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "my-proj"},
|
||||
Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "my-role"}}},
|
||||
Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "my-role"}}, Destinations: []ApplicationDestination{{}}},
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
||||
// TestAppProject_ValidateDestinations tests for an invalid destination
|
||||
func TestAppProject_ValidateDestinations(t *testing.T) {
|
||||
p := newTestProject()
|
||||
err := p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
|
||||
goodNamespaces := []string{
|
||||
"*",
|
||||
"some-namespace",
|
||||
}
|
||||
for _, goodNamespace := range goodNamespaces {
|
||||
p.Spec.Destinations[0].Namespace = goodNamespace
|
||||
err = p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
goodServers := []string{
|
||||
"*",
|
||||
"some-server",
|
||||
}
|
||||
for _, badName := range goodServers {
|
||||
p.Spec.Destinations[0].Server = badName
|
||||
err = p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
goodNames := []string{
|
||||
"*",
|
||||
"some-name",
|
||||
}
|
||||
for _, goodName := range goodNames {
|
||||
p.Spec.Destinations[0].Name = goodName
|
||||
err = p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
validDestination := ApplicationDestination{
|
||||
Server: "some-server",
|
||||
Namespace: "some-namespace",
|
||||
}
|
||||
|
||||
p.Spec.Destinations[0] = validDestination
|
||||
err = p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
|
||||
//no duplicates allowed
|
||||
p.Spec.Destinations = []ApplicationDestination{validDestination, validDestination}
|
||||
err = p.ValidateProject()
|
||||
assert.Error(t, err)
|
||||
|
||||
cluster1Destination := ApplicationDestination{
|
||||
Name: "cluster1",
|
||||
Namespace: "some-namespace",
|
||||
}
|
||||
cluster2Destination := ApplicationDestination{
|
||||
Name: "cluster2",
|
||||
Namespace: "some-namespace",
|
||||
}
|
||||
// allow multiple destinations with blank server, same namespace but unique cluster name
|
||||
p.Spec.Destinations = []ApplicationDestination{cluster1Destination, cluster2Destination}
|
||||
err = p.ValidateProject()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// TestValidateRoleName tests for an invalid role name
|
||||
func TestAppProject_ValidateRoleName(t *testing.T) {
|
||||
p := newTestProject()
|
||||
|
||||
@@ -697,6 +697,32 @@ func runHelmBuild(appPath string, h helm.Helm) error {
|
||||
return ioutil.WriteFile(markerFile, []byte("marker"), 0644)
|
||||
}
|
||||
|
||||
func populateRequestRepos(appPath string, q *apiclient.ManifestRequest) error {
|
||||
repos, err := getHelmDependencyRepos(appPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, r := range repos {
|
||||
if !repoExists(r.Repo, q.Repos) {
|
||||
repositoryCredential := getRepoCredential(q.HelmRepoCreds, r.Repo)
|
||||
if repositoryCredential != nil {
|
||||
if repositoryCredential.EnableOCI {
|
||||
r.Repo = strings.TrimPrefix(r.Repo, ociPrefix)
|
||||
}
|
||||
r.EnableOCI = repositoryCredential.EnableOCI
|
||||
r.Password = repositoryCredential.Password
|
||||
r.Username = repositoryCredential.Username
|
||||
r.SSHPrivateKey = repositoryCredential.SSHPrivateKey
|
||||
r.TLSClientCertData = repositoryCredential.TLSClientCertData
|
||||
r.TLSClientCertKey = repositoryCredential.TLSClientCertKey
|
||||
}
|
||||
q.Repos = append(q.Repos, r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool) ([]*unstructured.Unstructured, error) {
|
||||
concurrencyAllowed := isConcurrencyAllowed(appPath)
|
||||
if !concurrencyAllowed {
|
||||
@@ -728,7 +754,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
|
||||
for _, val := range appHelm.ValueFiles {
|
||||
|
||||
// This will resolve val to an absolute path (or an URL)
|
||||
path, isRemote, err := pathutil.ResolveFilePath(appPath, repoRoot, val, q.GetValuesFileSchemes())
|
||||
path, isRemote, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, val, q.GetValuesFileSchemes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -768,7 +794,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
|
||||
}
|
||||
}
|
||||
for _, p := range appHelm.FileParameters {
|
||||
resolvedPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes())
|
||||
resolvedPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -787,24 +813,8 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
|
||||
templateOpts.SetString[i] = env.Envsubst(j)
|
||||
}
|
||||
|
||||
repos, err := getHelmDependencyRepos(appPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, r := range repos {
|
||||
if !repoExists(r.Repo, q.Repos) {
|
||||
repositoryCredential := getRepoCredential(q.HelmRepoCreds, r.Repo)
|
||||
if repositoryCredential != nil {
|
||||
r.EnableOCI = repositoryCredential.EnableOCI
|
||||
r.Password = repositoryCredential.Password
|
||||
r.Username = repositoryCredential.Username
|
||||
r.SSHPrivateKey = repositoryCredential.SSHPrivateKey
|
||||
r.TLSClientCertData = repositoryCredential.TLSClientCertData
|
||||
r.TLSClientCertKey = repositoryCredential.TLSClientCertKey
|
||||
}
|
||||
q.Repos = append(q.Repos, r)
|
||||
}
|
||||
if err := populateRequestRepos(appPath, q); err != nil {
|
||||
return nil, fmt.Errorf("failed parsing dependencies: %v", err)
|
||||
}
|
||||
|
||||
var proxy string
|
||||
@@ -939,6 +949,10 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
|
||||
|
||||
manifests := make([]string, 0)
|
||||
for _, obj := range targetObjs {
|
||||
if obj == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var targets []*unstructured.Unstructured
|
||||
if obj.IsList() {
|
||||
err = obj.EachListItem(func(object runtime.Object) error {
|
||||
@@ -1367,7 +1381,7 @@ func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.Appli
|
||||
jpaths := []string{appPath}
|
||||
for _, p := range sourceJsonnet.Libs {
|
||||
// the jsonnet library path is relative to the repository root, not application path
|
||||
jpath, _, err := pathutil.ResolveFilePath(repoRoot, repoRoot, p, nil)
|
||||
jpath, err := pathutil.ResolveFileOrDirectoryPath(repoRoot, repoRoot, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1609,7 +1623,7 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
|
||||
return err
|
||||
}
|
||||
|
||||
if resolvedValuesPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, "values.yaml", []string{}); err == nil {
|
||||
if resolvedValuesPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, "values.yaml", []string{}); err == nil {
|
||||
if err := loadFileIntoIfExists(resolvedValuesPath, &res.Helm.Values); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1619,7 +1633,7 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
|
||||
var resolvedSelectedValueFiles []pathutil.ResolvedFilePath
|
||||
// drop not allowed values files
|
||||
for _, file := range selectedValueFiles {
|
||||
if resolvedFile, _, err := pathutil.ResolveFilePath(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil {
|
||||
if resolvedFile, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil {
|
||||
resolvedSelectedValueFiles = append(resolvedSelectedValueFiles, resolvedFile)
|
||||
} else {
|
||||
log.Warnf("Values file %s is not allowed: %v", file, err)
|
||||
|
||||
@@ -47,14 +47,14 @@ gpg: using RSA key 4AEE18F83AFDEB23
|
||||
gpg: Good signature from "GitHub (web-flow commit signing) <noreply@github.com>" [ultimate]
|
||||
`
|
||||
|
||||
type clientFunc func(*gitmocks.Client)
|
||||
type clientFunc func(*gitmocks.Client, *helmmocks.Client)
|
||||
|
||||
func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) {
|
||||
root, err := filepath.Abs(root)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return newServiceWithOpt(func(gitClient *gitmocks.Client) {
|
||||
return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) {
|
||||
gitClient.On("Init").Return(nil)
|
||||
gitClient.On("Fetch", mock.Anything).Return(nil)
|
||||
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
|
||||
@@ -66,26 +66,27 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client)
|
||||
} else {
|
||||
gitClient.On("VerifyCommitSignature", mock.Anything).Return("", nil)
|
||||
}
|
||||
})
|
||||
|
||||
chart := "my-chart"
|
||||
version := "1.1.0"
|
||||
helmClient.On("GetIndex", true).Return(&helm.Index{Entries: map[string]helm.Entries{
|
||||
chart: {{Version: "1.0.0"}, {Version: version}},
|
||||
}}, nil)
|
||||
helmClient.On("ExtractChart", chart, version).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version).Return(nil)
|
||||
helmClient.On("DependencyBuild").Return(nil)
|
||||
}, root)
|
||||
}
|
||||
|
||||
func newServiceWithOpt(cf clientFunc) (*Service, *gitmocks.Client) {
|
||||
func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) {
|
||||
helmClient := &helmmocks.Client{}
|
||||
gitClient := &gitmocks.Client{}
|
||||
cf(gitClient)
|
||||
cf(gitClient, helmClient)
|
||||
service := NewService(metrics.NewMetricsServer(), cache.NewCache(
|
||||
cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)),
|
||||
1*time.Minute,
|
||||
1*time.Minute,
|
||||
), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, os.TempDir())
|
||||
|
||||
chart := "my-chart"
|
||||
version := "1.1.0"
|
||||
helmClient.On("GetIndex", true).Return(&helm.Index{Entries: map[string]helm.Entries{
|
||||
chart: {{Version: "1.0.0"}, {Version: version}},
|
||||
}}, nil)
|
||||
helmClient.On("ExtractChart", chart, version).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version).Return(nil)
|
||||
), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root)
|
||||
|
||||
service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, prosy string, opts ...git.ClientOpts) (client git.Client, e error) {
|
||||
return gitClient, nil
|
||||
@@ -110,6 +111,11 @@ func newServiceWithSignature(root string) *Service {
|
||||
}
|
||||
|
||||
func newServiceWithCommitSHA(root, revision string) *Service {
|
||||
root, err := filepath.Abs(root)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var revisionErr error
|
||||
|
||||
commitSHARegex := regexp.MustCompile("^[0-9A-Fa-f]{40}$")
|
||||
@@ -117,14 +123,14 @@ func newServiceWithCommitSHA(root, revision string) *Service {
|
||||
revisionErr = errors.New("not a commit SHA")
|
||||
}
|
||||
|
||||
service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client) {
|
||||
service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) {
|
||||
gitClient.On("Init").Return(nil)
|
||||
gitClient.On("Fetch", mock.Anything).Return(nil)
|
||||
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
|
||||
gitClient.On("LsRemote", revision).Return(revision, revisionErr)
|
||||
gitClient.On("CommitSHA").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil)
|
||||
gitClient.On("Root").Return(root)
|
||||
})
|
||||
}, root)
|
||||
|
||||
service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) {
|
||||
return gitClient, nil
|
||||
@@ -363,6 +369,27 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) {
|
||||
assert.Equal(t, 2, len(res1.Manifests))
|
||||
}
|
||||
|
||||
func TestGenerateJsonnetManifestInRootDir(t *testing.T) {
|
||||
service := newService("testdata/jsonnet-1")
|
||||
|
||||
q := apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
ApplicationSource: &argoappv1.ApplicationSource{
|
||||
Path: ".",
|
||||
Directory: &argoappv1.ApplicationSourceDirectory{
|
||||
Jsonnet: argoappv1.ApplicationSourceJsonnet{
|
||||
ExtVars: []argoappv1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}},
|
||||
TLAs: []argoappv1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}},
|
||||
Libs: []string{"."},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
res1, err := service.GenerateManifest(context.Background(), &q)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res1.Manifests))
|
||||
}
|
||||
|
||||
func TestGenerateJsonnetLibOutside(t *testing.T) {
|
||||
service := newService(".")
|
||||
|
||||
@@ -379,7 +406,7 @@ func TestGenerateJsonnetLibOutside(t *testing.T) {
|
||||
}
|
||||
_, err := service.GenerateManifest(context.Background(), &q)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "value file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
|
||||
require.Contains(t, err.Error(), "file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
|
||||
}
|
||||
|
||||
func TestManifestGenErrorCacheByNumRequests(t *testing.T) {
|
||||
@@ -1159,6 +1186,7 @@ func TestListApps(t *testing.T) {
|
||||
"kustomization_yml": "Kustomize",
|
||||
"my-chart": "Helm",
|
||||
"my-chart-2": "Helm",
|
||||
"oci-dependencies": "Helm",
|
||||
"out-of-bounds-values-file-link": "Helm",
|
||||
"values-files": "Helm",
|
||||
}
|
||||
@@ -2478,3 +2506,18 @@ func Test_populateHelmAppDetails_values_symlinks(t *testing.T) {
|
||||
assert.Empty(t, res.Helm.Parameters)
|
||||
})
|
||||
}
|
||||
|
||||
func TestOCIDependencies(t *testing.T) {
|
||||
src := argoappv1.ApplicationSource{Path: "."}
|
||||
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, HelmRepoCreds: []*argoappv1.RepoCreds{
|
||||
{URL: "example.com", Username: "test", Password: "test", EnableOCI: true},
|
||||
}}
|
||||
|
||||
err := populateRequestRepos("./testdata/oci-dependencies", &q)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, len(q.Repos), 1)
|
||||
assert.Equal(t, q.Repos[0].Username, "test")
|
||||
assert.Equal(t, q.Repos[0].EnableOCI, true)
|
||||
assert.Equal(t, q.Repos[0].Repo, "example.com")
|
||||
}
|
||||
|
||||
47
reposerver/repository/testdata/jsonnet-1/guestbook-ui.jsonnet
vendored
Normal file
47
reposerver/repository/testdata/jsonnet-1/guestbook-ui.jsonnet
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
local service = import 'vendor/nested/service.libsonnet';
|
||||
local params = import 'params.libsonnet';
|
||||
|
||||
function(tlaString, tlaCode)
|
||||
[
|
||||
service.new(params),
|
||||
{
|
||||
apiVersion: 'apps/v1beta2',
|
||||
kind: 'Deployment',
|
||||
metadata: {
|
||||
name: params.name,
|
||||
},
|
||||
spec: {
|
||||
replicas: params.replicas,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
app: params.name,
|
||||
},
|
||||
},
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: params.name,
|
||||
tlaString: tlaString,
|
||||
tlaCode: tlaCode,
|
||||
extVarString: std.extVar('extVarString'),
|
||||
extVarCode: std.extVar('extVarCode'),
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
containers: [
|
||||
{
|
||||
image: params.image,
|
||||
name: params.name,
|
||||
ports: [
|
||||
{
|
||||
containerPort: params.containerPort,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
]
|
||||
8
reposerver/repository/testdata/jsonnet-1/params.libsonnet
vendored
Normal file
8
reposerver/repository/testdata/jsonnet-1/params.libsonnet
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
containerPort: 80,
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
|
||||
name: "guestbook-ui",
|
||||
replicas: 1,
|
||||
servicePort: 80,
|
||||
type: "ClusterIP",
|
||||
}
|
||||
23
reposerver/repository/testdata/jsonnet-1/vendor/nested/service.libsonnet
vendored
Normal file
23
reposerver/repository/testdata/jsonnet-1/vendor/nested/service.libsonnet
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
local new(params) = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: params.name,
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{
|
||||
port: params.servicePort,
|
||||
targetPort: params.containerPort,
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
app: params.name,
|
||||
},
|
||||
type: params.type,
|
||||
},
|
||||
};
|
||||
|
||||
{
|
||||
new:: new,
|
||||
}
|
||||
@@ -43,4 +43,5 @@ function(tlaString, tlaCode)
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
]
|
||||
|
||||
6
reposerver/repository/testdata/oci-dependencies/Chart.yaml
vendored
Normal file
6
reposerver/repository/testdata/oci-dependencies/Chart.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
name: my-chart
|
||||
version: 1.1.0
|
||||
dependencies:
|
||||
- name: my-dependency
|
||||
repository: oci://example.com
|
||||
version: '*'
|
||||
@@ -3,7 +3,7 @@ if obj.status ~= nil then
|
||||
if obj.status.conditions ~= nil and obj.status.replicas ~= nil then
|
||||
numTrue = 0
|
||||
for i, condition in pairs(obj.status.conditions) do
|
||||
if (condition.type == "Available" or condition.type == "Progressing") and condition.status == "True" then
|
||||
if (condition.type == "Available" or (condition.type == "Progressing" and condition.reason == "NewReplicationControllerAvailable")) and condition.status == "True" then
|
||||
numTrue = numTrue + 1
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,10 @@ tests:
|
||||
status: Progressing
|
||||
message: "replication controller is waiting for pods to run"
|
||||
inputPath: testdata/progressing.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "replication controller is waiting for pods to run"
|
||||
inputPath: testdata/progressing_rc_updated.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: "Deployment config is degraded"
|
||||
|
||||
66
resource_customizations/apps.openshift.io/DeploymentConfig/testdata/progressing_rc_updated.yaml
vendored
Normal file
66
resource_customizations/apps.openshift.io/DeploymentConfig/testdata/progressing_rc_updated.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
kind: DeploymentConfig
|
||||
apiVersion: apps.openshift.io/v1
|
||||
metadata:
|
||||
name: example
|
||||
namespace: default
|
||||
spec:
|
||||
strategy:
|
||||
type: Rolling
|
||||
rollingParams:
|
||||
updatePeriodSeconds: 1
|
||||
intervalSeconds: 1
|
||||
timeoutSeconds: 600
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
resources: {}
|
||||
activeDeadlineSeconds: 21600
|
||||
triggers:
|
||||
- type: ConfigChange
|
||||
replicas: 3
|
||||
revisionHistoryLimit: 10
|
||||
test: false
|
||||
selector:
|
||||
app: httpd
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: httpd
|
||||
spec:
|
||||
containers:
|
||||
- name: httpd
|
||||
image: >-
|
||||
image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
imagePullPolicy: Always
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 30
|
||||
dnsPolicy: ClusterFirst
|
||||
securityContext: {}
|
||||
schedulerName: default-scheduler
|
||||
status:
|
||||
observedGeneration: 1
|
||||
details:
|
||||
message: config change
|
||||
causes:
|
||||
- type: ConfigChange
|
||||
availableReplicas: 3
|
||||
conditions:
|
||||
- type: Available
|
||||
status: 'True'
|
||||
lastUpdateTime: '2021-08-25T23:48:29Z'
|
||||
lastTransitionTime: '2021-08-25T23:48:29Z'
|
||||
message: Deployment config has minimum availability.
|
||||
- type: Progressing
|
||||
status: 'True'
|
||||
lastUpdateTime: '2021-08-25T23:48:29Z'
|
||||
lastTransitionTime: '2021-08-25T23:48:15Z'
|
||||
reason: ReplicationControllerUpdated
|
||||
message: replication controller "example-1" is progressing
|
||||
replicas: 3
|
||||
readyReplicas: 3
|
||||
@@ -3,17 +3,21 @@ if obj.status ~= nil then
|
||||
if obj.status.conditions ~= nil then
|
||||
for i, condition in ipairs(obj.status.conditions) do
|
||||
health_status.message = condition.message
|
||||
if condition.reason == "Successful" then
|
||||
if condition.type == "Successful" and condition.status == "True" then
|
||||
health_status.status = "Healthy"
|
||||
elseif condition.reason == "Running" then
|
||||
health_status.status = "Progressing"
|
||||
else
|
||||
health_status.status = "Degraded"
|
||||
return health_status
|
||||
end
|
||||
if condition.type == "Failure" and condition.status == "True" then
|
||||
health_status.status = "Degraded"
|
||||
return health_status
|
||||
end
|
||||
if condition.type == "Running" and condition.reason == "Running" then
|
||||
health_status.status = "Progressing"
|
||||
return health_status
|
||||
end
|
||||
return health_status
|
||||
end
|
||||
end
|
||||
end
|
||||
health_status.status = "Progressing"
|
||||
health_status.message = "Waiting for Kiali"
|
||||
return health_status
|
||||
return health_status
|
||||
|
||||
@@ -9,5 +9,5 @@ tests:
|
||||
inputPath: testdata/degraded.yaml
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: "Awaiting next reconciliation"
|
||||
message: "Last reconciliation succeeded"
|
||||
inputPath: testdata/healthy.yaml
|
||||
|
||||
@@ -14,14 +14,24 @@ metadata:
|
||||
spec: {}
|
||||
status:
|
||||
conditions:
|
||||
- ansibleResult:
|
||||
changed: 1
|
||||
completion: 2020-06-08T13:41:20.133525
|
||||
failures: 0
|
||||
ok: 56
|
||||
skipped: 82
|
||||
lastTransitionTime: "2020-06-04T17:47:31Z"
|
||||
message: Error Reconciling
|
||||
reason: null
|
||||
status: "True"
|
||||
type: Running
|
||||
- lastTransitionTime: '2022-10-19T09:44:32Z'
|
||||
message: ''
|
||||
reason: ''
|
||||
status: 'False'
|
||||
type: Failure
|
||||
- ansibleResult:
|
||||
changed: 18
|
||||
completion: '2022-10-19T09:44:32.289505'
|
||||
failures: 0
|
||||
ok: 101
|
||||
skipped: 101
|
||||
lastTransitionTime: '2022-10-19T09:43:39Z'
|
||||
message: Awaiting next reconciliation
|
||||
reason: Successful
|
||||
status: 'True'
|
||||
type: Running
|
||||
- lastTransitionTime: '2022-10-19T09:44:32Z'
|
||||
message: Error Reconciling
|
||||
reason: Failure
|
||||
status: 'True'
|
||||
type: Failure
|
||||
|
||||
@@ -14,14 +14,24 @@ metadata:
|
||||
spec: {}
|
||||
status:
|
||||
conditions:
|
||||
- ansibleResult:
|
||||
changed: 1
|
||||
completion: 2020-06-08T13:41:20.133525
|
||||
failures: 0
|
||||
ok: 56
|
||||
skipped: 82
|
||||
lastTransitionTime: "2020-06-04T17:47:31Z"
|
||||
message: Awaiting next reconciliation
|
||||
reason: Successful
|
||||
status: "True"
|
||||
type: Running
|
||||
- lastTransitionTime: '2022-10-19T09:44:32Z'
|
||||
message: ''
|
||||
reason: ''
|
||||
status: 'False'
|
||||
type: Failure
|
||||
- ansibleResult:
|
||||
changed: 18
|
||||
completion: '2022-10-19T09:44:32.289505'
|
||||
failures: 0
|
||||
ok: 101
|
||||
skipped: 101
|
||||
lastTransitionTime: '2022-10-19T09:43:39Z'
|
||||
message: Awaiting next reconciliation
|
||||
reason: Successful
|
||||
status: 'True'
|
||||
type: Running
|
||||
- lastTransitionTime: '2022-10-19T09:44:32Z'
|
||||
message: Last reconciliation succeeded
|
||||
reason: Successful
|
||||
status: 'True'
|
||||
type: Successful
|
||||
|
||||
@@ -36,11 +36,21 @@ if obj.status ~= nil then
|
||||
health_status.message = obj.status.currentState
|
||||
return health_status
|
||||
end
|
||||
if obj.status.currentState == "Tenant credentials are not set properly" then
|
||||
health_status.status = "Degraded"
|
||||
health_status.message = obj.status.currentState
|
||||
return health_status
|
||||
end
|
||||
if obj.status.currentState == "Different versions across MinIO Pools" then
|
||||
health_status.status = "Degraded"
|
||||
health_status.message = obj.status.currentState
|
||||
return health_status
|
||||
end
|
||||
if obj.status.currentState == "Pool Decommissioning Not Allowed" then
|
||||
health_status.status = "Degraded"
|
||||
health_status.message = obj.status.currentState
|
||||
return health_status
|
||||
end
|
||||
health_status.status = "Progressing"
|
||||
health_status.message = obj.status.currentState
|
||||
return health_status
|
||||
|
||||
@@ -23,10 +23,18 @@ tests:
|
||||
status: Degraded
|
||||
message: "Another MinIO Tenant already exists in the namespace"
|
||||
inputPath: testdata/another_tenant_exists.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: "Tenant credentials are not set properly"
|
||||
inputPath: testdata/incorrect_tenant_credentials.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: "Different versions across MinIO Pools"
|
||||
inputPath: testdata/versions_mismatch.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: "Pool Decommissioning Not Allowed"
|
||||
inputPath: testdata/pool_decommissioning_not_allowed.yaml
|
||||
- healthStatus:
|
||||
status: Progressing
|
||||
message: "<unknown status message>"
|
||||
|
||||
13
resource_customizations/minio.min.io/Tenant/testdata/incorrect_tenant_credentials.yaml
vendored
Normal file
13
resource_customizations/minio.min.io/Tenant/testdata/incorrect_tenant_credentials.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: minio.min.io/v2
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: minio-tenant
|
||||
spec:
|
||||
image: minio/minio:latest
|
||||
pools:
|
||||
- name: pool-0
|
||||
servers: 1
|
||||
volumesPerServer: 4
|
||||
status:
|
||||
revision: 0
|
||||
currentState: Tenant credentials are not set properly
|
||||
13
resource_customizations/minio.min.io/Tenant/testdata/pool_decommissioning_not_allowed.yaml
vendored
Normal file
13
resource_customizations/minio.min.io/Tenant/testdata/pool_decommissioning_not_allowed.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: minio.min.io/v2
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: minio-tenant
|
||||
spec:
|
||||
image: minio/minio:latest
|
||||
pools:
|
||||
- name: pool-0
|
||||
servers: 1
|
||||
volumesPerServer: 4
|
||||
status:
|
||||
revision: 0
|
||||
currentState: Pool Decommissioning Not Allowed
|
||||
@@ -8,7 +8,9 @@ if obj.status ~= nil then
|
||||
msg = msg .. i .. ": " .. condition.type .. " | " .. condition.status .. "\n"
|
||||
if condition.type == "InstallPlanPending" and condition.status == "True" then
|
||||
numPending = numPending + 1
|
||||
elseif (condition.type == "CatalogSourcesUnhealthy" or condition.type == "InstallPlanMissing" or condition.type == "InstallPlanFailed" or condition.type == "ResolutionFailed") and condition.status == "True" then
|
||||
elseif (condition.type == "InstallPlanMissing" and condition.reason ~= "ReferencedInstallPlanNotFound") then
|
||||
numDegraded = numDegraded + 1
|
||||
elseif (condition.type == "CatalogSourcesUnhealthy" or condition.type == "InstallPlanFailed" or condition.type == "ResolutionFailed") and condition.status == "True" then
|
||||
numDegraded = numDegraded + 1
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ tests:
|
||||
message: "1: CatalogSourcesUnhealthy | True\n"
|
||||
inputPath: testdata/catalog_sources_unhealthy.yaml
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
status: Healthy
|
||||
message: "1: CatalogSourcesUnhealthy | False\n2: InstallPlanMissing | True\n"
|
||||
inputPath: testdata/install_plan_missing.yaml
|
||||
- healthStatus:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
@@ -144,6 +145,12 @@ func (s *Server) getCluster(ctx context.Context, q *cluster.ClusterQuery) (*appv
|
||||
q.Name = ""
|
||||
if q.Id.Type == "name" {
|
||||
q.Name = q.Id.Value
|
||||
} else if q.Id.Type == "name_escaped" {
|
||||
nameUnescaped, err := url.QueryUnescape(q.Id.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q.Name = nameUnescaped
|
||||
} else {
|
||||
q.Server = q.Id.Value
|
||||
}
|
||||
|
||||
@@ -48,6 +48,66 @@ func newNoopEnforcer() *rbac.Enforcer {
|
||||
return enf
|
||||
}
|
||||
|
||||
func TestGetCluster_UrlEncodedName(t *testing.T) {
|
||||
db := &dbmocks.ArgoDB{}
|
||||
|
||||
mockCluster := v1alpha1.Cluster{
|
||||
Name: "test/ing",
|
||||
Server: "https://127.0.0.1",
|
||||
Namespaces: []string{"default", "kube-system"},
|
||||
}
|
||||
mockClusterList := v1alpha1.ClusterList{
|
||||
ListMeta: v1.ListMeta{},
|
||||
Items: []v1alpha1.Cluster{
|
||||
mockCluster,
|
||||
},
|
||||
}
|
||||
|
||||
db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil)
|
||||
|
||||
server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{})
|
||||
|
||||
cluster, err := server.Get(context.Background(), &clusterapi.ClusterQuery{
|
||||
Id: &clusterapi.ClusterID{
|
||||
Type: "name_escaped",
|
||||
Value: "test%2fing",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, cluster.Name, "test/ing")
|
||||
}
|
||||
|
||||
func TestGetCluster_NameWithUrlEncodingButShouldNotBeUnescaped(t *testing.T) {
|
||||
db := &dbmocks.ArgoDB{}
|
||||
|
||||
mockCluster := v1alpha1.Cluster{
|
||||
Name: "test%2fing",
|
||||
Server: "https://127.0.0.1",
|
||||
Namespaces: []string{"default", "kube-system"},
|
||||
}
|
||||
mockClusterList := v1alpha1.ClusterList{
|
||||
ListMeta: v1.ListMeta{},
|
||||
Items: []v1alpha1.Cluster{
|
||||
mockCluster,
|
||||
},
|
||||
}
|
||||
|
||||
db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil)
|
||||
|
||||
server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{})
|
||||
|
||||
cluster, err := server.Get(context.Background(), &clusterapi.ClusterQuery{
|
||||
Id: &clusterapi.ClusterID{
|
||||
Type: "name",
|
||||
Value: "test%2fing",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, cluster.Name, "test%2fing")
|
||||
}
|
||||
|
||||
func TestUpdateCluster_NoFieldsPaths(t *testing.T) {
|
||||
db := &dbmocks.ArgoDB{}
|
||||
var updated *v1alpha1.Cluster
|
||||
|
||||
@@ -97,7 +97,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/dex"
|
||||
dexutil "github.com/argoproj/argo-cd/v2/util/dex"
|
||||
"github.com/argoproj/argo-cd/v2/util/env"
|
||||
"github.com/argoproj/argo-cd/v2/util/errors"
|
||||
errorsutil "github.com/argoproj/argo-cd/v2/util/errors"
|
||||
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
|
||||
"github.com/argoproj/argo-cd/v2/util/healthz"
|
||||
httputil "github.com/argoproj/argo-cd/v2/util/http"
|
||||
@@ -112,6 +112,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/swagger"
|
||||
tlsutil "github.com/argoproj/argo-cd/v2/util/tls"
|
||||
"github.com/argoproj/argo-cd/v2/util/webhook"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const maxConcurrentLoginRequestsCountEnv = "ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT"
|
||||
@@ -226,9 +227,9 @@ func initializeDefaultProject(opts ArgoCDServerOpts) error {
|
||||
func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
|
||||
settingsMgr := settings_util.NewSettingsManager(ctx, opts.KubeClientset, opts.Namespace)
|
||||
settings, err := settingsMgr.InitializeSettings(opts.Insecure)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
err = initializeDefaultProject(opts)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
|
||||
factory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(opts.Namespace), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {}))
|
||||
projInformer := factory.Argoproj().V1alpha1().AppProjects().Informer()
|
||||
@@ -242,7 +243,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
|
||||
enf := rbac.NewEnforcer(opts.KubeClientset, opts.Namespace, common.ArgoCDRBACConfigMapName, nil)
|
||||
enf.EnableEnforce(!opts.DisableAuth)
|
||||
err = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
enf.EnableLog(os.Getenv(common.EnvVarRBACDebug) == "1")
|
||||
|
||||
policyEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, projLister)
|
||||
@@ -511,7 +512,7 @@ func (a *ArgoCDServer) watchSettings() {
|
||||
prevURL := a.settings.URL
|
||||
prevOIDCConfig := a.settings.OIDCConfig()
|
||||
prevDexCfgBytes, err := dex.GenerateDexConfigYAML(a.settings)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
prevGitHubSecret := a.settings.WebhookGitHubSecret
|
||||
prevGitLabSecret := a.settings.WebhookGitLabSecret
|
||||
prevBitbucketUUID := a.settings.WebhookBitbucketUUID
|
||||
@@ -526,7 +527,7 @@ func (a *ArgoCDServer) watchSettings() {
|
||||
newSettings := <-updateCh
|
||||
a.settings = newSettings
|
||||
newDexCfgBytes, err := dex.GenerateDexConfigYAML(a.settings)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
if string(newDexCfgBytes) != string(prevDexCfgBytes) {
|
||||
log.Infof("dex config modified. restarting")
|
||||
break
|
||||
@@ -590,7 +591,7 @@ func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) {
|
||||
a.policyEnforcer.SetScopes(scopes)
|
||||
return nil
|
||||
})
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
}
|
||||
|
||||
func (a *ArgoCDServer) useTLS() bool {
|
||||
@@ -715,7 +716,7 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre
|
||||
// Register reflection service on gRPC server.
|
||||
reflection.Register(grpcS)
|
||||
grpc_prometheus.Register(grpcS)
|
||||
errors.CheckError(projectService.NormalizeProjs())
|
||||
errorsutil.CheckError(projectService.NormalizeProjs())
|
||||
return grpcS, appResourceTreeFn
|
||||
}
|
||||
|
||||
@@ -924,7 +925,7 @@ func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.Respo
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
log.Errorf("Failed to walk extensions directory: %v", err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -944,7 +945,7 @@ func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) {
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
}
|
||||
a.ssoClientApp, err = oidc.NewClientApp(a.settings, a.DexServerAddr, a.BaseHRef)
|
||||
errors.CheckError(err)
|
||||
errorsutil.CheckError(err)
|
||||
mux.HandleFunc(common.LoginEndpoint, a.ssoClientApp.HandleLogin)
|
||||
mux.HandleFunc(common.CallbackEndpoint, a.ssoClientApp.HandleCallback)
|
||||
}
|
||||
|
||||
@@ -9,5 +9,3 @@ spec:
|
||||
discover:
|
||||
find:
|
||||
glob: "**/kustomization.yaml"
|
||||
allowConcurrency: true
|
||||
lockRepo: false
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-application-controller go run ./cmd/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||
api-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-server go run ./cmd/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080}"
|
||||
controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||
api-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} "
|
||||
dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.30.0 serve /dex.yaml"
|
||||
redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-/tmp/argo-e2e/app/config/plugin} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server go run ./cmd/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||
repo-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
|
||||
ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start"
|
||||
reaper: ./test/container/reaper.sh
|
||||
sshd: sudo sh -c "test $ARGOCD_E2E_TEST = true && /usr/sbin/sshd -p 2222 -D -e"
|
||||
@@ -10,5 +10,5 @@ fcgiwrap: sudo sh -c "test $ARGOCD_E2E_TEST = true && (fcgiwrap -s unix:/var/run
|
||||
nginx: sudo sh -c "test $ARGOCD_E2E_TEST = true && nginx -g 'daemon off;' -c $(pwd)/test/fixture/testrepos/nginx.conf"
|
||||
helm-registry: sudo sh -c "registry serve /etc/docker/registry/config.yml"
|
||||
dev-mounter: test "$ARGOCD_E2E_TEST" != "true" && go run hack/dev-mounter/main.go --configmap argocd-ssh-known-hosts-cm=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} --configmap argocd-tls-certs-cm=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} --configmap argocd-gpg-keys-cm=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source}
|
||||
applicationset-controller: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock ARGOCD_BINARY_NAME=argocd-applicationset-controller go run ./cmd/main.go --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --namespace argocd-e2e --loglevel debug --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||
notification: sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications go run ./cmd/main.go --loglevel debug"
|
||||
applicationset-controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-applicationset-controller $COMMAND --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
|
||||
notification: sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications go run ./cmd/main.go --loglevel debug"
|
||||
|
||||
@@ -3,11 +3,9 @@ package e2e
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -21,6 +19,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -369,23 +368,18 @@ func TestDeleteAppResource(t *testing.T) {
|
||||
// demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force"
|
||||
func TestImmutableChange(t *testing.T) {
|
||||
SkipOnEnv(t, "OPENSHIFT")
|
||||
text := FailOnErr(Run(".", "kubectl", "get", "service", "-n", "kube-system", "kube-dns", "-o", "jsonpath={.spec.clusterIP}")).(string)
|
||||
parts := strings.Split(text, ".")
|
||||
n := rand.Intn(254)
|
||||
ip1 := fmt.Sprintf("%s.%s.%s.%d", parts[0], parts[1], parts[2], n)
|
||||
ip2 := fmt.Sprintf("%s.%s.%s.%d", parts[0], parts[1], parts[2], n+1)
|
||||
Given(t).
|
||||
Path("service").
|
||||
Path("secrets").
|
||||
When().
|
||||
CreateApp().
|
||||
PatchFile("service.yaml", fmt.Sprintf(`[{"op": "add", "path": "/spec/clusterIP", "value": "%s"}]`, ip1)).
|
||||
PatchFile("secrets.yaml", `[{"op": "add", "path": "/data/new-field", "value": "dGVzdA=="}, {"op": "add", "path": "/immutable", "value": true}]`).
|
||||
Sync().
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
PatchFile("service.yaml", fmt.Sprintf(`[{"op": "add", "path": "/spec/clusterIP", "value": "%s"}]`, ip2)).
|
||||
PatchFile("secrets.yaml", `[{"op": "add", "path": "/data/new-field", "value": "dGVzdDI="}]`).
|
||||
IgnoreErrors().
|
||||
Sync().
|
||||
DoNotIgnoreErrors().
|
||||
@@ -394,14 +388,14 @@ func TestImmutableChange(t *testing.T) {
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(ResourceResultNumbering(1)).
|
||||
Expect(ResourceResultMatches(ResourceResult{
|
||||
Kind: "Service",
|
||||
Kind: "Secret",
|
||||
Version: "v1",
|
||||
Namespace: DeploymentNamespace(),
|
||||
Name: "my-service",
|
||||
Name: "test-secret",
|
||||
SyncPhase: "Sync",
|
||||
Status: "SyncFailed",
|
||||
HookPhase: "Failed",
|
||||
Message: `Service "my-service" is invalid`,
|
||||
Message: `Secret "test-secret" is invalid`,
|
||||
})).
|
||||
// now we can do this will a force
|
||||
Given().
|
||||
@@ -1600,9 +1594,11 @@ func TestSyncWithInfos(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource console which does not require namespace
|
||||
//Expect: no app.Status.Conditions
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource console which does not require namespace
|
||||
//
|
||||
// Expect: no app.Status.Conditions
|
||||
func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) {
|
||||
Given(t).
|
||||
Path(globalWithNoNameSpace).
|
||||
@@ -1617,10 +1613,12 @@ func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Deployment and service do not have namespace in manifest
|
||||
//Expect: app.Status.Conditions for deployment ans service which does not have namespace in manifest
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Deployment and service do not have namespace in manifest
|
||||
//
|
||||
// Expect: app.Status.Conditions for deployment ans service which does not have namespace in manifest
|
||||
func TestCreateAppWithNoNameSpaceWhenRequired(t *testing.T) {
|
||||
Given(t).
|
||||
Path(guestbookPath).
|
||||
@@ -1638,11 +1636,13 @@ func TestCreateAppWithNoNameSpaceWhenRequired(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//Given: argocd app create does not provide --dest-namespace
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Some deployment and service has namespace in manifest
|
||||
// Some deployment and service does not have namespace in manifest
|
||||
//Expect: app.Status.Conditions for deployment and service which does not have namespace in manifest
|
||||
// Given: argocd app create does not provide --dest-namespace
|
||||
//
|
||||
// Manifest contains resource deployment, and service which requires namespace
|
||||
// Some deployment and service has namespace in manifest
|
||||
// Some deployment and service does not have namespace in manifest
|
||||
//
|
||||
// Expect: app.Status.Conditions for deployment and service which does not have namespace in manifest
|
||||
func TestCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) {
|
||||
Given(t).
|
||||
Path(guestbookWithNamespace).
|
||||
@@ -1718,10 +1718,13 @@ func TestListResource(t *testing.T) {
|
||||
}
|
||||
|
||||
// Given application is set with --sync-option CreateNamespace=true
|
||||
// application --dest-namespace does not exist
|
||||
//
|
||||
// application --dest-namespace does not exist
|
||||
//
|
||||
// Verity application --dest-namespace is created
|
||||
// application sync successful
|
||||
// when application is deleted, --dest-namespace is not deleted
|
||||
//
|
||||
// application sync successful
|
||||
// when application is deleted, --dest-namespace is not deleted
|
||||
func TestNamespaceAutoCreation(t *testing.T) {
|
||||
SkipOnEnv(t, "OPENSHIFT")
|
||||
updatedNamespace := getNewNamespace(t)
|
||||
@@ -2320,5 +2323,58 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a cluster-scoped resource that is not referencing itself
|
||||
FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "e2e-test-clusterrole",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
fixture.TestingLabel: "true",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
And(func() {
|
||||
// Add a cluster-scoped resource that is referencing itself
|
||||
FailOnErr(KubeClientset.RbacV1().ClusterRoles().Create(context.Background(), &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "e2e-other-clusterrole",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", Name(), DeploymentNamespace()),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
fixture.TestingLabel: "true",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{}))
|
||||
}).
|
||||
Refresh(RefreshTypeNormal).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy)).
|
||||
When().
|
||||
Sync("--prune").
|
||||
And(func() {
|
||||
// The extra configmap must be pruned now, because it's tracked and does not exist in git
|
||||
cr, err := KubeClientset.RbacV1().ClusterRoles().Get(context.Background(), "e2e-other-clusterrole", metav1.GetOptions{})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "", cr.Name)
|
||||
}).
|
||||
Then().
|
||||
Expect(OperationPhaseIs(OperationSucceeded)).
|
||||
Expect(SyncStatusIs(SyncStatusCodeSynced)).
|
||||
Expect(HealthIs(health.HealthStatusHealthy))
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user