mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-24 11:38:46 +01:00
Compare commits
47 Commits
temp-cherr
...
commit-ser
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e71863944 | ||
|
|
cc1f9f53f1 | ||
|
|
030a7be7e2 | ||
|
|
8dbddb101a | ||
|
|
72c711e7f0 | ||
|
|
be080a5319 | ||
|
|
4b229c0484 | ||
|
|
87c853e872 | ||
|
|
cc68f018fe | ||
|
|
d9be098d9c | ||
|
|
6897c2e33f | ||
|
|
6a3cdb6ea5 | ||
|
|
deb4d2b01e | ||
|
|
a78b6287b1 | ||
|
|
bd322fe451 | ||
|
|
f2e4739178 | ||
|
|
2fe9a220dd | ||
|
|
2f51067e75 | ||
|
|
9741c065d8 | ||
|
|
90a148987d | ||
|
|
dfbfdbab11 | ||
|
|
eadc2a47dc | ||
|
|
eb1bb831d4 | ||
|
|
1bf56d8905 | ||
|
|
ed2fde1a8f | ||
|
|
35c12d9486 | ||
|
|
96d0226a49 | ||
|
|
8f0d3d0f6a | ||
|
|
4f6e4088ef | ||
|
|
71658c8897 | ||
|
|
fa9023a006 | ||
|
|
cdec7e2868 | ||
|
|
9f71ecbf5f | ||
|
|
6ace657e2a | ||
|
|
0a57d21c3d | ||
|
|
955858eaad | ||
|
|
e28aa2eb54 | ||
|
|
89f222b6a2 | ||
|
|
0fbbc0dda9 | ||
|
|
522d07a8d8 | ||
|
|
730363f14b | ||
|
|
523b0e6a78 | ||
|
|
975786629f | ||
|
|
52dbe514e0 | ||
|
|
51a7966b92 | ||
|
|
0d7f1f7053 | ||
|
|
b8e118ff7d |
38
.github/workflows/ci-build.yaml
vendored
38
.github/workflows/ci-build.yaml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
docs: ${{ steps.filter.outputs.docs_any_changed }}
|
||||
steps:
|
||||
- uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- uses: tj-actions/changed-files@4edd678ac3f81e2dc578756871e4d00c19191daf # v45.0.4
|
||||
- uses: tj-actions/changed-files@bab30c2299617f6615ec02a68b9a40d10bd21366 # v45.0.5
|
||||
id: filter
|
||||
with:
|
||||
# Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Download all Go modules
|
||||
@@ -78,11 +78,11 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Run golangci-lint
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -197,7 +197,7 @@ jobs:
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -217,7 +217,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -253,7 +253,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Create symlink in GOPATH
|
||||
@@ -311,7 +311,7 @@ jobs:
|
||||
node-version: '22.9.0'
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -351,7 +351,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -370,11 +370,11 @@ jobs:
|
||||
path: test-results
|
||||
- name: combine-go-coverage
|
||||
# We generate coverage reports for all Argo CD components, but only the applicationset-controller,
|
||||
# app-controller, and repo-server report contain coverage data. The other components currently don't shut down
|
||||
# gracefully, so no coverage data is produced. Once those components are fixed, we can add references to their
|
||||
# coverage output directories.
|
||||
# app-controller, repo-server, and commit-server report contain coverage data. The other components currently
|
||||
# don't shut down gracefully, so no coverage data is produced. Once those components are fixed, we can add
|
||||
# references to their coverage output directories.
|
||||
run: |
|
||||
go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller -o test-results/full-coverage.out
|
||||
go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller,e2e-code-coverage/commit-server -o test-results/full-coverage.out
|
||||
- name: Upload code coverage information to codecov.io
|
||||
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
|
||||
with:
|
||||
@@ -393,7 +393,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
uses: SonarSource/sonarqube-scan-action@13990a695682794b53148ff9f6a8b6e22e43955e # v2.2
|
||||
uses: SonarSource/sonarqube-scan-action@1b442ee39ac3fa7c2acdd410208dcb2bcfaae6c4 # v4.1.0
|
||||
if: env.sonar_secret != ''
|
||||
test-e2e:
|
||||
name: Run end-to-end tests
|
||||
@@ -432,7 +432,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: GH actions workaround - Kill XSP4 process
|
||||
@@ -451,7 +451,7 @@ jobs:
|
||||
sudo chmod go-r $HOME/.kube/config
|
||||
kubectl version
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
|
||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
# Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
|
||||
2
.github/workflows/image-reuse.yaml
vendored
2
.github/workflows/image-reuse.yaml
vendored
@@ -69,7 +69,7 @@ jobs:
|
||||
if: ${{ github.ref_type != 'tag'}}
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
|
||||
|
||||
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
run: git fetch --force --tags
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload SBOM
|
||||
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
|
||||
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
@@ -26,6 +26,13 @@ packages:
|
||||
github.com/argoproj/argo-cd/v2/applicationset/utils:
|
||||
interfaces:
|
||||
Renderer:
|
||||
github.com/argoproj/argo-cd/v2/commitserver/commit:
|
||||
interfaces:
|
||||
RepoClientFactory:
|
||||
github.com/argoproj/argo-cd/v2/commitserver/apiclient:
|
||||
interfaces:
|
||||
CommitServiceClient:
|
||||
Clientset:
|
||||
github.com/argoproj/argo-cd/v2/controller/cache:
|
||||
interfaces:
|
||||
LiveStateCache:
|
||||
|
||||
@@ -140,7 +140,8 @@ RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-dex && \
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-notifications && \
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-applicationset-controller && \
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-k8s-auth
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-k8s-auth && \
|
||||
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-commit-server
|
||||
|
||||
USER $ARGOCD_USER_ID
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
|
||||
1
Makefile
1
Makefile
@@ -472,6 +472,7 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local
|
||||
mkdir -p /tmp/coverage/repo-server
|
||||
mkdir -p /tmp/coverage/applicationset-controller
|
||||
mkdir -p /tmp/coverage/notification
|
||||
mkdir -p /tmp/coverage/commit-server
|
||||
# set paths for locally managed ssh known hosts and tls certs data
|
||||
ARGOCD_SSH_DATA_PATH=/tmp/argo-e2e/app/config/ssh \
|
||||
ARGOCD_TLS_DATA_PATH=/tmp/argo-e2e/app/config/tls \
|
||||
|
||||
1
Procfile
1
Procfile
@@ -4,6 +4,7 @@ dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/
|
||||
redis: hack/start-redis-with-password.sh
|
||||
repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/repo-server} 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_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-repo-server ARGOCD_GPG_ENABLED=${ARGOCD_GPG_ENABLED:-false} $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --otlp-address=${ARGOCD_OTLP_ADDRESS}"
|
||||
cmp-server: [ "$ARGOCD_E2E_TEST" = 'true' ] && exit 0 || [ "$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-cmp-server ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} $COMMAND --config-dir-path ./test/cmp --loglevel debug --otlp-address=${ARGOCD_OTLP_ADDRESS}"
|
||||
commit-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/commit-server} FORCE_LOG_COLORS=1 ARGOCD_BINARY_NAME=argocd-commit-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_COMMITSERVER_PORT:-8086}"
|
||||
ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start'
|
||||
git-server: test/fixture/testrepos/start-git.sh
|
||||
helm-registry: test/fixture/testrepos/start-helm-registry.sh
|
||||
|
||||
1
USERS.md
1
USERS.md
@@ -392,4 +392,5 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Yubo](https://www.yubo.live/)
|
||||
1. [ZDF](https://www.zdf.de/)
|
||||
1. [Zimpler](https://www.zimpler.com/)
|
||||
1. [ZipRecuiter](https://www.ziprecruiter.com/)
|
||||
1. [ZOZO](https://corp.zozo.com/)
|
||||
|
||||
@@ -1783,7 +1783,7 @@ func TestDeleteInCluster(t *testing.T) {
|
||||
Name: obj.Name,
|
||||
}, got)
|
||||
|
||||
assert.EqualError(t, err, fmt.Sprintf("applications.argoproj.io \"%s\" not found", obj.Name))
|
||||
assert.EqualError(t, err, fmt.Sprintf("applications.argoproj.io %q not found", obj.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1894,12 +1894,6 @@ func TestValidateGeneratedApplications(t *testing.T) {
|
||||
err := v1alpha1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Valid cluster
|
||||
myCluster := v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.default.svc",
|
||||
Name: "my-cluster",
|
||||
}
|
||||
|
||||
// Valid project
|
||||
myProject := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "namespace"},
|
||||
@@ -2066,18 +2060,12 @@ func TestValidateGeneratedApplications(t *testing.T) {
|
||||
objects := append([]runtime.Object{}, secret)
|
||||
kubeclientset := kubefake.NewSimpleClientset(objects...)
|
||||
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil)
|
||||
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
|
||||
myCluster,
|
||||
}}, nil)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
ArgoCDNamespace: "namespace",
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
@@ -2159,17 +2147,9 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
|
||||
}
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset()
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &project).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
|
||||
badCluster := v1alpha1.Cluster{Server: "https://bad-cluster", Name: "bad-cluster"}
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://bad-cluster").Return(&badCluster, nil)
|
||||
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
|
||||
goodCluster,
|
||||
}}, nil)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
@@ -2179,7 +2159,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Policy: v1alpha1.ApplicationsSyncPolicySync,
|
||||
ArgoCDNamespace: "argocd",
|
||||
@@ -2363,7 +2343,6 @@ func TestSetApplicationSetStatusCondition(t *testing.T) {
|
||||
}
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&testCase.appset).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).WithStatusSubresource(&testCase.appset).Build()
|
||||
@@ -2377,7 +2356,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) {
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -2433,16 +2412,28 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
|
||||
},
|
||||
}
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset()
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster",
|
||||
Namespace: "argocd",
|
||||
Labels: map[string]string{
|
||||
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
// Since this test requires the cluster to be an invalid destination, we
|
||||
// always return a cluster named 'my-cluster2' (different from app 'my-cluster', above)
|
||||
"name": []byte("good-cluster"),
|
||||
"server": []byte("https://good-cluster"),
|
||||
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
|
||||
},
|
||||
}
|
||||
|
||||
objects := append([]runtime.Object{}, secret)
|
||||
kubeclientset := kubefake.NewSimpleClientset(objects...)
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
|
||||
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
|
||||
goodCluster,
|
||||
}}, nil)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
@@ -2452,7 +2443,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
ArgoCDNamespace: "argocd",
|
||||
KubeClientset: kubeclientset,
|
||||
Policy: v1alpha1.ApplicationsSyncPolicySync,
|
||||
@@ -2595,16 +2586,28 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
|
||||
},
|
||||
}
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset()
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster",
|
||||
Namespace: "argocd",
|
||||
Labels: map[string]string{
|
||||
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
// Since this test requires the cluster to be an invalid destination, we
|
||||
// always return a cluster named 'my-cluster2' (different from app 'my-cluster', above)
|
||||
"name": []byte("good-cluster"),
|
||||
"server": []byte("https://good-cluster"),
|
||||
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
|
||||
},
|
||||
}
|
||||
|
||||
objects := append([]runtime.Object{}, secret)
|
||||
kubeclientset := kubefake.NewSimpleClientset(objects...)
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
|
||||
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
|
||||
goodCluster,
|
||||
}}, nil)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
@@ -2614,7 +2617,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
ArgoCDNamespace: "argocd",
|
||||
KubeClientset: kubeclientset,
|
||||
Policy: v1alpha1.ApplicationsSyncPolicySync,
|
||||
@@ -2689,7 +2692,7 @@ func TestDeletePerformedWithSyncPolicyCreateDelete(t *testing.T) {
|
||||
|
||||
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true)
|
||||
|
||||
assert.Empty(t, apps.Items)
|
||||
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
|
||||
}
|
||||
|
||||
func TestDeletePerformedWithSyncPolicySync(t *testing.T) {
|
||||
@@ -2697,7 +2700,7 @@ func TestDeletePerformedWithSyncPolicySync(t *testing.T) {
|
||||
|
||||
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true)
|
||||
|
||||
assert.Empty(t, apps.Items)
|
||||
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
|
||||
}
|
||||
|
||||
func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) {
|
||||
@@ -2705,7 +2708,7 @@ func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t
|
||||
|
||||
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, false)
|
||||
|
||||
assert.Empty(t, apps.Items)
|
||||
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
|
||||
}
|
||||
|
||||
func TestPolicies(t *testing.T) {
|
||||
@@ -2717,14 +2720,8 @@ func TestPolicies(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
|
||||
Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://kubernetes.default.svc"}}},
|
||||
}
|
||||
myCluster := v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.default.svc",
|
||||
Name: "my-cluster",
|
||||
}
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset()
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil)
|
||||
|
||||
for _, c := range []struct {
|
||||
name string
|
||||
@@ -2807,7 +2804,7 @@ func TestPolicies(t *testing.T) {
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
ArgoCDNamespace: "argocd",
|
||||
KubeClientset: kubeclientset,
|
||||
Policy: policy,
|
||||
@@ -2881,7 +2878,6 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
for _, cc := range []struct {
|
||||
name string
|
||||
@@ -2965,7 +2961,7 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) {
|
||||
Generators: map[string]generators.Generator{
|
||||
"List": generators.NewListGenerator(),
|
||||
},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -3714,14 +3710,13 @@ func TestBuildAppDependencyList(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -4381,14 +4376,13 @@ func TestBuildAppSyncMap(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -5326,7 +5320,6 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
@@ -5336,7 +5329,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -6075,7 +6068,6 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
@@ -6085,7 +6077,7 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -6286,7 +6278,6 @@ func TestUpdateResourceStatus(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
@@ -6296,7 +6287,7 @@ func TestUpdateResourceStatus(t *testing.T) {
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
@@ -6376,7 +6367,6 @@ func TestResourceStatusAreOrdered(t *testing.T) {
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
argoDBMock := dbmocks.ArgoDB{}
|
||||
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
|
||||
@@ -6386,7 +6376,7 @@ func TestResourceStatusAreOrdered(t *testing.T) {
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: &argoDBMock,
|
||||
ArgoDB: &dbmocks.ArgoDB{},
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
}
|
||||
|
||||
@@ -69,9 +69,11 @@ func GenerateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.App
|
||||
res = append(res, *app)
|
||||
}
|
||||
}
|
||||
|
||||
logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res))
|
||||
logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res)
|
||||
if log.IsLevelEnabled(log.DebugLevel) {
|
||||
logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res)
|
||||
} else {
|
||||
logCtx.Infof("generated %d applications", len(res))
|
||||
}
|
||||
}
|
||||
|
||||
return res, applicationSetReason, firstError
|
||||
|
||||
@@ -48,7 +48,7 @@ func NewClusterGenerator(c client.Client, ctx context.Context, clientset kuberne
|
||||
|
||||
// GetRequeueAfter never requeue the cluster generator because the `clusterSecretEventHandler` will requeue the appsets
|
||||
// when the cluster secrets change
|
||||
func (g *ClusterGenerator) GetRequeueAfter(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
func (g *ClusterGenerator) GetRequeueAfter(_ *argoappsetv1alpha1.ApplicationSetGenerator) time.Duration {
|
||||
return NoRequeueAfter
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ func (g *ClusterGenerator) GetTemplate(appSetGenerator *argoappsetv1alpha1.Appli
|
||||
}
|
||||
|
||||
func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator, appSet *argoappsetv1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) {
|
||||
logCtx := log.WithField("applicationset", appSet.GetName()).WithField("namespace", appSet.GetNamespace())
|
||||
if appSetGenerator == nil {
|
||||
return nil, EmptyAppSetGeneratorError
|
||||
}
|
||||
@@ -79,7 +80,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
clusterSecrets, err := g.getSecretsByClusterName(appSetGenerator)
|
||||
clusterSecrets, err := g.getSecretsByClusterName(logCtx, appSetGenerator)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting cluster secrets: %w", err)
|
||||
}
|
||||
@@ -89,7 +90,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
secretsFound := []corev1.Secret{}
|
||||
|
||||
isFlatMode := appSetGenerator.Clusters.FlatList
|
||||
log.Debug("Using flat mode = ", isFlatMode, " for cluster generator")
|
||||
logCtx.Debugf("Using flat mode = %t for cluster generator", isFlatMode)
|
||||
clustersParams := make([]map[string]interface{}, 0)
|
||||
|
||||
for _, cluster := range clustersFromArgoCD.Items {
|
||||
@@ -116,7 +117,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
res = append(res, params)
|
||||
}
|
||||
|
||||
log.WithField("cluster", "local cluster").Info("matched local cluster")
|
||||
logCtx.WithField("cluster", "local cluster").Info("matched local cluster")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +168,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
res = append(res, params)
|
||||
}
|
||||
|
||||
log.WithField("cluster", cluster.Name).Info("matched cluster secret")
|
||||
logCtx.WithField("cluster", cluster.Name).Debug("matched cluster secret")
|
||||
}
|
||||
|
||||
if isFlatMode {
|
||||
@@ -178,8 +179,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) (map[string]corev1.Secret, error) {
|
||||
// List all Clusters:
|
||||
func (g *ClusterGenerator) getSecretsByClusterName(log *log.Entry, appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) (map[string]corev1.Secret, error) {
|
||||
clusterSecretList := &corev1.SecretList{}
|
||||
|
||||
selector := metav1.AddLabelToSelector(&appSetGenerator.Clusters.Selector, common.LabelKeySecretType, common.LabelValueSecretTypeCluster)
|
||||
@@ -191,7 +191,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1
|
||||
if err := g.Client.List(context.Background(), clusterSecretList, client.MatchingLabelsSelector{Selector: secretSelector}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("clusters matching labels", "count", len(clusterSecretList.Items))
|
||||
log.Debugf("clusters matching labels: %d", len(clusterSecretList.Items))
|
||||
|
||||
res := map[string]corev1.Secret{}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/bradleyfalzon/ghinstallation/v2"
|
||||
"github.com/google/go-github/v63/github"
|
||||
"github.com/google/go-github/v66/github"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth"
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ type BitbucketCloudPullRequest struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Source BitbucketCloudPullRequestSource `json:"source"`
|
||||
Author string `json:"author"`
|
||||
Author BitbucketCloudPullRequestAuthor `json:"author"`
|
||||
}
|
||||
|
||||
type BitbucketCloudPullRequestSource struct {
|
||||
@@ -35,6 +35,11 @@ type BitbucketCloudPullRequestSourceCommit struct {
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
// Also have display_name and uuid, but don't plan to use them.
|
||||
type BitbucketCloudPullRequestAuthor struct {
|
||||
Nickname string `json:"nickname"`
|
||||
}
|
||||
|
||||
type PullRequestResponse struct {
|
||||
Page int32 `json:"page"`
|
||||
Size int32 `json:"size"`
|
||||
@@ -134,7 +139,7 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error)
|
||||
Title: pull.Title,
|
||||
Branch: pull.Source.Branch.Name,
|
||||
HeadSHA: pull.Source.Commit.Hash,
|
||||
Author: pull.Author,
|
||||
Author: pull.Author.Nickname,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request)
|
||||
"hash": "1a8dd249c04a"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`)
|
||||
@@ -155,7 +157,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
|
||||
"hash": "1a8dd249c04a"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
@@ -169,7 +173,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
|
||||
"hash": "4cf807e67a6d"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`, r.Host))
|
||||
@@ -192,7 +198,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
|
||||
"hash": "6344d9623e3b"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`, r.Host))
|
||||
@@ -340,7 +348,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
"hash": "1a8dd249c04a"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 200,
|
||||
@@ -354,7 +364,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
"hash": "4cf807e67a6d"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`, r.Host))
|
||||
@@ -377,7 +389,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
|
||||
"hash": "6344d9623e3b"
|
||||
}
|
||||
},
|
||||
"author": "testName"
|
||||
"author": {
|
||||
"nickname": "testName"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`, r.Host))
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-github/v63/github"
|
||||
"github.com/google/go-github/v66/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package pull_request
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v63/github"
|
||||
"github.com/google/go-github/v66/github"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-github/v63/github"
|
||||
"github.com/google/go-github/v66/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
||||
@@ -51,9 +51,12 @@ const (
|
||||
// if we used destination name we infer the server url
|
||||
// if we used both name and server then we return an invalid spec error
|
||||
func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination, clientset kubernetes.Interface, argoCDNamespace string) error {
|
||||
if dest.IsServerInferred() && dest.IsNameInferred() {
|
||||
return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server)
|
||||
}
|
||||
if dest.Name != "" {
|
||||
if dest.Server == "" {
|
||||
server, err := getDestinationServer(ctx, dest.Name, clientset, argoCDNamespace)
|
||||
server, err := getDestinationBy(ctx, dest.Name, clientset, argoCDNamespace, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find destination server: %w", err)
|
||||
}
|
||||
@@ -61,14 +64,25 @@ func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination
|
||||
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name)
|
||||
}
|
||||
dest.SetInferredServer(server)
|
||||
} else if !dest.IsServerInferred() {
|
||||
} else if !dest.IsServerInferred() && !dest.IsNameInferred() {
|
||||
return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server)
|
||||
}
|
||||
} else if dest.Server != "" {
|
||||
if dest.Name == "" {
|
||||
serverName, err := getDestinationBy(ctx, dest.Server, clientset, argoCDNamespace, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find destination server: %w", err)
|
||||
}
|
||||
if serverName == "" {
|
||||
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server)
|
||||
}
|
||||
dest.SetInferredName(serverName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDestinationServer(ctx context.Context, clusterName string, clientset kubernetes.Interface, argoCDNamespace string) (string, error) {
|
||||
func getDestinationBy(ctx context.Context, cluster string, clientset kubernetes.Interface, argoCDNamespace string, byName bool) (string, error) {
|
||||
// settingsMgr := settings.NewSettingsManager(context.TODO(), clientset, namespace)
|
||||
// argoDB := db.NewDB(namespace, settingsMgr, clientset)
|
||||
// clusterList, err := argoDB.ListClusters(ctx)
|
||||
@@ -78,14 +92,17 @@ func getDestinationServer(ctx context.Context, clusterName string, clientset kub
|
||||
}
|
||||
var servers []string
|
||||
for _, c := range clusterList.Items {
|
||||
if c.Name == clusterName {
|
||||
if byName && c.Name == cluster {
|
||||
servers = append(servers, c.Server)
|
||||
}
|
||||
if !byName && c.Server == cluster {
|
||||
servers = append(servers, c.Name)
|
||||
}
|
||||
}
|
||||
if len(servers) > 1 {
|
||||
return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers)
|
||||
} else if len(servers) == 0 {
|
||||
return "", fmt.Errorf("there are no clusters with this name: %s", clusterName)
|
||||
return "", fmt.Errorf("there are no clusters with this name: %s", cluster)
|
||||
}
|
||||
return servers[0], nil
|
||||
}
|
||||
|
||||
@@ -93,7 +93,12 @@ func TestValidateDestination(t *testing.T) {
|
||||
Namespace: "default",
|
||||
}
|
||||
|
||||
appCond := ValidateDestination(context.Background(), &dest, nil, fakeNamespace)
|
||||
secret := createClusterSecret("my-secret", "minikube", "https://127.0.0.1:6443")
|
||||
objects := []runtime.Object{}
|
||||
objects = append(objects, secret)
|
||||
kubeclientset := fake.NewSimpleClientset(objects...)
|
||||
|
||||
appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace)
|
||||
require.NoError(t, appCond)
|
||||
assert.False(t, dest.IsServerInferred())
|
||||
})
|
||||
|
||||
132
assets/swagger.json
generated
132
assets/swagger.json
generated
@@ -4691,6 +4691,12 @@
|
||||
"clusterSettings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"additionalUrls": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"appLabelKey": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6851,6 +6857,9 @@
|
||||
"source": {
|
||||
"$ref": "#/definitions/v1alpha1ApplicationSource"
|
||||
},
|
||||
"sourceHydrator": {
|
||||
"$ref": "#/definitions/v1alpha1SourceHydrator"
|
||||
},
|
||||
"sources": {
|
||||
"type": "array",
|
||||
"title": "Sources is a reference to the location of the application's manifests or chart",
|
||||
@@ -6908,6 +6917,9 @@
|
||||
"$ref": "#/definitions/applicationv1alpha1ResourceStatus"
|
||||
}
|
||||
},
|
||||
"sourceHydrator": {
|
||||
"$ref": "#/definitions/v1alpha1SourceHydratorStatus"
|
||||
},
|
||||
"sourceType": {
|
||||
"type": "string",
|
||||
"title": "SourceType specifies the type of this application"
|
||||
@@ -7335,6 +7347,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1DrySource": {
|
||||
"description": "DrySource specifies a location for dry \"don't repeat yourself\" manifest source information.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"title": "Path is a directory path within the Git repository where the manifests are located"
|
||||
},
|
||||
"repoURL": {
|
||||
"type": "string",
|
||||
"title": "RepoURL is the URL to the git repository that contains the application manifests"
|
||||
},
|
||||
"targetRevision": {
|
||||
"type": "string",
|
||||
"title": "TargetRevision defines the revision of the source to hydrate"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1DuckTypeGenerator": {
|
||||
"description": "DuckType defines a generator to match against clusters registered with ArgoCD.",
|
||||
"type": "object",
|
||||
@@ -7505,6 +7535,9 @@
|
||||
"type": "object",
|
||||
"title": "HealthStatus contains information about the currently observed health state of an application or resource",
|
||||
"properties": {
|
||||
"lastTransitionTime": {
|
||||
"$ref": "#/definitions/v1Time"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"title": "Message is a human-readable informational message describing the health status"
|
||||
@@ -7586,6 +7619,47 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1HydrateOperation": {
|
||||
"type": "object",
|
||||
"title": "HydrateOperation contains information about the most recent hydrate operation",
|
||||
"properties": {
|
||||
"drySHA": {
|
||||
"type": "string",
|
||||
"title": "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation"
|
||||
},
|
||||
"finishedAt": {
|
||||
"$ref": "#/definitions/v1Time"
|
||||
},
|
||||
"hydratedSHA": {
|
||||
"type": "string",
|
||||
"title": "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"title": "Message contains a message describing the current status of the hydrate operation"
|
||||
},
|
||||
"phase": {
|
||||
"type": "string",
|
||||
"title": "Phase indicates the status of the hydrate operation"
|
||||
},
|
||||
"sourceHydrator": {
|
||||
"$ref": "#/definitions/v1alpha1SourceHydrator"
|
||||
},
|
||||
"startedAt": {
|
||||
"$ref": "#/definitions/v1Time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1HydrateTo": {
|
||||
"description": "HydrateTo specifies a location to which hydrated manifests should be pushed as a \"staging area\" before being moved to\nthe SyncSource. The RepoURL and Path are assumed based on the associated SyncSource config in the SourceHydrator.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"targetBranch": {
|
||||
"type": "string",
|
||||
"title": "TargetBranch is the branch to which hydrated manifests should be committed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1Info": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -9193,6 +9267,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SourceHydrator": {
|
||||
"description": "SourceHydrator specifies a dry \"don't repeat yourself\" source for manifests, a sync source from which to sync\nhydrated manifests, and an optional hydrateTo location to act as a \"staging\" aread for hydrated manifests.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"drySource": {
|
||||
"$ref": "#/definitions/v1alpha1DrySource"
|
||||
},
|
||||
"hydrateTo": {
|
||||
"$ref": "#/definitions/v1alpha1HydrateTo"
|
||||
},
|
||||
"syncSource": {
|
||||
"$ref": "#/definitions/v1alpha1SyncSource"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SourceHydratorStatus": {
|
||||
"type": "object",
|
||||
"title": "SourceHydratorStatus contains information about the current state of source hydration",
|
||||
"properties": {
|
||||
"currentOperation": {
|
||||
"$ref": "#/definitions/v1alpha1HydrateOperation"
|
||||
},
|
||||
"lastSuccessfulOperation": {
|
||||
"$ref": "#/definitions/v1alpha1SuccessfulHydrateOperation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SuccessfulHydrateOperation": {
|
||||
"type": "object",
|
||||
"title": "SuccessfulHydrateOperation contains information about the most recent successful hydrate operation",
|
||||
"properties": {
|
||||
"drySHA": {
|
||||
"type": "string",
|
||||
"title": "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation"
|
||||
},
|
||||
"hydratedSHA": {
|
||||
"type": "string",
|
||||
"title": "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation"
|
||||
},
|
||||
"sourceHydrator": {
|
||||
"$ref": "#/definitions/v1alpha1SourceHydrator"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SyncOperation": {
|
||||
"description": "SyncOperation contains details about a sync operation.",
|
||||
"type": "object",
|
||||
@@ -9352,6 +9470,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SyncSource": {
|
||||
"description": "SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the\nassociated DrySource config in the SourceHydrator.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "Path is a directory path within the git repository where hydrated manifests should be committed to and synced\nfrom. If hydrateTo is set, this is just the path from which hydrated manifests will be synced.",
|
||||
"type": "string"
|
||||
},
|
||||
"targetBranch": {
|
||||
"type": "string",
|
||||
"title": "TargetBranch is the branch to which hydrated manifests should be committed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1alpha1SyncStatus": {
|
||||
"type": "object",
|
||||
"title": "SyncStatus contains information about the currently observed live and desired states of an application",
|
||||
|
||||
@@ -62,6 +62,7 @@ func NewCommand() *cobra.Command {
|
||||
selfHealBackoffTimeoutSeconds int
|
||||
selfHealBackoffFactor int
|
||||
selfHealBackoffCapSeconds int
|
||||
syncTimeout int
|
||||
statusProcessors int
|
||||
operationProcessors int
|
||||
glogLevel int
|
||||
@@ -189,6 +190,7 @@ func NewCommand() *cobra.Command {
|
||||
time.Duration(appResyncJitter)*time.Second,
|
||||
time.Duration(selfHealTimeoutSeconds)*time.Second,
|
||||
selfHealBackoff,
|
||||
time.Duration(syncTimeout)*time.Second,
|
||||
time.Duration(repoErrorGracePeriod)*time.Second,
|
||||
metricsPort,
|
||||
metricsCacheExpiration,
|
||||
@@ -205,7 +207,7 @@ func NewCommand() *cobra.Command {
|
||||
enableK8sEvent,
|
||||
)
|
||||
errors.CheckError(err)
|
||||
cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer())
|
||||
cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer(), nil)
|
||||
|
||||
stats.RegisterStackDumper()
|
||||
stats.StartStatsTicker(10 * time.Minute)
|
||||
@@ -256,6 +258,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().IntVar(&selfHealBackoffTimeoutSeconds, "self-heal-backoff-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS", 2, 0, math.MaxInt32), "Specifies initial timeout of exponential backoff between self heal attempts")
|
||||
command.Flags().IntVar(&selfHealBackoffFactor, "self-heal-backoff-factor", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR", 3, 0, math.MaxInt32), "Specifies factor of exponential timeout between application self heal attempts")
|
||||
command.Flags().IntVar(&selfHealBackoffCapSeconds, "self-heal-backoff-cap-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS", 300, 0, math.MaxInt32), "Specifies max timeout of exponential backoff between application self heal attempts")
|
||||
command.Flags().IntVar(&syncTimeout, "sync-timeout", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT", 0, 0, math.MaxInt32), "Specifies the timeout after which a sync would be terminated. 0 means no timeout (default 0).")
|
||||
command.Flags().Int64Var(&kubectlParallelismLimit, "kubectl-parallelism-limit", env.ParseInt64FromEnv("ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT", 20, 0, math.MaxInt64), "Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit.")
|
||||
command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server")
|
||||
command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server")
|
||||
|
||||
117
cmd/argocd-commit-server/commands/argocd_commit_server.go
Normal file
117
cmd/argocd-commit-server/commands/argocd_commit_server.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
|
||||
cmdutil "github.com/argoproj/argo-cd/v2/cmd/util"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/metrics"
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
"github.com/argoproj/argo-cd/v2/util/askpass"
|
||||
"github.com/argoproj/argo-cd/v2/util/cli"
|
||||
"github.com/argoproj/argo-cd/v2/util/env"
|
||||
"github.com/argoproj/argo-cd/v2/util/errors"
|
||||
"github.com/argoproj/argo-cd/v2/util/healthz"
|
||||
ioutil "github.com/argoproj/argo-cd/v2/util/io"
|
||||
)
|
||||
|
||||
// NewCommand returns a new instance of an argocd-commit-server command
|
||||
func NewCommand() *cobra.Command {
|
||||
var (
|
||||
listenHost string
|
||||
listenPort int
|
||||
metricsPort int
|
||||
metricsHost string
|
||||
)
|
||||
command := &cobra.Command{
|
||||
Use: "argocd-commit-server",
|
||||
Short: "Run Argo CD Commit Server",
|
||||
Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
vers := common.GetVersion()
|
||||
vers.LogStartupInfo(
|
||||
"Argo CD Commit Server",
|
||||
map[string]any{
|
||||
"port": listenPort,
|
||||
},
|
||||
)
|
||||
|
||||
cli.SetLogFormat(cmdutil.LogFormat)
|
||||
cli.SetLogLevel(cmdutil.LogLevel)
|
||||
|
||||
metricsServer := metrics.NewMetricsServer()
|
||||
http.Handle("/metrics", metricsServer.GetHandler())
|
||||
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }()
|
||||
|
||||
askPassServer := askpass.NewServer(askpass.CommitServerSocketPath)
|
||||
go func() { errors.CheckError(askPassServer.Run()) }()
|
||||
|
||||
server := commitserver.NewServer(askPassServer, metricsServer)
|
||||
grpc := server.CreateGRPC()
|
||||
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", listenHost, listenPort))
|
||||
errors.CheckError(err)
|
||||
|
||||
healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error {
|
||||
if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
|
||||
// connect to itself to make sure commit server is able to serve connection
|
||||
// used by liveness probe to auto restart commit server
|
||||
conn, err := apiclient.NewConnection(fmt.Sprintf("localhost:%d", listenPort))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ioutil.Close(conn)
|
||||
client := grpc_health_v1.NewHealthClient(conn)
|
||||
res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.Status != grpc_health_v1.HealthCheckResponse_SERVING {
|
||||
return fmt.Errorf("grpc health check status is '%v'", res.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Graceful shutdown code adapted from here: https://gist.github.com/embano1/e0bf49d24f1cdd07cffad93097c04f0a
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
s := <-sigCh
|
||||
log.Printf("got signal %v, attempting graceful shutdown", s)
|
||||
grpc.GracefulStop()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
log.Println("starting grpc server")
|
||||
err = grpc.Serve(listener)
|
||||
errors.CheckError(err)
|
||||
wg.Wait()
|
||||
log.Println("clean shutdown")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS", common.DefaultAddressCommitServer), "Listen on given address for incoming connections")
|
||||
command.Flags().IntVar(&listenPort, "port", common.DefaultPortCommitServer, "Listen on given port for incoming connections")
|
||||
command.Flags().StringVar(&metricsHost, "metrics-address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS", common.DefaultAddressCommitServerMetrics), "Listen on given address for metrics")
|
||||
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortCommitServerMetrics, "Start metrics server on given port")
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/askpass"
|
||||
"github.com/argoproj/argo-cd/v2/util/askpass"
|
||||
"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/io"
|
||||
|
||||
@@ -23,10 +23,10 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/askpass"
|
||||
reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/metrics"
|
||||
"github.com/argoproj/argo-cd/v2/reposerver/repository"
|
||||
"github.com/argoproj/argo-cd/v2/util/askpass"
|
||||
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
|
||||
"github.com/argoproj/argo-cd/v2/util/cli"
|
||||
"github.com/argoproj/argo-cd/v2/util/env"
|
||||
@@ -130,7 +130,7 @@ func NewCommand() *cobra.Command {
|
||||
|
||||
askPassServer := askpass.NewServer(askpass.SocketPath)
|
||||
metricsServer := metrics.NewMetricsServer()
|
||||
cacheutil.CollectMetrics(redisClient, metricsServer)
|
||||
cacheutil.CollectMetrics(redisClient, metricsServer, nil)
|
||||
server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{
|
||||
ParallelismLimit: parallelismLimit,
|
||||
PauseGenerationAfterFailedGenerationAttempts: pauseGenerationAfterFailedGenerationAttempts,
|
||||
|
||||
@@ -258,22 +258,25 @@ func NewCommand() *cobra.Command {
|
||||
stats.RegisterHeapDumper("memprofile")
|
||||
argocd := server.NewServer(ctx, argoCDOpts, appsetOpts)
|
||||
argocd.Init(ctx)
|
||||
lns, err := argocd.Listen()
|
||||
errors.CheckError(err)
|
||||
for {
|
||||
var closer func()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
serverCtx, cancel := context.WithCancel(ctx)
|
||||
lns, err := argocd.Listen()
|
||||
errors.CheckError(err)
|
||||
if otlpAddress != "" {
|
||||
closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs)
|
||||
closer, err = traceutil.InitTracer(serverCtx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize tracing: %v", err)
|
||||
}
|
||||
}
|
||||
argocd.Run(ctx, lns)
|
||||
cancel()
|
||||
argocd.Run(serverCtx, lns)
|
||||
if closer != nil {
|
||||
closer()
|
||||
}
|
||||
cancel()
|
||||
if argocd.TerminateRequested() {
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
Example: templates.Examples(`
|
||||
|
||||
@@ -680,7 +680,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command
|
||||
command.PersistentFlags().StringVar(&pathOpts.LoadingRules.ExplicitPath, pathOpts.ExplicitFileFlag, pathOpts.LoadingRules.ExplicitPath, "use a particular kubeconfig file")
|
||||
command.Flags().StringVar(&bearerToken, "bearer-token", "", "Authentication token that should be used to access K8S API server")
|
||||
command.Flags().BoolVar(&generateToken, "generate-bearer-token", false, "Generate authentication token that should be used to access K8S API server")
|
||||
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "argocd-manager", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be used", clusterauth.ArgoCDManagerServiceAccount))
|
||||
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "argocd-manager", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default %q SA will be used", clusterauth.ArgoCDManagerServiceAccount))
|
||||
command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace")
|
||||
command.Flags().StringVarP(&outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml")
|
||||
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
|
||||
|
||||
@@ -50,13 +50,13 @@ func NewGenProjectSpecCommand() *cobra.Command {
|
||||
Short: "Generate declarative config for a project",
|
||||
Example: templates.Examples(`
|
||||
# Generate a YAML configuration for a project named "myproject"
|
||||
argocd admin projects generate-spec myproject
|
||||
argocd admin proj generate-spec myproject
|
||||
|
||||
# Generate a JSON configuration for a project named "anotherproject" and specify an output file
|
||||
argocd admin projects generate-spec anotherproject --output json --file config.json
|
||||
argocd admin proj generate-spec anotherproject --output json --file config.json
|
||||
|
||||
# Generate a YAML configuration for a project named "someproject" and write it back to the input file
|
||||
argocd admin projects generate-spec someproject --inline
|
||||
argocd admin proj generate-spec someproject --inline
|
||||
`),
|
||||
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
@@ -155,10 +155,10 @@ func NewUpdatePolicyRuleCommand() *cobra.Command {
|
||||
Use: "update-role-policy PROJECT_GLOB MODIFICATION ACTION",
|
||||
Short: "Implement bulk project role update. Useful to back-fill existing project policies or remove obsolete actions.",
|
||||
Example: ` # Add policy that allows executing any action (action/*) to roles which name matches to *deployer* in all projects
|
||||
argocd admin projects update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow
|
||||
argocd admin proj update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow
|
||||
|
||||
# Remove policy that which manages running (action/*) from all roles which name matches *deployer* in all projects
|
||||
argocd admin projects update-role-policy '*' remove override --role '*deployer*'
|
||||
argocd admin proj update-role-policy '*' remove override --role '*deployer*'
|
||||
`,
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
ctx := c.Context()
|
||||
|
||||
@@ -192,7 +192,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
|
||||
}
|
||||
command.PersistentFlags().StringVar(&pathOpts.LoadingRules.ExplicitPath, pathOpts.ExplicitFileFlag, pathOpts.LoadingRules.ExplicitPath, "use a particular kubeconfig file")
|
||||
command.Flags().BoolVar(&clusterOpts.Upsert, "upsert", false, "Override an existing cluster with the same name even if the spec differs")
|
||||
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be created", clusterauth.ArgoCDManagerServiceAccount))
|
||||
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default %q SA will be created", clusterauth.ArgoCDManagerServiceAccount))
|
||||
command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace")
|
||||
command.Flags().BoolVarP(&skipConfirmation, "yes", "y", false, "Skip explicit confirmation")
|
||||
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands"
|
||||
applicationset "github.com/argoproj/argo-cd/v2/cmd/argocd-applicationset-controller/commands"
|
||||
cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands"
|
||||
commitserver "github.com/argoproj/argo-cd/v2/cmd/argocd-commit-server/commands"
|
||||
dex "github.com/argoproj/argo-cd/v2/cmd/argocd-dex/commands"
|
||||
gitaskpass "github.com/argoproj/argo-cd/v2/cmd/argocd-git-ask-pass/commands"
|
||||
k8sauth "github.com/argoproj/argo-cd/v2/cmd/argocd-k8s-auth/commands"
|
||||
@@ -46,6 +47,8 @@ func main() {
|
||||
case "argocd-cmp-server":
|
||||
command = cmpserver.NewCommand()
|
||||
isCLI = true
|
||||
case "argocd-commit-server":
|
||||
command = commitserver.NewCommand()
|
||||
case "argocd-dex":
|
||||
command = dex.NewCommand()
|
||||
case "argocd-notifications":
|
||||
|
||||
49
commitserver/apiclient/clientset.go
Normal file
49
commitserver/apiclient/clientset.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package apiclient
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/io"
|
||||
)
|
||||
|
||||
// Clientset represents commit server api clients
|
||||
type Clientset interface {
|
||||
NewCommitServerClient() (io.Closer, CommitServiceClient, error)
|
||||
}
|
||||
|
||||
type clientSet struct {
|
||||
address string
|
||||
}
|
||||
|
||||
// NewCommitServerClient creates new instance of commit server client
|
||||
func (c *clientSet) NewCommitServerClient() (io.Closer, CommitServiceClient, error) {
|
||||
conn, err := NewConnection(c.address)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to open a new connection to commit server: %w", err)
|
||||
}
|
||||
return conn, NewCommitServiceClient(conn), nil
|
||||
}
|
||||
|
||||
// NewConnection creates new connection to commit server
|
||||
func NewConnection(address string) (*grpc.ClientConn, error) {
|
||||
var opts []grpc.DialOption
|
||||
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// TODO: switch to grpc.NewClient.
|
||||
// nolint:staticcheck
|
||||
conn, err := grpc.Dial(address, opts...)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to connect to commit service with address %s", address)
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// NewCommitServerClientset creates new instance of commit server Clientset
|
||||
func NewCommitServerClientset(address string) Clientset {
|
||||
return &clientSet{address: address}
|
||||
}
|
||||
1382
commitserver/apiclient/commit.pb.go
generated
Normal file
1382
commitserver/apiclient/commit.pb.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
68
commitserver/apiclient/mocks/Clientset.go
generated
Normal file
68
commitserver/apiclient/mocks/Clientset.go
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
io "github.com/argoproj/argo-cd/v2/util/io"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// Clientset is an autogenerated mock type for the Clientset type
|
||||
type Clientset struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// NewCommitServerClient provides a mock function with given fields:
|
||||
func (_m *Clientset) NewCommitServerClient() (io.Closer, apiclient.CommitServiceClient, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for NewCommitServerClient")
|
||||
}
|
||||
|
||||
var r0 io.Closer
|
||||
var r1 apiclient.CommitServiceClient
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func() (io.Closer, apiclient.CommitServiceClient, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() io.Closer); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(io.Closer)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() apiclient.CommitServiceClient); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(apiclient.CommitServiceClient)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func() error); ok {
|
||||
r2 = rf()
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// NewClientset creates a new instance of Clientset. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewClientset(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *Clientset {
|
||||
mock := &Clientset{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
69
commitserver/apiclient/mocks/CommitServiceClient.go
generated
Normal file
69
commitserver/apiclient/mocks/CommitServiceClient.go
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// CommitServiceClient is an autogenerated mock type for the CommitServiceClient type
|
||||
type CommitServiceClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CommitHydratedManifests provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *CommitServiceClient) CommitHydratedManifests(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CommitHydratedManifests")
|
||||
}
|
||||
|
||||
var r0 *apiclient.CommitHydratedManifestsResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) *apiclient.CommitHydratedManifestsResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*apiclient.CommitHydratedManifestsResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// NewCommitServiceClient creates a new instance of CommitServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewCommitServiceClient(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *CommitServiceClient {
|
||||
mock := &CommitServiceClient{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
225
commitserver/commit/commit.go
Normal file
225
commitserver/commit/commit.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/metrics"
|
||||
"github.com/argoproj/argo-cd/v2/util/git"
|
||||
"github.com/argoproj/argo-cd/v2/util/io/files"
|
||||
)
|
||||
|
||||
// Service is the service that handles commit requests.
|
||||
type Service struct {
|
||||
gitCredsStore git.CredsStore
|
||||
metricsServer *metrics.Server
|
||||
repoClientFactory RepoClientFactory
|
||||
}
|
||||
|
||||
// NewService returns a new instance of the commit service.
|
||||
func NewService(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *Service {
|
||||
return &Service{
|
||||
gitCredsStore: gitCredsStore,
|
||||
metricsServer: metricsServer,
|
||||
repoClientFactory: NewRepoClientFactory(gitCredsStore, metricsServer),
|
||||
}
|
||||
}
|
||||
|
||||
// CommitHydratedManifests handles a commit request. It clones the repository, checks out the sync branch, checks out
|
||||
// the target branch, clears the repository contents, writes the manifests to the repository, commits the changes, and
|
||||
// pushes the changes. It returns the hydrated revision SHA and an error if one occurred.
|
||||
func (s *Service) CommitHydratedManifests(ctx context.Context, r *apiclient.CommitHydratedManifestsRequest) (*apiclient.CommitHydratedManifestsResponse, error) {
|
||||
// This method is intentionally short. It's a wrapper around handleCommitRequest that adds metrics and logging.
|
||||
// Keep logic here minimal and put most of the logic in handleCommitRequest.
|
||||
startTime := time.Now()
|
||||
|
||||
// We validate for a nil repo in handleCommitRequest, but we need to check for a nil repo here to get the repo URL
|
||||
// for metrics.
|
||||
var repoURL string
|
||||
if r.Repo != nil {
|
||||
repoURL = r.Repo.Repo
|
||||
}
|
||||
|
||||
var err error
|
||||
s.metricsServer.IncPendingCommitRequest(repoURL)
|
||||
defer func() {
|
||||
s.metricsServer.DecPendingCommitRequest(repoURL)
|
||||
commitResponseType := metrics.CommitResponseTypeSuccess
|
||||
if err != nil {
|
||||
commitResponseType = metrics.CommitResponseTypeFailure
|
||||
}
|
||||
s.metricsServer.IncCommitRequest(repoURL, commitResponseType)
|
||||
s.metricsServer.ObserveCommitRequestDuration(repoURL, commitResponseType, time.Since(startTime))
|
||||
}()
|
||||
|
||||
logCtx := log.WithFields(log.Fields{"branch": r.TargetBranch, "drySHA": r.DrySha})
|
||||
|
||||
out, sha, err := s.handleCommitRequest(logCtx, r)
|
||||
if err != nil {
|
||||
logCtx.WithError(err).WithField("output", out).Error("failed to handle commit request")
|
||||
|
||||
// No need to wrap this error, sufficient context is build in handleCommitRequest.
|
||||
return &apiclient.CommitHydratedManifestsResponse{}, err
|
||||
}
|
||||
|
||||
logCtx.Info("Successfully handled commit request")
|
||||
return &apiclient.CommitHydratedManifestsResponse{
|
||||
HydratedSha: sha,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// handleCommitRequest handles the commit request. It clones the repository, checks out the sync branch, checks out the
|
||||
// target branch, clears the repository contents, writes the manifests to the repository, commits the changes, and pushes
|
||||
// the changes. It returns the output of the git commands and an error if one occurred.
|
||||
func (s *Service) handleCommitRequest(logCtx *log.Entry, r *apiclient.CommitHydratedManifestsRequest) (string, string, error) {
|
||||
if r.Repo == nil {
|
||||
return "", "", fmt.Errorf("repo is required")
|
||||
}
|
||||
if r.Repo.Repo == "" {
|
||||
return "", "", fmt.Errorf("repo URL is required")
|
||||
}
|
||||
if r.TargetBranch == "" {
|
||||
return "", "", fmt.Errorf("target branch is required")
|
||||
}
|
||||
if r.SyncBranch == "" {
|
||||
return "", "", fmt.Errorf("sync branch is required")
|
||||
}
|
||||
|
||||
logCtx = logCtx.WithField("repo", r.Repo.Repo)
|
||||
logCtx.Debug("Initiating git client")
|
||||
gitClient, dirPath, cleanup, err := s.initGitClient(logCtx, r)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to init git client: %w", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
logCtx.Debugf("Checking out sync branch %s", r.SyncBranch)
|
||||
var out string
|
||||
out, err = gitClient.CheckoutOrOrphan(r.SyncBranch, false)
|
||||
if err != nil {
|
||||
return out, "", fmt.Errorf("failed to checkout sync branch: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debugf("Checking out target branch %s", r.TargetBranch)
|
||||
out, err = gitClient.CheckoutOrNew(r.TargetBranch, r.SyncBranch, false)
|
||||
if err != nil {
|
||||
return out, "", fmt.Errorf("failed to checkout target branch: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debug("Clearing repo contents")
|
||||
out, err = gitClient.RemoveContents()
|
||||
if err != nil {
|
||||
return out, "", fmt.Errorf("failed to clear repo: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debug("Writing manifests")
|
||||
err = WriteForPaths(dirPath, r.Repo.Repo, r.DrySha, r.Paths)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to write manifests: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debug("Committing and pushing changes")
|
||||
out, err = gitClient.CommitAndPush(r.TargetBranch, r.CommitMessage)
|
||||
if err != nil {
|
||||
return out, "", fmt.Errorf("failed to commit and push: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debug("Getting commit SHA")
|
||||
sha, err := gitClient.CommitSHA()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to get commit SHA: %w", err)
|
||||
}
|
||||
|
||||
return "", sha, nil
|
||||
}
|
||||
|
||||
// initGitClient initializes a git client for the given repository and returns the client, the path to the directory where
|
||||
// the repository is cloned, a cleanup function that should be called when the directory is no longer needed, and an error
|
||||
// if one occurred.
|
||||
func (s *Service) initGitClient(logCtx *log.Entry, r *apiclient.CommitHydratedManifestsRequest) (git.Client, string, func(), error) {
|
||||
dirPath, err := files.CreateTempDir("/tmp/_commit-service")
|
||||
if err != nil {
|
||||
return nil, "", nil, fmt.Errorf("failed to create temp dir: %w", err)
|
||||
}
|
||||
// Call cleanupOrLog in this function if an error occurs to ensure the temp dir is cleaned up.
|
||||
cleanupOrLog := func() {
|
||||
err := os.RemoveAll(dirPath)
|
||||
if err != nil {
|
||||
logCtx.WithError(err).Error("failed to cleanup temp dir")
|
||||
}
|
||||
}
|
||||
|
||||
gitClient, err := s.repoClientFactory.NewClient(r.Repo, dirPath)
|
||||
if err != nil {
|
||||
cleanupOrLog()
|
||||
return nil, "", nil, fmt.Errorf("failed to create git client: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debugf("Initializing repo %s", r.Repo.Repo)
|
||||
err = gitClient.Init()
|
||||
if err != nil {
|
||||
cleanupOrLog()
|
||||
return nil, "", nil, fmt.Errorf("failed to init git client: %w", err)
|
||||
}
|
||||
|
||||
logCtx.Debugf("Fetching repo %s", r.Repo.Repo)
|
||||
err = gitClient.Fetch("")
|
||||
if err != nil {
|
||||
cleanupOrLog()
|
||||
return nil, "", nil, fmt.Errorf("failed to clone repo: %w", err)
|
||||
}
|
||||
|
||||
// FIXME: make it work for GHE
|
||||
//logCtx.Debugf("Getting user info for repo credentials")
|
||||
//gitCreds := r.Repo.GetGitCreds(s.gitCredsStore)
|
||||
//startTime := time.Now()
|
||||
//authorName, authorEmail, err := gitCreds.GetUserInfo(ctx)
|
||||
//s.metricsServer.ObserveUserInfoRequestDuration(r.Repo.Repo, getCredentialType(r.Repo), time.Since(startTime))
|
||||
//if err != nil {
|
||||
// cleanupOrLog()
|
||||
// return nil, "", nil, fmt.Errorf("failed to get github app info: %w", err)
|
||||
//}
|
||||
var authorName, authorEmail string
|
||||
|
||||
if authorName == "" {
|
||||
authorName = "Argo CD"
|
||||
}
|
||||
if authorEmail == "" {
|
||||
logCtx.Warnf("Author email not available, using 'argo-cd@example.com'.")
|
||||
authorEmail = "argo-cd@example.com"
|
||||
}
|
||||
|
||||
logCtx.Debugf("Setting author %s <%s>", authorName, authorEmail)
|
||||
_, err = gitClient.SetAuthor(authorName, authorEmail)
|
||||
if err != nil {
|
||||
cleanupOrLog()
|
||||
return nil, "", nil, fmt.Errorf("failed to set author: %w", err)
|
||||
}
|
||||
|
||||
return gitClient, dirPath, cleanupOrLog, nil
|
||||
}
|
||||
|
||||
type hydratorMetadataFile struct {
|
||||
RepoURL string `json:"repoURL"`
|
||||
DrySHA string `json:"drySha"`
|
||||
Commands []string `json:"commands"`
|
||||
}
|
||||
|
||||
// TODO: make this configurable via ConfigMap.
|
||||
var manifestHydrationReadmeTemplate = `
|
||||
# Manifest Hydration
|
||||
|
||||
To hydrate the manifests in this repository, run the following commands:
|
||||
|
||||
` + "```shell\n" + `
|
||||
git clone {{ .RepoURL }}
|
||||
# cd into the cloned directory
|
||||
git checkout {{ .DrySHA }}
|
||||
{{ range $command := .Commands -}}
|
||||
{{ $command }}
|
||||
{{ end -}}` + "```"
|
||||
50
commitserver/commit/commit.proto
Normal file
50
commitserver/commit/commit.proto
Normal file
@@ -0,0 +1,50 @@
|
||||
syntax = "proto3";
|
||||
option go_package = "github.com/argoproj/argo-cd/v2/commitserver/apiclient";
|
||||
|
||||
import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto";
|
||||
|
||||
// CommitHydratedManifestsRequest is the request to commit hydrated manifests to a repository.
|
||||
message CommitHydratedManifestsRequest {
|
||||
// Repo contains repository information including, at minimum, the URL of the repository. Generally it will contain
|
||||
// repo credentials.
|
||||
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1;
|
||||
// SyncBranch is the branch Argo CD syncs from, i.e. the hydrated branch.
|
||||
string syncBranch = 2;
|
||||
// TargetBranch is the branch Argo CD is committing to, i.e. the branch that will be updated.
|
||||
string targetBranch = 3;
|
||||
// DrySha is the commit SHA from the dry branch, i.e. pre-rendered manifest branch.
|
||||
string drySha = 4;
|
||||
// CommitMessage is the commit message to use when committing changes.
|
||||
string commitMessage = 5;
|
||||
// Paths contains the paths to write hydrated manifests to, along with the manifests and commands to execute.
|
||||
repeated PathDetails paths = 6;
|
||||
}
|
||||
|
||||
// PathDetails holds information about hydrated manifests to be written to a particular path in the hydrated manifests
|
||||
// commit.
|
||||
message PathDetails {
|
||||
// Path is the path to write the hydrated manifests to.
|
||||
string path = 1;
|
||||
// Manifests contains the manifests to write to the path.
|
||||
repeated HydratedManifestDetails manifests = 2;
|
||||
// Commands contains the commands executed when hydrating the manifests.
|
||||
repeated string commands = 3;
|
||||
}
|
||||
|
||||
// ManifestDetails contains the hydrated manifests.
|
||||
message HydratedManifestDetails {
|
||||
// ManifestJSON is the hydrated manifest as JSON.
|
||||
string manifestJSON = 1;
|
||||
}
|
||||
|
||||
// ManifestsResponse is the response to the ManifestsRequest.
|
||||
message CommitHydratedManifestsResponse {
|
||||
// HydratedSha is the commit SHA of the hydrated manifests commit.
|
||||
string hydratedSha = 1;
|
||||
}
|
||||
|
||||
// CommitService is the service for committing hydrated manifests to a repository.
|
||||
service CommitService {
|
||||
// Commit commits hydrated manifests to a repository.
|
||||
rpc CommitHydratedManifests (CommitHydratedManifestsRequest) returns (CommitHydratedManifestsResponse);
|
||||
}
|
||||
125
commitserver/commit/commit_test.go
Normal file
125
commitserver/commit/commit_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/commit/mocks"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/metrics"
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/util/git"
|
||||
gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks"
|
||||
)
|
||||
|
||||
func Test_CommitHydratedManifests(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validRequest := &apiclient.CommitHydratedManifestsRequest{
|
||||
Repo: &v1alpha1.Repository{
|
||||
Repo: "https://github.com/argoproj/argocd-example-apps.git",
|
||||
},
|
||||
TargetBranch: "main",
|
||||
SyncBranch: "env/test",
|
||||
CommitMessage: "test commit message",
|
||||
}
|
||||
|
||||
t.Run("missing repo", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, _ := newServiceWithMocks(t)
|
||||
request := &apiclient.CommitHydratedManifestsRequest{}
|
||||
_, err := service.CommitHydratedManifests(context.Background(), request)
|
||||
require.Error(t, err)
|
||||
assert.ErrorContains(t, err, "repo is required")
|
||||
})
|
||||
|
||||
t.Run("missing repo URL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, _ := newServiceWithMocks(t)
|
||||
request := &apiclient.CommitHydratedManifestsRequest{
|
||||
Repo: &v1alpha1.Repository{},
|
||||
}
|
||||
_, err := service.CommitHydratedManifests(context.Background(), request)
|
||||
require.Error(t, err)
|
||||
assert.ErrorContains(t, err, "repo URL is required")
|
||||
})
|
||||
|
||||
t.Run("missing target branch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, _ := newServiceWithMocks(t)
|
||||
request := &apiclient.CommitHydratedManifestsRequest{
|
||||
Repo: &v1alpha1.Repository{
|
||||
Repo: "https://github.com/argoproj/argocd-example-apps.git",
|
||||
},
|
||||
}
|
||||
_, err := service.CommitHydratedManifests(context.Background(), request)
|
||||
require.Error(t, err)
|
||||
assert.ErrorContains(t, err, "target branch is required")
|
||||
})
|
||||
|
||||
t.Run("missing sync branch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, _ := newServiceWithMocks(t)
|
||||
request := &apiclient.CommitHydratedManifestsRequest{
|
||||
Repo: &v1alpha1.Repository{
|
||||
Repo: "https://github.com/argoproj/argocd-example-apps.git",
|
||||
},
|
||||
TargetBranch: "main",
|
||||
}
|
||||
_, err := service.CommitHydratedManifests(context.Background(), request)
|
||||
require.Error(t, err)
|
||||
assert.ErrorContains(t, err, "sync branch is required")
|
||||
})
|
||||
|
||||
t.Run("failed to create git client", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, mockRepoClientFactory := newServiceWithMocks(t)
|
||||
mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(nil, assert.AnError).Once()
|
||||
|
||||
_, err := service.CommitHydratedManifests(context.Background(), validRequest)
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, assert.AnError)
|
||||
})
|
||||
|
||||
t.Run("happy path", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
service, mockRepoClientFactory := newServiceWithMocks(t)
|
||||
mockGitClient := gitmocks.NewClient(t)
|
||||
mockGitClient.On("Init").Return(nil).Once()
|
||||
mockGitClient.On("Fetch", mock.Anything).Return(nil).Once()
|
||||
mockGitClient.On("SetAuthor", "Argo CD", "argo-cd@example.com").Return("", nil).Once()
|
||||
mockGitClient.On("CheckoutOrOrphan", "env/test", false).Return("", nil).Once()
|
||||
mockGitClient.On("CheckoutOrNew", "main", "env/test", false).Return("", nil).Once()
|
||||
mockGitClient.On("RemoveContents").Return("", nil).Once()
|
||||
mockGitClient.On("CommitAndPush", "main", "test commit message").Return("", nil).Once()
|
||||
mockGitClient.On("CommitSHA").Return("it-worked!", nil).Once()
|
||||
mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(mockGitClient, nil).Once()
|
||||
|
||||
resp, err := service.CommitHydratedManifests(context.Background(), validRequest)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "it-worked!", resp.HydratedSha)
|
||||
})
|
||||
}
|
||||
|
||||
func newServiceWithMocks(t *testing.T) (*Service, *mocks.RepoClientFactory) {
|
||||
t.Helper()
|
||||
|
||||
metricsServer := metrics.NewMetricsServer()
|
||||
mockCredsStore := git.NoopCredsStore{}
|
||||
service := NewService(mockCredsStore, metricsServer)
|
||||
mockRepoClientFactory := mocks.NewRepoClientFactory(t)
|
||||
service.repoClientFactory = mockRepoClientFactory
|
||||
|
||||
return service, mockRepoClientFactory
|
||||
}
|
||||
23
commitserver/commit/credentialtypehelper.go
Normal file
23
commitserver/commit/credentialtypehelper.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package commit
|
||||
|
||||
import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
|
||||
// getCredentialType returns the type of credential used by the repository.
|
||||
func getCredentialType(repo *v1alpha1.Repository) string {
|
||||
if repo == nil {
|
||||
return ""
|
||||
}
|
||||
if repo.Password != "" {
|
||||
return "https"
|
||||
}
|
||||
if repo.SSHPrivateKey != "" {
|
||||
return "ssh"
|
||||
}
|
||||
if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 {
|
||||
return "github-app"
|
||||
}
|
||||
if repo.GCPServiceAccountKey != "" {
|
||||
return "cloud-source-repositories"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
62
commitserver/commit/credentialtypehelper_test.go
Normal file
62
commitserver/commit/credentialtypehelper_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
func TestRepository_GetCredentialType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repo *v1alpha1.Repository
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Empty Repository",
|
||||
repo: nil,
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "HTTPS Repository",
|
||||
repo: &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
Password: "some-password",
|
||||
},
|
||||
want: "https",
|
||||
},
|
||||
{
|
||||
name: "SSH Repository",
|
||||
repo: &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
SSHPrivateKey: "some-key",
|
||||
},
|
||||
want: "ssh",
|
||||
},
|
||||
{
|
||||
name: "GitHub App Repository",
|
||||
repo: &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
GithubAppPrivateKey: "some-key",
|
||||
GithubAppId: 1,
|
||||
GithubAppInstallationId: 1,
|
||||
},
|
||||
want: "github-app",
|
||||
},
|
||||
{
|
||||
name: "Google Cloud Repository",
|
||||
repo: &v1alpha1.Repository{
|
||||
Repo: "foo",
|
||||
GCPServiceAccountKey: "some-key",
|
||||
},
|
||||
want: "cloud-source-repositories",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getCredentialType(tt.repo); got != tt.want {
|
||||
t.Errorf("Repository.GetCredentialType() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
145
commitserver/commit/hydratorhelper.go
Normal file
145
commitserver/commit/hydratorhelper.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"text/template"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/util/io/files"
|
||||
)
|
||||
|
||||
// WriteForPaths writes the manifests, hydrator.metadata, and README.md files for each path in the provided paths. It
|
||||
// also writes a root-level hydrator.metadata file containing the repo URL and dry SHA.
|
||||
func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apiclient.PathDetails) error {
|
||||
// Write the top-level readme.
|
||||
err := writeMetadata(rootPath, hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write top-level hydrator metadata: %w", err)
|
||||
}
|
||||
|
||||
for _, p := range paths {
|
||||
hydratePath := p.Path
|
||||
if hydratePath == "." {
|
||||
hydratePath = ""
|
||||
}
|
||||
|
||||
var fullHydratePath string
|
||||
fullHydratePath, err = files.SecureMkdirAll(rootPath, hydratePath, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create path: %w", err)
|
||||
}
|
||||
|
||||
// Write the manifests
|
||||
err = writeManifests(fullHydratePath, p.Manifests)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write manifests: %w", err)
|
||||
}
|
||||
|
||||
// Write hydrator.metadata containing information about the hydration process.
|
||||
hydratorMetadata := hydratorMetadataFile{
|
||||
Commands: p.Commands,
|
||||
DrySHA: drySha,
|
||||
RepoURL: repoUrl,
|
||||
}
|
||||
err = writeMetadata(fullHydratePath, hydratorMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write hydrator metadata: %w", err)
|
||||
}
|
||||
|
||||
// Write README
|
||||
err = writeReadme(fullHydratePath, hydratorMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write readme: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeMetadata writes the metadata to the hydrator.metadata file.
|
||||
func writeMetadata(dirPath string, metadata hydratorMetadataFile) error {
|
||||
hydratorMetadataJson, err := json.MarshalIndent(metadata, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal hydrator metadata: %w", err)
|
||||
}
|
||||
// No need to use SecureJoin here, as the path is already sanitized.
|
||||
hydratorMetadataPath := path.Join(dirPath, "hydrator.metadata")
|
||||
err = os.WriteFile(hydratorMetadataPath, hydratorMetadataJson, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write hydrator metadata: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeReadme writes the readme to the README.md file.
|
||||
func writeReadme(dirPath string, metadata hydratorMetadataFile) error {
|
||||
readmeTemplate := template.New("readme")
|
||||
readmeTemplate, err := readmeTemplate.Parse(manifestHydrationReadmeTemplate)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse readme template: %w", err)
|
||||
}
|
||||
// Create writer to template into
|
||||
// No need to use SecureJoin here, as the path is already sanitized.
|
||||
readmePath := path.Join(dirPath, "README.md")
|
||||
readmeFile, err := os.Create(readmePath)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return fmt.Errorf("failed to create README file: %w", err)
|
||||
}
|
||||
err = readmeTemplate.Execute(readmeFile, metadata)
|
||||
closeErr := readmeFile.Close()
|
||||
if closeErr != nil {
|
||||
log.WithError(closeErr).Error("failed to close README file")
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute readme template: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeManifests writes the manifests to the manifest.yaml file, truncating the file if it exists and appending the
|
||||
// manifests in the order they are provided.
|
||||
func writeManifests(dirPath string, manifests []*apiclient.HydratedManifestDetails) error {
|
||||
// If the file exists, truncate it.
|
||||
// No need to use SecureJoin here, as the path is already sanitized.
|
||||
manifestPath := path.Join(dirPath, "manifest.yaml")
|
||||
|
||||
file, err := os.OpenFile(manifestPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open manifest file: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to close file")
|
||||
}
|
||||
}()
|
||||
|
||||
enc := yaml.NewEncoder(file)
|
||||
defer func() {
|
||||
err := enc.Close()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to close yaml encoder")
|
||||
}
|
||||
}()
|
||||
enc.SetIndent(2)
|
||||
|
||||
for _, m := range manifests {
|
||||
obj := &unstructured.Unstructured{}
|
||||
err = json.Unmarshal([]byte(m.ManifestJSON), obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal manifest: %w", err)
|
||||
}
|
||||
err = enc.Encode(&obj.Object)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode manifest: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
135
commitserver/commit/hydratorhelper_test.go
Normal file
135
commitserver/commit/hydratorhelper_test.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
)
|
||||
|
||||
func TestWriteForPaths(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
repoUrl := "https://github.com/example/repo"
|
||||
drySha := "abc123"
|
||||
paths := []*apiclient.PathDetails{
|
||||
{
|
||||
Path: "path1",
|
||||
Manifests: []*apiclient.HydratedManifestDetails{
|
||||
{ManifestJSON: `{"kind":"Pod","apiVersion":"v1"}`},
|
||||
},
|
||||
Commands: []string{"command1", "command2"},
|
||||
},
|
||||
{
|
||||
Path: "path2",
|
||||
Manifests: []*apiclient.HydratedManifestDetails{
|
||||
{ManifestJSON: `{"kind":"Service","apiVersion":"v1"}`},
|
||||
},
|
||||
Commands: []string{"command3"},
|
||||
},
|
||||
}
|
||||
|
||||
err := WriteForPaths(dir, repoUrl, drySha, paths)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check if the top-level hydrator.metadata exists and contains the repo URL and dry SHA
|
||||
topMetadataPath := path.Join(dir, "hydrator.metadata")
|
||||
topMetadataBytes, err := os.ReadFile(topMetadataPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
var topMetadata hydratorMetadataFile
|
||||
err = json.Unmarshal(topMetadataBytes, &topMetadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, repoUrl, topMetadata.RepoURL)
|
||||
assert.Equal(t, drySha, topMetadata.DrySHA)
|
||||
|
||||
for _, p := range paths {
|
||||
fullHydratePath, err := securejoin.SecureJoin(dir, p.Path)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check if each path directory exists
|
||||
assert.DirExists(t, fullHydratePath)
|
||||
|
||||
// Check if each path contains a hydrator.metadata file and contains the repo URL
|
||||
metadataPath := path.Join(fullHydratePath, "hydrator.metadata")
|
||||
metadataBytes, err := os.ReadFile(metadataPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
var readMetadata hydratorMetadataFile
|
||||
err = json.Unmarshal(metadataBytes, &readMetadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, repoUrl, readMetadata.RepoURL)
|
||||
|
||||
// Check if each path contains a README.md file and contains the repo URL
|
||||
readmePath := path.Join(fullHydratePath, "README.md")
|
||||
readmeBytes, err := os.ReadFile(readmePath)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(readmeBytes), repoUrl)
|
||||
|
||||
// Check if each path contains a manifest.yaml file and contains the word Pod
|
||||
manifestPath := path.Join(fullHydratePath, "manifest.yaml")
|
||||
manifestBytes, err := os.ReadFile(manifestPath)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(manifestBytes), "kind")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteMetadata(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
metadata := hydratorMetadataFile{
|
||||
RepoURL: "https://github.com/example/repo",
|
||||
DrySHA: "abc123",
|
||||
}
|
||||
|
||||
err := writeMetadata(dir, metadata)
|
||||
require.NoError(t, err)
|
||||
|
||||
metadataPath := path.Join(dir, "hydrator.metadata")
|
||||
metadataBytes, err := os.ReadFile(metadataPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
var readMetadata hydratorMetadataFile
|
||||
err = json.Unmarshal(metadataBytes, &readMetadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, metadata, readMetadata)
|
||||
}
|
||||
|
||||
func TestWriteReadme(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
metadata := hydratorMetadataFile{
|
||||
RepoURL: "https://github.com/example/repo",
|
||||
DrySHA: "abc123",
|
||||
}
|
||||
|
||||
err := writeReadme(dir, metadata)
|
||||
require.NoError(t, err)
|
||||
|
||||
readmePath := path.Join(dir, "README.md")
|
||||
readmeBytes, err := os.ReadFile(readmePath)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(readmeBytes), metadata.RepoURL)
|
||||
}
|
||||
|
||||
func TestWriteManifests(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
manifests := []*apiclient.HydratedManifestDetails{
|
||||
{ManifestJSON: `{"kind":"Pod","apiVersion":"v1"}`},
|
||||
}
|
||||
|
||||
err := writeManifests(dir, manifests)
|
||||
require.NoError(t, err)
|
||||
|
||||
manifestPath := path.Join(dir, "manifest.yaml")
|
||||
manifestBytes, err := os.ReadFile(manifestPath)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(manifestBytes), "kind")
|
||||
}
|
||||
59
commitserver/commit/mocks/RepoClientFactory.go
generated
Normal file
59
commitserver/commit/mocks/RepoClientFactory.go
generated
Normal file
@@ -0,0 +1,59 @@
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
git "github.com/argoproj/argo-cd/v2/util/git"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
// RepoClientFactory is an autogenerated mock type for the RepoClientFactory type
|
||||
type RepoClientFactory struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// NewClient provides a mock function with given fields: repo, rootPath
|
||||
func (_m *RepoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) {
|
||||
ret := _m.Called(repo, rootPath)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for NewClient")
|
||||
}
|
||||
|
||||
var r0 git.Client
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) (git.Client, error)); ok {
|
||||
return rf(repo, rootPath)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) git.Client); ok {
|
||||
r0 = rf(repo, rootPath)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(git.Client)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(*v1alpha1.Repository, string) error); ok {
|
||||
r1 = rf(repo, rootPath)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// NewRepoClientFactory creates a new instance of RepoClientFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewRepoClientFactory(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *RepoClientFactory {
|
||||
mock := &RepoClientFactory{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
32
commitserver/commit/repo_client_factory.go
Normal file
32
commitserver/commit/repo_client_factory.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package commit
|
||||
|
||||
import (
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/metrics"
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/util/git"
|
||||
)
|
||||
|
||||
// RepoClientFactory is a factory for creating git clients for a repository.
|
||||
type RepoClientFactory interface {
|
||||
NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error)
|
||||
}
|
||||
|
||||
type repoClientFactory struct {
|
||||
gitCredsStore git.CredsStore
|
||||
metricsServer *metrics.Server
|
||||
}
|
||||
|
||||
// NewRepoClientFactory returns a new instance of the repo client factory.
|
||||
func NewRepoClientFactory(gitCredsStore git.CredsStore, metricsServer *metrics.Server) RepoClientFactory {
|
||||
return &repoClientFactory{
|
||||
gitCredsStore: gitCredsStore,
|
||||
metricsServer: metricsServer,
|
||||
}
|
||||
}
|
||||
|
||||
// NewClient creates a new git client for the repository.
|
||||
func (r *repoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) {
|
||||
gitCreds := repo.GetGitCreds(r.gitCredsStore)
|
||||
opts := git.WithEventHandlers(metrics.NewGitClientEventHandlers(r.metricsServer))
|
||||
return git.NewClientExt(repo.Repo, rootPath, gitCreds, repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy, repo.NoProxy, opts)
|
||||
}
|
||||
34
commitserver/metrics/githandlers.go
Normal file
34
commitserver/metrics/githandlers.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/git"
|
||||
)
|
||||
|
||||
// NewGitClientEventHandlers creates event handlers that update Git related metrics
|
||||
func NewGitClientEventHandlers(metricsServer *Server) git.EventHandlers {
|
||||
return git.EventHandlers{
|
||||
OnFetch: func(repo string) func() {
|
||||
startTime := time.Now()
|
||||
metricsServer.IncGitRequest(repo, GitRequestTypeFetch)
|
||||
return func() {
|
||||
metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeFetch, time.Since(startTime))
|
||||
}
|
||||
},
|
||||
OnLsRemote: func(repo string) func() {
|
||||
startTime := time.Now()
|
||||
metricsServer.IncGitRequest(repo, GitRequestTypeLsRemote)
|
||||
return func() {
|
||||
metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeLsRemote, time.Since(startTime))
|
||||
}
|
||||
},
|
||||
OnPush: func(repo string) func() {
|
||||
startTime := time.Now()
|
||||
metricsServer.IncGitRequest(repo, GitRequestTypePush)
|
||||
return func() {
|
||||
metricsServer.ObserveGitRequestDuration(repo, GitRequestTypePush, time.Since(startTime))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
157
commitserver/metrics/metrics.go
Normal file
157
commitserver/metrics/metrics.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
// Server is a prometheus server which collects application metrics.
|
||||
type Server struct {
|
||||
handler http.Handler
|
||||
commitPendingRequestsGauge *prometheus.GaugeVec
|
||||
gitRequestCounter *prometheus.CounterVec
|
||||
gitRequestHistogram *prometheus.HistogramVec
|
||||
commitRequestHistogram *prometheus.HistogramVec
|
||||
userInfoRequestHistogram *prometheus.HistogramVec
|
||||
commitRequestCounter *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// GitRequestType is the type of git request
|
||||
type GitRequestType string
|
||||
|
||||
const (
|
||||
// GitRequestTypeLsRemote is a request to list remote refs
|
||||
GitRequestTypeLsRemote = "ls-remote"
|
||||
// GitRequestTypeFetch is a request to fetch from remote
|
||||
GitRequestTypeFetch = "fetch"
|
||||
// GitRequestTypePush is a request to push to remote
|
||||
GitRequestTypePush = "push"
|
||||
)
|
||||
|
||||
// CommitResponseType is the type of response for a commit request
|
||||
type CommitResponseType string
|
||||
|
||||
const (
|
||||
// CommitResponseTypeSuccess is a successful commit request
|
||||
CommitResponseTypeSuccess CommitResponseType = "success"
|
||||
// CommitResponseTypeFailure is a failed commit request
|
||||
CommitResponseTypeFailure CommitResponseType = "failure"
|
||||
)
|
||||
|
||||
// NewMetricsServer returns a new prometheus server which collects application metrics.
|
||||
func NewMetricsServer() *Server {
|
||||
registry := prometheus.NewRegistry()
|
||||
registry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
|
||||
registry.MustRegister(collectors.NewGoCollector())
|
||||
|
||||
commitPendingRequestsGauge := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "argocd_commitserver_commit_pending_request_total",
|
||||
Help: "Number of pending commit requests",
|
||||
},
|
||||
[]string{"repo"},
|
||||
)
|
||||
registry.MustRegister(commitPendingRequestsGauge)
|
||||
|
||||
gitRequestCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "argocd_commitserver_git_request_total",
|
||||
Help: "Number of git requests performed by repo server",
|
||||
},
|
||||
[]string{"repo", "request_type"},
|
||||
)
|
||||
registry.MustRegister(gitRequestCounter)
|
||||
|
||||
gitRequestHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_commitserver_git_request_duration_seconds",
|
||||
Help: "Git requests duration seconds.",
|
||||
Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20},
|
||||
},
|
||||
[]string{"repo", "request_type"},
|
||||
)
|
||||
registry.MustRegister(gitRequestHistogram)
|
||||
|
||||
commitRequestHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_commitserver_commit_request_duration_seconds",
|
||||
Help: "Commit request duration seconds.",
|
||||
Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20},
|
||||
},
|
||||
[]string{"repo", "response_type"},
|
||||
)
|
||||
registry.MustRegister(commitRequestHistogram)
|
||||
|
||||
userInfoRequestHistogram := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "argocd_commitserver_userinfo_request_duration_seconds",
|
||||
Help: "Userinfo request duration seconds.",
|
||||
Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20},
|
||||
},
|
||||
[]string{"repo", "credential_type"},
|
||||
)
|
||||
registry.MustRegister(userInfoRequestHistogram)
|
||||
|
||||
commitRequestCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "argocd_commitserver_commit_request_total",
|
||||
Help: "Number of commit requests performed handled",
|
||||
},
|
||||
[]string{"repo", "response_type"},
|
||||
)
|
||||
registry.MustRegister(commitRequestCounter)
|
||||
|
||||
return &Server{
|
||||
handler: promhttp.HandlerFor(registry, promhttp.HandlerOpts{}),
|
||||
commitPendingRequestsGauge: commitPendingRequestsGauge,
|
||||
gitRequestCounter: gitRequestCounter,
|
||||
gitRequestHistogram: gitRequestHistogram,
|
||||
commitRequestHistogram: commitRequestHistogram,
|
||||
userInfoRequestHistogram: userInfoRequestHistogram,
|
||||
commitRequestCounter: commitRequestCounter,
|
||||
}
|
||||
}
|
||||
|
||||
// GetHandler returns the http.Handler for the prometheus server
|
||||
func (m *Server) GetHandler() http.Handler {
|
||||
return m.handler
|
||||
}
|
||||
|
||||
// IncPendingCommitRequest increments the pending commit requests gauge
|
||||
func (m *Server) IncPendingCommitRequest(repo string) {
|
||||
m.commitPendingRequestsGauge.WithLabelValues(repo).Inc()
|
||||
}
|
||||
|
||||
// DecPendingCommitRequest decrements the pending commit requests gauge
|
||||
func (m *Server) DecPendingCommitRequest(repo string) {
|
||||
m.commitPendingRequestsGauge.WithLabelValues(repo).Dec()
|
||||
}
|
||||
|
||||
// IncGitRequest increments the git requests counter
|
||||
func (m *Server) IncGitRequest(repo string, requestType GitRequestType) {
|
||||
m.gitRequestCounter.WithLabelValues(repo, string(requestType)).Inc()
|
||||
}
|
||||
|
||||
// ObserveGitRequestDuration observes the duration of a git request
|
||||
func (m *Server) ObserveGitRequestDuration(repo string, requestType GitRequestType, duration time.Duration) {
|
||||
m.gitRequestHistogram.WithLabelValues(repo, string(requestType)).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// ObserveCommitRequestDuration observes the duration of a commit request
|
||||
func (m *Server) ObserveCommitRequestDuration(repo string, rt CommitResponseType, duration time.Duration) {
|
||||
m.commitRequestHistogram.WithLabelValues(repo, string(rt)).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// ObserveUserInfoRequestDuration observes the duration of a userinfo request
|
||||
func (m *Server) ObserveUserInfoRequestDuration(repo string, credentialType string, duration time.Duration) {
|
||||
m.userInfoRequestHistogram.WithLabelValues(repo, credentialType).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// IncCommitRequest increments the commit request counter
|
||||
func (m *Server) IncCommitRequest(repo string, rt CommitResponseType) {
|
||||
m.commitRequestCounter.WithLabelValues(repo, string(rt)).Inc()
|
||||
}
|
||||
38
commitserver/server.go
Normal file
38
commitserver/server.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package commitserver
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/health"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/commit"
|
||||
"github.com/argoproj/argo-cd/v2/commitserver/metrics"
|
||||
versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version"
|
||||
"github.com/argoproj/argo-cd/v2/server/version"
|
||||
"github.com/argoproj/argo-cd/v2/util/git"
|
||||
)
|
||||
|
||||
// ArgoCDCommitServer is the server that handles commit requests.
|
||||
type ArgoCDCommitServer struct {
|
||||
commitService *commit.Service
|
||||
}
|
||||
|
||||
// NewServer returns a new instance of the commit server.
|
||||
func NewServer(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *ArgoCDCommitServer {
|
||||
return &ArgoCDCommitServer{commitService: commit.NewService(gitCredsStore, metricsServer)}
|
||||
}
|
||||
|
||||
// CreateGRPC creates a new gRPC server.
|
||||
func (a *ArgoCDCommitServer) CreateGRPC() *grpc.Server {
|
||||
server := grpc.NewServer()
|
||||
versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) {
|
||||
return true, nil
|
||||
}))
|
||||
apiclient.RegisterCommitServiceServer(server, a.commitService)
|
||||
|
||||
healthService := health.NewServer()
|
||||
grpc_health_v1.RegisterHealthServer(server, healthService)
|
||||
|
||||
return server
|
||||
}
|
||||
@@ -62,15 +62,19 @@ const (
|
||||
DefaultPortArgoCDMetrics = 8082
|
||||
DefaultPortArgoCDAPIServerMetrics = 8083
|
||||
DefaultPortRepoServerMetrics = 8084
|
||||
DefaultPortCommitServer = 8086
|
||||
DefaultPortCommitServerMetrics = 8087
|
||||
)
|
||||
|
||||
// DefaultAddressAPIServer for ArgoCD components
|
||||
const (
|
||||
DefaultAddressAdminDashboard = "localhost"
|
||||
DefaultAddressAPIServer = "0.0.0.0"
|
||||
DefaultAddressAPIServerMetrics = "0.0.0.0"
|
||||
DefaultAddressRepoServer = "0.0.0.0"
|
||||
DefaultAddressRepoServerMetrics = "0.0.0.0"
|
||||
DefaultAddressAdminDashboard = "localhost"
|
||||
DefaultAddressAPIServer = "0.0.0.0"
|
||||
DefaultAddressAPIServerMetrics = "0.0.0.0"
|
||||
DefaultAddressRepoServer = "0.0.0.0"
|
||||
DefaultAddressRepoServerMetrics = "0.0.0.0"
|
||||
DefaultAddressCommitServer = "0.0.0.0"
|
||||
DefaultAddressCommitServerMetrics = "0.0.0.0"
|
||||
)
|
||||
|
||||
// Default paths on the pod's file system
|
||||
|
||||
@@ -131,6 +131,7 @@ type ApplicationController struct {
|
||||
statusRefreshJitter time.Duration
|
||||
selfHealTimeout time.Duration
|
||||
selfHealBackOff *wait.Backoff
|
||||
syncTimeout time.Duration
|
||||
db db.ArgoDB
|
||||
settingsMgr *settings_util.SettingsManager
|
||||
refreshRequestedApps map[string]CompareWith
|
||||
@@ -161,6 +162,7 @@ func NewApplicationController(
|
||||
appResyncJitter time.Duration,
|
||||
selfHealTimeout time.Duration,
|
||||
selfHealBackoff *wait.Backoff,
|
||||
syncTimeout time.Duration,
|
||||
repoErrorGracePeriod time.Duration,
|
||||
metricsPort int,
|
||||
metricsCacheExpiration time.Duration,
|
||||
@@ -202,6 +204,7 @@ func NewApplicationController(
|
||||
settingsMgr: settingsMgr,
|
||||
selfHealTimeout: selfHealTimeout,
|
||||
selfHealBackOff: selfHealBackoff,
|
||||
syncTimeout: syncTimeout,
|
||||
clusterSharding: clusterSharding,
|
||||
projByNameCache: sync.Map{},
|
||||
applicationNamespaces: applicationNamespaces,
|
||||
@@ -377,7 +380,11 @@ func (projCache *appProjCache) GetAppProject(ctx context.Context) (*appv1.AppPro
|
||||
|
||||
// getAppProj gets the AppProject for the given Application app.
|
||||
func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.AppProject, error) {
|
||||
projCache, _ := ctrl.projByNameCache.LoadOrStore(app.Spec.GetProject(), ctrl.newAppProjCache(app.Spec.GetProject()))
|
||||
projCache, _ := ctrl.projByNameCache.Load(app.Spec.GetProject())
|
||||
if projCache == nil {
|
||||
projCache = ctrl.newAppProjCache(app.Spec.GetProject())
|
||||
ctrl.projByNameCache.Store(app.Spec.GetProject(), projCache)
|
||||
}
|
||||
proj, err := projCache.(*appProjCache).GetAppProject(context.TODO())
|
||||
if err != nil {
|
||||
if apierr.IsNotFound(err) {
|
||||
@@ -1373,12 +1380,21 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
||||
// Get rid of sync results and null out previous operation completion time
|
||||
state.SyncResult = nil
|
||||
}
|
||||
} else if ctrl.syncTimeout != time.Duration(0) && time.Now().After(state.StartedAt.Add(ctrl.syncTimeout)) && !terminating {
|
||||
state.Phase = synccommon.OperationTerminating
|
||||
state.Message = "operation is terminating due to timeout"
|
||||
ctrl.setOperationState(app, state)
|
||||
logCtx.Infof("Terminating in-progress operation due to timeout. Started at: %v, timeout: %v", state.StartedAt, ctrl.syncTimeout)
|
||||
} else {
|
||||
logCtx.Infof("Resuming in-progress operation. phase: %s, message: %s", state.Phase, state.Message)
|
||||
}
|
||||
} else {
|
||||
state = &appv1.OperationState{Phase: synccommon.OperationRunning, Operation: *app.Operation, StartedAt: metav1.Now()}
|
||||
ctrl.setOperationState(app, state)
|
||||
if ctrl.syncTimeout != time.Duration(0) {
|
||||
// Schedule a check during which the timeout would be checked.
|
||||
ctrl.appOperationQueue.AddAfter(ctrl.toAppKey(app.QualifiedName()), ctrl.syncTimeout)
|
||||
}
|
||||
logCtx.Infof("Initialized new operation: %v", *app.Operation)
|
||||
}
|
||||
ts.AddCheckpoint("initial_operation_stage_ms")
|
||||
@@ -1630,9 +1646,11 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
|
||||
project, hasErrors := ctrl.refreshAppConditions(app)
|
||||
ts.AddCheckpoint("refresh_app_conditions_ms")
|
||||
now := metav1.Now()
|
||||
if hasErrors {
|
||||
app.Status.Sync.Status = appv1.SyncStatusCodeUnknown
|
||||
app.Status.Health.Status = health.HealthStatusUnknown
|
||||
app.Status.Health.LastTransitionTime = &now
|
||||
patchMs = ctrl.persistAppStatus(origApp, &app.Status)
|
||||
|
||||
if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), &appv1.ApplicationTree{}); err != nil {
|
||||
@@ -1676,7 +1694,6 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
revisions = append(revisions, revision)
|
||||
sources = append(sources, app.Spec.GetSource())
|
||||
}
|
||||
now := metav1.Now()
|
||||
|
||||
compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources,
|
||||
refreshType == appv1.RefreshTypeHard,
|
||||
@@ -2080,7 +2097,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *
|
||||
}
|
||||
|
||||
// alreadyAttemptedSync returns whether the most recent sync was performed against the
|
||||
// commitSHA and with the same app source config which are currently set in the app
|
||||
// commitSHA and with the same app source config which are currently set in the app.
|
||||
func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS []string, hasMultipleSources bool, revisionUpdated bool) (bool, synccommon.OperationPhase) {
|
||||
if app.Status.OperationState == nil || app.Status.OperationState.Operation.Sync == nil || app.Status.OperationState.SyncResult == nil {
|
||||
return false, ""
|
||||
@@ -2105,24 +2122,8 @@ func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS
|
||||
}
|
||||
|
||||
if hasMultipleSources {
|
||||
// Ignore differences in target revision, since we already just verified commitSHAs are equal,
|
||||
// and we do not want to trigger auto-sync due to things like HEAD != master
|
||||
specSources := app.Spec.Sources.DeepCopy()
|
||||
syncSources := app.Status.OperationState.SyncResult.Sources.DeepCopy()
|
||||
for _, source := range specSources {
|
||||
source.TargetRevision = ""
|
||||
}
|
||||
for _, source := range syncSources {
|
||||
source.TargetRevision = ""
|
||||
}
|
||||
return reflect.DeepEqual(app.Spec.Sources, app.Status.OperationState.SyncResult.Sources), app.Status.OperationState.Phase
|
||||
} else {
|
||||
// Ignore differences in target revision, since we already just verified commitSHAs are equal,
|
||||
// and we do not want to trigger auto-sync due to things like HEAD != master
|
||||
specSource := app.Spec.Source.DeepCopy()
|
||||
specSource.TargetRevision = ""
|
||||
syncResSource := app.Status.OperationState.SyncResult.Source.DeepCopy()
|
||||
syncResSource.TargetRevision = ""
|
||||
return reflect.DeepEqual(app.Spec.GetSource(), app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ import (
|
||||
"time"
|
||||
|
||||
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/utils/ptr"
|
||||
@@ -26,6 +28,7 @@ import (
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -90,6 +93,10 @@ func (m *MockKubectl) DeleteResource(ctx context.Context, config *rest.Config, g
|
||||
}
|
||||
|
||||
func newFakeController(data *fakeData, repoErr error) *ApplicationController {
|
||||
return newFakeControllerWithResync(data, time.Minute, repoErr)
|
||||
}
|
||||
|
||||
func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration, repoErr error) *ApplicationController {
|
||||
var clust corev1.Secret
|
||||
err := yaml.Unmarshal([]byte(fakeCluster), &clust)
|
||||
if err != nil {
|
||||
@@ -155,11 +162,12 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController {
|
||||
1*time.Minute,
|
||||
),
|
||||
kubectl,
|
||||
time.Minute,
|
||||
appResyncPeriod,
|
||||
time.Hour,
|
||||
time.Second,
|
||||
time.Minute,
|
||||
nil,
|
||||
0,
|
||||
time.Second*10,
|
||||
common.DefaultPortArgoCDMetrics,
|
||||
data.metricsCacheExpiration,
|
||||
@@ -492,10 +500,23 @@ func newFakeApp() *v1alpha1.Application {
|
||||
return createFakeApp(fakeApp)
|
||||
}
|
||||
|
||||
func newFakeAppWithHealthAndTime(status health.HealthStatusCode, timestamp metav1.Time) *v1alpha1.Application {
|
||||
return createFakeAppWithHealthAndTime(fakeApp, status, timestamp)
|
||||
}
|
||||
|
||||
func newFakeMultiSourceApp() *v1alpha1.Application {
|
||||
return createFakeApp(fakeMultiSourceApp)
|
||||
}
|
||||
|
||||
func createFakeAppWithHealthAndTime(testApp string, status health.HealthStatusCode, timestamp metav1.Time) *v1alpha1.Application {
|
||||
app := createFakeApp(testApp)
|
||||
app.Status.Health = v1alpha1.HealthStatus{
|
||||
Status: status,
|
||||
LastTransitionTime: ×tamp,
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
func newFakeAppWithDestMismatch() *v1alpha1.Application {
|
||||
return createFakeApp(fakeAppWithDestMismatch)
|
||||
}
|
||||
@@ -1669,6 +1690,211 @@ func TestUpdateReconciledAt(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateHealthStatusTransitionTime(t *testing.T) {
|
||||
deployment := kube.MustToUnstructured(&v1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: "default",
|
||||
},
|
||||
})
|
||||
testCases := []struct {
|
||||
name string
|
||||
app *v1alpha1.Application
|
||||
configMapData map[string]string
|
||||
expectedStatus health.HealthStatusCode
|
||||
}{
|
||||
{
|
||||
name: "Degraded to Missing",
|
||||
app: newFakeAppWithHealthAndTime(health.HealthStatusDegraded, testTimestamp),
|
||||
configMapData: map[string]string{
|
||||
"resource.customizations": `
|
||||
apps/Deployment:
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = "Missing"
|
||||
hs.message = ""
|
||||
return hs`,
|
||||
},
|
||||
expectedStatus: health.HealthStatusMissing,
|
||||
},
|
||||
{
|
||||
name: "Missing to Progressing",
|
||||
app: newFakeAppWithHealthAndTime(health.HealthStatusMissing, testTimestamp),
|
||||
configMapData: map[string]string{
|
||||
"resource.customizations": `
|
||||
apps/Deployment:
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = "Progressing"
|
||||
hs.message = ""
|
||||
return hs`,
|
||||
},
|
||||
expectedStatus: health.HealthStatusProgressing,
|
||||
},
|
||||
{
|
||||
name: "Progressing to Healthy",
|
||||
app: newFakeAppWithHealthAndTime(health.HealthStatusProgressing, testTimestamp),
|
||||
configMapData: map[string]string{
|
||||
"resource.customizations": `
|
||||
apps/Deployment:
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = "Healthy"
|
||||
hs.message = ""
|
||||
return hs`,
|
||||
},
|
||||
expectedStatus: health.HealthStatusHealthy,
|
||||
},
|
||||
{
|
||||
name: "Healthy to Degraded",
|
||||
app: newFakeAppWithHealthAndTime(health.HealthStatusHealthy, testTimestamp),
|
||||
configMapData: map[string]string{
|
||||
"resource.customizations": `
|
||||
apps/Deployment:
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = "Degraded"
|
||||
hs.message = ""
|
||||
return hs`,
|
||||
},
|
||||
expectedStatus: health.HealthStatusDegraded,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{tc.app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(deployment): deployment,
|
||||
},
|
||||
configMapData: tc.configMapData,
|
||||
}, nil)
|
||||
|
||||
ctrl.processAppRefreshQueueItem()
|
||||
apps, err := ctrl.appLister.List(labels.Everything())
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, apps)
|
||||
assert.Equal(t, tc.expectedStatus, apps[0].Status.Health.Status)
|
||||
assert.NotEqual(t, testTimestamp, *apps[0].Status.Health.LastTransitionTime)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateHealthStatusProgression(t *testing.T) {
|
||||
app := newFakeAppWithHealthAndTime(health.HealthStatusDegraded, testTimestamp)
|
||||
deployment := kube.MustToUnstructured(&v1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: "default",
|
||||
},
|
||||
Status: v1.DeploymentStatus{
|
||||
ObservedGeneration: 0,
|
||||
},
|
||||
})
|
||||
configMapData := map[string]string{
|
||||
"resource.customizations": `
|
||||
apps/Deployment:
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = ""
|
||||
hs.message = ""
|
||||
|
||||
if obj.metadata ~= nil then
|
||||
if obj.metadata.labels ~= nil then
|
||||
current_status = obj.metadata.labels["status"]
|
||||
if current_status == "Degraded" then
|
||||
hs.status = "Missing"
|
||||
elseif current_status == "Missing" then
|
||||
hs.status = "Progressing"
|
||||
elseif current_status == "Progressing" then
|
||||
hs.status = "Healthy"
|
||||
elseif current_status == "Healthy" then
|
||||
hs.status = "Degraded"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return hs`,
|
||||
}
|
||||
ctrl := newFakeControllerWithResync(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(deployment): deployment,
|
||||
},
|
||||
configMapData: configMapData,
|
||||
manifestResponses: []*apiclient.ManifestResponse{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
},
|
||||
}, time.Millisecond*10, nil)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
initialStatus string
|
||||
expectedStatus health.HealthStatusCode
|
||||
}{
|
||||
{
|
||||
name: "Degraded to Missing",
|
||||
initialStatus: "Degraded",
|
||||
expectedStatus: health.HealthStatusMissing,
|
||||
},
|
||||
{
|
||||
name: "Missing to Progressing",
|
||||
initialStatus: "Missing",
|
||||
expectedStatus: health.HealthStatusProgressing,
|
||||
},
|
||||
{
|
||||
name: "Progressing to Healthy",
|
||||
initialStatus: "Progressing",
|
||||
expectedStatus: health.HealthStatusHealthy,
|
||||
},
|
||||
{
|
||||
name: "Healthy to Degraded",
|
||||
initialStatus: "Healthy",
|
||||
expectedStatus: health.HealthStatusDegraded,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
deployment.SetLabels(map[string]string{"status": tc.initialStatus})
|
||||
ctrl.processAppRefreshQueueItem()
|
||||
apps, err := ctrl.appLister.List(labels.Everything())
|
||||
require.NoError(t, err)
|
||||
if assert.NotEmpty(t, apps) {
|
||||
assert.Equal(t, tc.expectedStatus, apps[0].Status.Health.Status)
|
||||
assert.NotEqual(t, testTimestamp, *apps[0].Status.Health.LastTransitionTime)
|
||||
}
|
||||
|
||||
ctrl.requestAppRefresh(app.Name, nil, nil)
|
||||
time.Sleep(time.Millisecond * 15)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProjectErrorToCondition(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.Project = "wrong project"
|
||||
@@ -2182,15 +2408,93 @@ func TestAppStatusIsReplaced(t *testing.T) {
|
||||
|
||||
func TestAlreadyAttemptSync(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
t.Run("same manifest with sync result", func(t *testing.T) {
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false)
|
||||
assert.True(t, attempted)
|
||||
|
||||
t.Run("no operation state", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState = nil
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("different manifest with sync result", func(t *testing.T) {
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, true)
|
||||
t.Run("no sync operation", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.Operation.Sync = nil
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("no sync result", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult = nil
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("single source", func(t *testing.T) {
|
||||
t.Run("same manifest with sync result", func(t *testing.T) {
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false)
|
||||
assert.True(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("same manifest with sync result different targetRevision, same SHA", func(t *testing.T) {
|
||||
// This test represents the case where the user changed a source's target revision to a new branch, but it
|
||||
// points to the same revision as the old branch. We currently do not consider this as having been "already
|
||||
// attempted." In the future we may want to short-circuit the auto-sync in these cases.
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Source = v1alpha1.ApplicationSource{TargetRevision: "branch1"}
|
||||
app.Spec.Source = &v1alpha1.ApplicationSource{TargetRevision: "branch2"}
|
||||
app.Status.OperationState.SyncResult.Revision = "sha"
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("different manifest with sync result, different SHA", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Revision = "sha1"
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha2", []string{}, false, true)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("different manifest with sync result, same SHA", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Revision = "sha"
|
||||
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, true)
|
||||
assert.True(t, attempted)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("multi-source", func(t *testing.T) {
|
||||
t.Run("same manifest with sync result", func(t *testing.T) {
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{"sha"}, true, false)
|
||||
assert.True(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("same manifest with sync result, different targetRevision, same SHA", func(t *testing.T) {
|
||||
// This test represents the case where the user changed a source's target revision to a new branch, but it
|
||||
// points to the same revision as the old branch. We currently do not consider this as having been "already
|
||||
// attempted." In the future we may want to short-circuit the auto-sync in these cases.
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Sources = []v1alpha1.ApplicationSource{{TargetRevision: "branch1"}}
|
||||
app.Spec.Sources = []v1alpha1.ApplicationSource{{TargetRevision: "branch2"}}
|
||||
app.Status.OperationState.SyncResult.Revisions = []string{"sha"}
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{"sha"}, true, false)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("different manifest with sync result, different SHAs", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Revisions = []string{"sha_a_=", "sha_b_1"}
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{"sha_a_2", "sha_b_2"}, true, true)
|
||||
assert.False(t, attempted)
|
||||
})
|
||||
|
||||
t.Run("different manifest with sync result, same SHAs", func(t *testing.T) {
|
||||
app := app.DeepCopy()
|
||||
app.Status.OperationState.SyncResult.Revisions = []string{"sha_a", "sha_b"}
|
||||
attempted, _ := alreadyAttemptedSync(app, "", []string{"sha_a", "sha_b"}, true, true)
|
||||
assert.True(t, attempted)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func assertDurationAround(t *testing.T, expected time.Duration, actual time.Duration) {
|
||||
@@ -2256,3 +2560,54 @@ func TestSelfHealExponentialBackoff(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncTimeout(t *testing.T) {
|
||||
testCases := []struct {
|
||||
delta time.Duration
|
||||
expectedPhase synccommon.OperationPhase
|
||||
expectedMessage string
|
||||
}{{
|
||||
delta: 2 * time.Minute,
|
||||
expectedPhase: synccommon.OperationFailed,
|
||||
expectedMessage: "Operation terminated",
|
||||
}, {
|
||||
delta: 30 * time.Second,
|
||||
expectedPhase: synccommon.OperationSucceeded,
|
||||
expectedMessage: "successfully synced (no more tasks)",
|
||||
}}
|
||||
for i := range testCases {
|
||||
tc := testCases[i]
|
||||
t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.Project = "default"
|
||||
app.Operation = &v1alpha1.Operation{
|
||||
Sync: &v1alpha1.SyncOperation{
|
||||
Revision: "HEAD",
|
||||
},
|
||||
}
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponses: []*apiclient.ManifestResponse{{
|
||||
Manifests: []string{},
|
||||
}},
|
||||
}, nil)
|
||||
|
||||
ctrl.syncTimeout = time.Minute
|
||||
app.Status.OperationState = &v1alpha1.OperationState{
|
||||
Operation: v1alpha1.Operation{
|
||||
Sync: &v1alpha1.SyncOperation{
|
||||
Revision: "HEAD",
|
||||
},
|
||||
},
|
||||
Phase: synccommon.OperationRunning,
|
||||
StartedAt: metav1.NewTime(time.Now().Add(-tc.delta)),
|
||||
}
|
||||
ctrl.processRequestedAppOperation(app)
|
||||
|
||||
app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.ObjectMeta.Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedPhase, app.Status.OperationState.Phase)
|
||||
require.Equal(t, tc.expectedMessage, app.Status.OperationState.Message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
|
||||
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/common"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
func setApplicationHealth(resources []managedResource, statuses []appv1.ResourceStatus, resourceOverrides map[string]appv1.ResourceOverride, app *appv1.Application, persistResourceHealth bool) (*appv1.HealthStatus, error) {
|
||||
var savedErr error
|
||||
var errCount uint
|
||||
|
||||
appHealth := appv1.HealthStatus{Status: health.HealthStatusHealthy}
|
||||
for i, res := range resources {
|
||||
if res.Target != nil && hookutil.Skip(res.Target) {
|
||||
@@ -80,6 +82,13 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
|
||||
}
|
||||
if persistResourceHealth {
|
||||
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline
|
||||
// if the status didn't change, don't update the timestamp
|
||||
if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil {
|
||||
appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime
|
||||
} else {
|
||||
now := metav1.Now()
|
||||
appHealth.LastTransitionTime = &now
|
||||
}
|
||||
} else {
|
||||
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationAppTree
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
@@ -19,7 +21,16 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/lua"
|
||||
)
|
||||
|
||||
var app = &appv1.Application{}
|
||||
var (
|
||||
app = &appv1.Application{
|
||||
Status: appv1.ApplicationStatus{
|
||||
Health: appv1.HealthStatus{
|
||||
LastTransitionTime: &metav1.Time{Time: time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC)},
|
||||
},
|
||||
},
|
||||
}
|
||||
testTimestamp = metav1.Time{Time: time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC)}
|
||||
)
|
||||
|
||||
func initStatuses(resources []managedResource) []appv1.ResourceStatus {
|
||||
statuses := make([]appv1.ResourceStatus, len(resources))
|
||||
@@ -56,15 +67,24 @@ func TestSetApplicationHealth(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status)
|
||||
|
||||
assert.Equal(t, health.HealthStatusHealthy, resourceStatuses[0].Health.Status)
|
||||
assert.Equal(t, health.HealthStatusDegraded, resourceStatuses[1].Health.Status)
|
||||
// Health.LastTransitionTime is set only for app health and not at individual resource level
|
||||
assert.NotNil(t, healthStatus.LastTransitionTime)
|
||||
assert.Nil(t, resourceStatuses[0].Health.LastTransitionTime)
|
||||
assert.Nil(t, resourceStatuses[1].Health.LastTransitionTime)
|
||||
previousLastTransitionTime := healthStatus.LastTransitionTime
|
||||
app.Status.Health = *healthStatus
|
||||
|
||||
// now mark the job as a hook and retry. it should ignore the hook and consider the app healthy
|
||||
failedJob.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "PreSync"})
|
||||
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
|
||||
// change in health, timestamp should change
|
||||
assert.NotEqual(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
|
||||
previousLastTransitionTime = healthStatus.LastTransitionTime
|
||||
app.Status.Health = *healthStatus
|
||||
|
||||
// now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target.
|
||||
// The app is considered healthy
|
||||
@@ -74,6 +94,8 @@ func TestSetApplicationHealth(t *testing.T) {
|
||||
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
|
||||
// no change in health, timestamp shouldn't change
|
||||
assert.Equal(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
|
||||
@@ -102,6 +124,41 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
|
||||
assert.False(t, healthStatus.LastTransitionTime.IsZero())
|
||||
}
|
||||
|
||||
func TestSetApplicationHealth_HealthImproves(t *testing.T) {
|
||||
testCases := []struct {
|
||||
oldStatus health.HealthStatusCode
|
||||
newStatus health.HealthStatusCode
|
||||
}{
|
||||
{health.HealthStatusUnknown, health.HealthStatusDegraded},
|
||||
{health.HealthStatusDegraded, health.HealthStatusProgressing},
|
||||
{health.HealthStatusMissing, health.HealthStatusProgressing},
|
||||
{health.HealthStatusProgressing, health.HealthStatusSuspended},
|
||||
{health.HealthStatusSuspended, health.HealthStatusHealthy},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
overrides := lua.ResourceHealthOverrides{
|
||||
lua.GetConfigMapKey(schema.FromAPIVersionAndKind("v1", "Pod")): appv1.ResourceOverride{
|
||||
HealthLua: fmt.Sprintf("hs = {}\nhs.status = %q\nhs.message = \"\"return hs", tc.newStatus),
|
||||
},
|
||||
}
|
||||
|
||||
runningPod := resourceFromFile("./testdata/pod-running-restart-always.yaml")
|
||||
resources := []managedResource{{
|
||||
Group: "", Version: "v1", Kind: "Pod", Live: &runningPod,
|
||||
}}
|
||||
resourceStatuses := initStatuses(resources)
|
||||
|
||||
t.Run(string(fmt.Sprintf("%s to %s", tc.oldStatus, tc.newStatus)), func(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.newStatus, healthStatus.Status)
|
||||
assert.NotEqual(t, testTimestamp, *healthStatus.LastTransitionTime)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
|
||||
@@ -127,6 +184,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
|
||||
}, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
|
||||
assert.False(t, healthStatus.LastTransitionTime.IsZero())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -437,6 +437,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
|
||||
// return unknown comparison result if basic comparison settings cannot be loaded
|
||||
if err != nil {
|
||||
now := metav1.Now()
|
||||
if hasMultipleSources {
|
||||
return &comparisonResult{
|
||||
syncStatus: &v1alpha1.SyncStatus{
|
||||
@@ -444,7 +445,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
Status: v1alpha1.SyncStatusCodeUnknown,
|
||||
Revisions: revisions,
|
||||
},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
|
||||
}, nil
|
||||
} else {
|
||||
return &comparisonResult{
|
||||
@@ -453,7 +454,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
Status: v1alpha1.SyncStatusCodeUnknown,
|
||||
Revision: revisions[0],
|
||||
},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,6 +715,44 @@ func TestSetHealth(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
|
||||
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
|
||||
}
|
||||
|
||||
func TestPreserveStatusTimestamp(t *testing.T) {
|
||||
timestamp := metav1.Now()
|
||||
app := newFakeAppWithHealthAndTime(health.HealthStatusHealthy, timestamp)
|
||||
deployment := kube.MustToUnstructured(&v1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: "default",
|
||||
},
|
||||
})
|
||||
ctrl := newFakeController(&fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponse: &apiclient.ManifestResponse{
|
||||
Manifests: []string{},
|
||||
Namespace: test.FakeDestNamespace,
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
|
||||
kube.GetResourceKey(deployment): deployment,
|
||||
},
|
||||
}, nil)
|
||||
|
||||
sources := make([]argoappv1.ApplicationSource, 0)
|
||||
sources = append(sources, app.Spec.GetSource())
|
||||
revisions := make([]string, 0)
|
||||
revisions = append(revisions, "")
|
||||
compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
|
||||
assert.Equal(t, timestamp, *compRes.healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestSetHealthSelfReferencedApp(t *testing.T) {
|
||||
@@ -752,6 +790,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
|
||||
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
|
||||
}
|
||||
|
||||
func TestSetManagedResourcesWithOrphanedResources(t *testing.T) {
|
||||
@@ -827,6 +866,7 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status)
|
||||
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
|
||||
assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status)
|
||||
}
|
||||
|
||||
|
||||
BIN
docs/assets/keycloak-add-client-pkce_2.png
Normal file
BIN
docs/assets/keycloak-add-client-pkce_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/assets/keycloak-authentication-successful.png
Normal file
BIN
docs/assets/keycloak-authentication-successful.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/assets/keycloak-configure-client-pkce.png
Normal file
BIN
docs/assets/keycloak-configure-client-pkce.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
BIN
docs/assets/keycloak-configure-client-pkce_2.png
Normal file
BIN
docs/assets/keycloak-configure-client-pkce_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 83 KiB |
@@ -432,7 +432,7 @@ data:
|
||||
name: some-cluster
|
||||
server: https://some-cluster
|
||||
# The maximum size of the payload that can be sent to the webhook server.
|
||||
webhook.maxPayloadSizeMB: "1024"
|
||||
webhook.maxPayloadSizeMB: "50"
|
||||
|
||||
# application.sync.impersonation.enabled enables application sync to use a custom service account, via impersonation. This allows decoupling sync from control-plane service account.
|
||||
application.sync.impersonation.enabled: "false"
|
||||
|
||||
@@ -51,6 +51,8 @@ data:
|
||||
controller.self.heal.timeout.seconds: "2"
|
||||
controller.self.heal.backoff.factor: "3"
|
||||
controller.self.heal.backoff.cap.seconds: "300"
|
||||
# Specifies a sync timeout for applications. "0" means no timeout (default "0")
|
||||
controller.sync.timeout.seconds: "0"
|
||||
|
||||
# Cache expiration for app state (default 1h0m0s)
|
||||
controller.app.state.cache.expiration: "1h0m0s"
|
||||
|
||||
@@ -129,6 +129,20 @@ Scraped at the `argocd-repo-server:8084/metrics` endpoint.
|
||||
| `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. |
|
||||
| `argocd_repo_pending_request_total` | gauge | Number of pending requests requiring repository lock |
|
||||
|
||||
## Commit Server Metrics
|
||||
|
||||
Metrics about the Commit Server.
|
||||
Scraped at the `argocd-commit-server:8087/metrics` endpoint.
|
||||
|
||||
| Metric | Type | Description |
|
||||
|---------------------------------------------------------|:---------:|------------------------------------------------------|
|
||||
| `argocd_commitserver_commit_pending_request_total` | guage | Number of pending commit requests. |
|
||||
| `argocd_commitserver_git_request_duration_seconds` | histogram | Git requests duration seconds. |
|
||||
| `argocd_commitserver_git_request_total` | counter | Number of git requests performed by commit server |
|
||||
| `argocd_commitserver_commit_request_duration_seconds` | histogram | Commit requests duration seconds. |
|
||||
| `argocd_commitserver_userinfo_request_duration_seconds` | histogram | Userinfo requests duration seconds. |
|
||||
| `argocd_commitserver_commit_request_total` | counter | Number of commit requests performed by commit server |
|
||||
|
||||
## Prometheus Operator
|
||||
|
||||
If using Prometheus Operator, the following ServiceMonitor example manifests can be used.
|
||||
|
||||
@@ -77,6 +77,7 @@ argocd-application-controller [flags]
|
||||
--server-side-diff-enabled Feature flag to enable ServerSide diff. Default ("false")
|
||||
--sharding-method string Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin, consistent-hashing] (default "legacy")
|
||||
--status-processors int Number of application status processors (default 20)
|
||||
--sync-timeout int Specifies the timeout after which a sync would be terminated. 0 means no timeout (default 0).
|
||||
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
|
||||
--token string Bearer token for authentication to the API server
|
||||
--user string The name of the kubeconfig user to use
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
# Keycloak
|
||||
Keycloak and ArgoCD integration can be configured in two ways with Client authentication and with PKCE.
|
||||
|
||||
# Integrating Keycloak and ArgoCD
|
||||
If you need to authenticate with __argo-cd command line__, you must choose PKCE way.
|
||||
|
||||
* [Keycloak and ArgoCD with Client authentication](#keycloak-and-argocd-with-client-authentication)
|
||||
* [Keycloak and ArgoCD with PKCE](#keycloak-and-argocd-with-pkce)
|
||||
|
||||
## Keycloak and ArgoCD with Client authentication
|
||||
|
||||
These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak.
|
||||
|
||||
These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak.
|
||||
You will create a client within Keycloak and configure ArgoCD to use Keycloak for authentication, using groups set in Keycloak
|
||||
to determine privileges in Argo.
|
||||
|
||||
## Creating a new client in Keycloak
|
||||
### Creating a new client in Keycloak
|
||||
|
||||
First we need to setup a new client. Start by logging into your keycloak server, select the realm you want to use (`master` by default)
|
||||
First we need to setup a new client.
|
||||
|
||||
Start by logging into your keycloak server, select the realm you want to use (`master` by default)
|
||||
and then go to __Clients__ and click the __Create client__ button at the top.
|
||||
|
||||

|
||||
@@ -19,60 +28,26 @@ Enable the __Client authentication__.
|
||||
|
||||
Configure the client by setting the __Root URL__, __Web origins__, __Admin URL__ to the hostname (https://{hostname}).
|
||||
|
||||
Also you can set __Home URL__ to your _/applications_ path and __Valid Post logout redirect URIs__ to "+".
|
||||
Also you can set __Home URL__ to _/applications_ path and __Valid Post logout redirect URIs__ to "https://{hostname}/applications".
|
||||
|
||||
The Valid Redirect URIs should be set to https://{hostname}/auth/callback (you can also set the less secure https://{hostname}/* for testing/development purposes,
|
||||
but it's not recommended in production).
|
||||
|
||||

|
||||
|
||||
Make sure to click __Save__. There should be a tab called __Credentials__. You can copy the Secret that we'll use in our ArgoCD
|
||||
configuration.
|
||||
Make sure to click __Save__.
|
||||
|
||||
There should be a tab called __Credentials__. You can copy the Client Secret that we'll use in our ArgoCD configuration.
|
||||
|
||||

|
||||
|
||||
## Configuring the groups claim
|
||||
|
||||
In order for ArgoCD to provide the groups the user is in we need to configure a groups claim that can be included in the authentication token.
|
||||
To do this we'll start by creating a new __Client Scope__ called _groups_.
|
||||
|
||||

|
||||
|
||||
Once you've created the client scope you can now add a Token Mapper which will add the groups claim to the token when the client requests
|
||||
the groups scope. In the Tab "Mappers", click on "Configure a new mapper" and choose __Group Membership__.
|
||||
Make sure to set the __Name__ as well as the __Token Claim Name__ to _groups_. Also disable the "Full group path".
|
||||
|
||||

|
||||
|
||||
We can now configure the client to provide the _groups_ scope. Go back to the client we've created earlier and go to the Tab "Client Scopes".
|
||||
Click on "Add client scope", choose the _groups_ scope and add it either to the __Default__ or to the __Optional__ Client Scope. If you put it in the Optional
|
||||
category you will need to make sure that ArgoCD requests the scope in its OIDC configuration. Since we will always want group information, I recommend
|
||||
using the Default category.
|
||||
|
||||

|
||||
|
||||
Create a group called _ArgoCDAdmins_ and have your current user join the group.
|
||||
|
||||

|
||||
|
||||
## Configuring ArgoCD OIDC
|
||||
### Configuring ArgoCD OIDC
|
||||
|
||||
Let's start by storing the client secret you generated earlier in the argocd secret _argocd-secret_.
|
||||
|
||||
1. First you'll need to encode the client secret in base64: `$ echo -n '83083958-8ec6-47b0-a411-a8c55381fbd2' | base64`
|
||||
2. Then you can edit the secret and add the base64 value to a new key called _oidc.keycloak.clientSecret_ using `$ kubectl edit secret argocd-secret`.
|
||||
|
||||
Your Secret should look something like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: argocd-secret
|
||||
data:
|
||||
...
|
||||
oidc.keycloak.clientSecret: ODMwODM5NTgtOGVjNi00N2IwLWE0MTEtYThjNTUzODFmYmQy
|
||||
...
|
||||
You can patch it with value copied previously:
|
||||
```bash
|
||||
kubectl -n argo-cd patch secret argocd-secret --patch='{"stringData": { "oidc.keycloak.clientSecret": "<REPLACE_WITH_CLIENT_SECRET>" }}'
|
||||
```
|
||||
|
||||
Now we can configure the config map and add the oidc configuration to enable our keycloak authentication.
|
||||
@@ -103,7 +78,110 @@ Make sure that:
|
||||
- __clientSecret__ points to the right key you created in the _argocd-secret_ Secret
|
||||
- __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes
|
||||
|
||||
## Configuring ArgoCD Policy
|
||||
## Keycloak and ArgoCD with PKCE
|
||||
|
||||
These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak.
|
||||
|
||||
You will create a client within Keycloak and configure ArgoCD to use Keycloak for authentication, using groups set in Keycloak
|
||||
to determine privileges in Argo.
|
||||
|
||||
You will also be able to authenticate using argo-cd command line.
|
||||
|
||||
### Creating a new client in Keycloak
|
||||
|
||||
First we need to setup a new client.
|
||||
|
||||
Start by logging into your keycloak server, select the realm you want to use (`master` by default)
|
||||
and then go to __Clients__ and click the __Create client__ button at the top.
|
||||
|
||||

|
||||
|
||||
Leave default values.
|
||||
|
||||

|
||||
|
||||
Configure the client by setting the __Root URL__, __Web origins__, __Admin URL__ to the hostname (https://{hostname}).
|
||||
|
||||
Also you can set __Home URL__ to _/applications_ path and __Valid Post logout redirect URIs__ to "https://{hostname}/applications".
|
||||
|
||||
The Valid Redirect URIs should be set to:
|
||||
- http://localhost:8085/auth/callback (needed for argo-cd cli, depends on value from [--sso-port](../../user-guide/commands/argocd_login.md))
|
||||
- https://{hostname}/auth/callback
|
||||
- https://{hostname}/pkce/verify
|
||||
|
||||

|
||||
|
||||
Make sure to click __Save__.
|
||||
|
||||
Now go to a tab called __Advanced__, look for parameter named __Proof Key for Code Exchange Code Challenge Method__ and set it to __S256__
|
||||
|
||||

|
||||
Make sure to click __Save__.
|
||||
|
||||
### Configuring ArgoCD OIDC
|
||||
Now we can configure the config map and add the oidc configuration to enable our keycloak authentication.
|
||||
You can use `$ kubectl edit configmap argocd-cm`.
|
||||
|
||||
Your ConfigMap should look like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cm
|
||||
data:
|
||||
url: https://argocd.example.com
|
||||
oidc.config: |
|
||||
name: Keycloak
|
||||
issuer: https://keycloak.example.com/realms/master
|
||||
clientID: argocd
|
||||
enablePKCEAuthentication: true
|
||||
requestedScopes: ["openid", "profile", "email", "groups"]
|
||||
```
|
||||
|
||||
Make sure that:
|
||||
|
||||
- __issuer__ ends with the correct realm (in this example _master_)
|
||||
- __issuer__ on Keycloak releases older than version 17 the URL must include /auth (in this example /auth/realms/master)
|
||||
- __clientID__ is set to the Client ID you configured in Keycloak
|
||||
- __enablePKCEAuthentication__ must be set to true to enable correct ArgoCD behaviour with PKCE
|
||||
- __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes
|
||||
|
||||
## Configuring the groups claim
|
||||
|
||||
In order for ArgoCD to provide the groups the user is in we need to configure a groups claim that can be included in the authentication token.
|
||||
|
||||
To do this we'll start by creating a new __Client Scope__ called _groups_.
|
||||
|
||||

|
||||
|
||||
Once you've created the client scope you can now add a Token Mapper which will add the groups claim to the token when the client requests
|
||||
the groups scope.
|
||||
|
||||
In the Tab "Mappers", click on "Configure a new mapper" and choose __Group Membership__.
|
||||
|
||||
Make sure to set the __Name__ as well as the __Token Claim Name__ to _groups_. Also disable the "Full group path".
|
||||
|
||||

|
||||
|
||||
We can now configure the client to provide the _groups_ scope.
|
||||
|
||||
Go back to the client we've created earlier and go to the Tab "Client Scopes".
|
||||
|
||||
Click on "Add client scope", choose the _groups_ scope and add it either to the __Default__ or to the __Optional__ Client Scope.
|
||||
|
||||
If you put it in the Optional
|
||||
category you will need to make sure that ArgoCD requests the scope in its OIDC configuration.
|
||||
Since we will always want group information, I recommend
|
||||
using the Default category.
|
||||
|
||||

|
||||
|
||||
Create a group called _ArgoCDAdmins_ and have your current user join the group.
|
||||
|
||||

|
||||
|
||||
## Configuring ArgoCD Policy
|
||||
|
||||
Now that we have an authentication that provides groups we want to apply a policy to these groups.
|
||||
We can modify the _argocd-rbac-cm_ ConfigMap using `$ kubectl edit configmap argocd-rbac-cm`.
|
||||
@@ -126,8 +204,23 @@ You can now login using our new Keycloak OIDC authentication:
|
||||
|
||||

|
||||
|
||||
If you have used PKCE method, you can also authenticate using command line:
|
||||
```bash
|
||||
argocd login argocd.example.com --sso --grpc-web
|
||||
```
|
||||
|
||||
argocd cli will start to listen on localhost:8085 and open your web browser to allow you to authenticate with Keycloak.
|
||||
|
||||
Once done, you should see
|
||||
|
||||

|
||||
|
||||
## Troubleshoot
|
||||
If ArgoCD auth returns 401 or when the login attempt leads to the loop, then restart the argocd-server pod.
|
||||
```
|
||||
kubectl rollout restart deployment argocd-server -n argocd
|
||||
```
|
||||
|
||||
If you migrate from Client authentification to PKCE, you can have the following error `invalid_request: Missing parameter: code_challenge_method`.
|
||||
|
||||
It could be a redirect issue, try in private browsing or clean browser cookies.
|
||||
|
||||
@@ -19,7 +19,7 @@ URL configured in the Git provider should use the `/api/webhook` endpoint of you
|
||||
(e.g. `https://argocd.example.com/api/webhook`). If you wish to use a shared secret, input an
|
||||
arbitrary value in the secret. This value will be used when configuring the webhook in the next step.
|
||||
|
||||
To prevent DDoS attacks with unauthenticated webhook events (the `/api/webhook` endpoint currently lacks rate limiting protection), it is recommended to limit the payload size. You can achieve this by configuring the `argocd-cm` ConfigMap with the `webhook.maxPayloadSizeMB` attribute. The default value is 1GB.
|
||||
To prevent DDoS attacks with unauthenticated webhook events (the `/api/webhook` endpoint currently lacks rate limiting protection), it is recommended to limit the payload size. You can achieve this by configuring the `argocd-cm` ConfigMap with the `webhook.maxPayloadSizeMB` attribute. The default value is 50MB.
|
||||
|
||||
## Github
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ recent minor releases.
|
||||
| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 |
|
||||
| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 |
|
||||
| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 9 |
|
||||
| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 10 |
|
||||
| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](master/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
@@ -32,7 +32,7 @@ recent minor releases.
|
||||
| [dex:v2.41.1](v2.13.1/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 |
|
||||
| [haproxy:2.6.17-alpine](v2.13.1/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 |
|
||||
| [redis:7.0.15-alpine](v2.13.1/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [argocd:v2.13.1](v2.13.1/quay.io_argoproj_argocd_v2.13.1.html) | 0 | 0 | 4 | 9 |
|
||||
| [argocd:v2.13.1](v2.13.1/quay.io_argoproj_argocd_v2.13.1.html) | 0 | 0 | 3 | 10 |
|
||||
| [redis:7.0.15-alpine](v2.13.1/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v2.13.1/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v2.13.1/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
@@ -46,7 +46,7 @@ recent minor releases.
|
||||
| [dex:v2.38.0](v2.12.7/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 |
|
||||
| [haproxy:2.6.17-alpine](v2.12.7/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 |
|
||||
| [redis:7.0.15-alpine](v2.12.7/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [argocd:v2.12.7](v2.12.7/quay.io_argoproj_argocd_v2.12.7.html) | 0 | 0 | 4 | 10 |
|
||||
| [argocd:v2.12.7](v2.12.7/quay.io_argoproj_argocd_v2.12.7.html) | 0 | 0 | 3 | 11 |
|
||||
| [redis:7.0.15-alpine](v2.12.7/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v2.12.7/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v2.12.7/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
@@ -59,7 +59,7 @@ recent minor releases.
|
||||
| [ui/yarn.lock](v2.11.12/argocd-test.html) | 0 | 0 | 1 | 0 |
|
||||
| [dex:v2.38.0](v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 |
|
||||
| [haproxy:2.6.14-alpine](v2.11.12/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 7 |
|
||||
| [argocd:v2.11.12](v2.11.12/quay.io_argoproj_argocd_v2.11.12.html) | 0 | 0 | 5 | 19 |
|
||||
| [argocd:v2.11.12](v2.11.12/quay.io_argoproj_argocd_v2.11.12.html) | 0 | 0 | 4 | 20 |
|
||||
| [redis:7.0.15-alpine](v2.11.12/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v2.11.12/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v2.11.12/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:23:21 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:04 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
@@ -507,7 +507,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22702
|
||||
Line number: 22859
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -553,7 +553,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22383
|
||||
Line number: 22540
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -599,7 +599,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22470
|
||||
Line number: 22627
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -645,7 +645,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22498
|
||||
Line number: 22655
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -691,7 +691,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22528
|
||||
Line number: 22685
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -737,7 +737,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22546
|
||||
Line number: 22703
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -783,7 +783,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22564
|
||||
Line number: 22721
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -829,7 +829,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 22586
|
||||
Line number: 22743
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -881,7 +881,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23677
|
||||
Line number: 23833
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -933,7 +933,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23984
|
||||
Line number: 24140
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -991,7 +991,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23196
|
||||
Line number: 23352
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1049,7 +1049,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23479
|
||||
Line number: 23635
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1107,7 +1107,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23433
|
||||
Line number: 23589
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1165,7 +1165,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23541
|
||||
Line number: 23697
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1223,7 +1223,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23648
|
||||
Line number: 23804
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1281,7 +1281,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23672
|
||||
Line number: 23828
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1339,7 +1339,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23984
|
||||
Line number: 24140
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1397,7 +1397,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23731
|
||||
Line number: 23887
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1455,7 +1455,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24071
|
||||
Line number: 24227
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1513,7 +1513,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24463
|
||||
Line number: 24619
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1565,7 +1565,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23459
|
||||
Line number: 23615
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1617,7 +1617,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23196
|
||||
Line number: 23352
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1669,7 +1669,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23433
|
||||
Line number: 23589
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1721,7 +1721,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23648
|
||||
Line number: 23804
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1779,7 +1779,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23196
|
||||
Line number: 23352
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1837,7 +1837,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23433
|
||||
Line number: 23589
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1895,7 +1895,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23479
|
||||
Line number: 23635
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1953,7 +1953,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23541
|
||||
Line number: 23697
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2011,7 +2011,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23648
|
||||
Line number: 23804
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2069,7 +2069,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23672
|
||||
Line number: 23828
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2127,7 +2127,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23984
|
||||
Line number: 24140
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2185,7 +2185,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23731
|
||||
Line number: 23887
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2243,7 +2243,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24071
|
||||
Line number: 24227
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2301,7 +2301,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24463
|
||||
Line number: 24619
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2357,7 +2357,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23355
|
||||
Line number: 23511
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2413,7 +2413,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23487
|
||||
Line number: 23643
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2469,7 +2469,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23462
|
||||
Line number: 23618
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2525,7 +2525,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23580
|
||||
Line number: 23736
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2581,7 +2581,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23665
|
||||
Line number: 23821
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2637,7 +2637,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23679
|
||||
Line number: 23835
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2693,7 +2693,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23991
|
||||
Line number: 24147
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2749,7 +2749,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 23957
|
||||
Line number: 24113
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2805,7 +2805,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24362
|
||||
Line number: 24518
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -2861,7 +2861,7 @@
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 24684
|
||||
Line number: 24840
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:23:32 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:14 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:01 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:20:56 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -470,7 +470,7 @@
|
||||
<div class="meta-counts">
|
||||
<div class="meta-count"><span>7</span> <span>known vulnerabilities</span></div>
|
||||
<div class="meta-count"><span>26 vulnerable dependency paths</span></div>
|
||||
<div class="meta-count"><span>2150</span> <span>dependencies</span></div>
|
||||
<div class="meta-count"><span>2158</span> <span>dependencies</span></div>
|
||||
</div><!-- .meta-counts -->
|
||||
</div><!-- .layout-container--short -->
|
||||
</header><!-- .project__header -->
|
||||
@@ -504,7 +504,7 @@
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
|
||||
github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.1.4 and others
|
||||
github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.1.5 and others
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -518,9 +518,9 @@
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
github.com/argoproj/argo-cd/v2@0.0.0
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
github.com/Azure/kubelogin/pkg/token@0.1.4
|
||||
github.com/Azure/kubelogin/pkg/token@0.1.5
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
github.com/Azure/kubelogin/pkg/internal/token@0.1.4
|
||||
github.com/Azure/kubelogin/pkg/internal/token@0.1.5
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gopkg.in/retry.v1@1.0.3
|
||||
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:11 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:21:06 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:18 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:21:11 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:25 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:21:15 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:49 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:21:33 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -472,7 +472,7 @@
|
||||
<div class="meta-counts">
|
||||
<div class="meta-count"><span>20</span> <span>known vulnerabilities</span></div>
|
||||
<div class="meta-count"><span>100 vulnerable dependency paths</span></div>
|
||||
<div class="meta-count"><span>2359</span> <span>dependencies</span></div>
|
||||
<div class="meta-count"><span>2378</span> <span>dependencies</span></div>
|
||||
</div><!-- .meta-counts -->
|
||||
</div><!-- .layout-container--short -->
|
||||
</header><!-- .project__header -->
|
||||
@@ -707,6 +707,8 @@
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-10041">https://access.redhat.com/security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2319212">https://bugzilla.redhat.com/show_bug.cgi?id=2319212</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9941">https://access.redhat.com/errata/RHSA-2024:9941</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:10379">https://access.redhat.com/errata/RHSA-2024:10379</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -951,170 +953,6 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-PAM-8352843">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--medium">
|
||||
<span class="label__text">medium severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@latest and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">CVE-2024-26462</h2>
|
||||
@@ -2086,6 +1924,170 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-OPENSSL-7838291">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
<span class="label__text">low severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@latest and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@latest
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">CVE-2024-26458</h2>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:21:54 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:21:38 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:31:10 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:30:13 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:31:20 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:30:22 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:29:08 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:19 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:29:16 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:28 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -777,15 +777,15 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/01/09/1">http://www.openwall.com/lists/oss-security/2024/01/09/1</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35">https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04">https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015">https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015</a></li>
|
||||
<li><a href="https://www.openssl.org/news/secadv/20240109.txt">https://www.openssl.org/news/secadv/20240109.txt</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -2817,6 +2817,7 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="https://bugs.busybox.net/show_bug.cgi?id=15874">https://bugs.busybox.net/show_bug.cgi?id=15874</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20241206-0007/">https://security.netapp.com/advisory/ntap-20241206-0007/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:29:22 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:32 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
@@ -1032,15 +1032,15 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/01/09/1">http://www.openwall.com/lists/oss-security/2024/01/09/1</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35">https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04">https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015">https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015</a></li>
|
||||
<li><a href="https://www.openssl.org/news/secadv/20240109.txt">https://www.openssl.org/news/secadv/20240109.txt</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -1325,6 +1325,7 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="https://bugs.busybox.net/show_bug.cgi?id=15874">https://bugs.busybox.net/show_bug.cgi?id=15874</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20241206-0007/">https://security.netapp.com/advisory/ntap-20241206-0007/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:29:44 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:51 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -872,6 +872,8 @@
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-10041">https://access.redhat.com/security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2319212">https://bugzilla.redhat.com/show_bug.cgi?id=2319212</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9941">https://access.redhat.com/errata/RHSA-2024:9941</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:10379">https://access.redhat.com/errata/RHSA-2024:10379</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -1106,220 +1108,6 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2204-PAM-8352842">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--medium">
|
||||
<span class="label__text">medium severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:22.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12 and libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg-utils@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgsm@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@249.11-0ubuntu3.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:22.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:22.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2204-LIBGCRYPT20-6411451">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">CVE-2024-26462</h2>
|
||||
@@ -3631,6 +3419,220 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2204-LIBZSTD-3368800">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
<span class="label__text">low severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:22.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12 and libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg-utils@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gnupg@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgsm@2.2.27-3ubuntu2.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.11.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0@2.4.13
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@249.11-0ubuntu3.12
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.9.4-3ubuntu3
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:22.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:22.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2204-LIBGCRYPT20-6411451">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">Integer Overflow or Wraparound</h2>
|
||||
@@ -5105,7 +5107,7 @@
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">CVE-2024-9681</h2>
|
||||
<h2 class="card__title">Insufficient Comparison</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:29:49 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:55 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:28:35 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:27:55 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:28:46 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:28:04 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:26:24 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:25:56 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:26:34 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:26:04 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -777,15 +777,15 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/01/09/1">http://www.openwall.com/lists/oss-security/2024/01/09/1</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35">https://github.com/openssl/openssl/commit/050d26383d4e264966fb83428e72d5d48f402d35</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04">https://github.com/openssl/openssl/commit/5b139f95c9a47a55a0c54100f3837b1eee942b04</a></li>
|
||||
<li><a href="https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015">https://github.com/openssl/openssl/commit/f3fc5808fe9ff74042d639839610d03b8fdcc015</a></li>
|
||||
<li><a href="https://www.openssl.org/news/secadv/20240109.txt">https://www.openssl.org/news/secadv/20240109.txt</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240216-0009/">https://security.netapp.com/advisory/ntap-20240216-0009/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0008/">https://security.netapp.com/advisory/ntap-20240426-0008/</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240426-0013/">https://security.netapp.com/advisory/ntap-20240426-0013/</a></li>
|
||||
<li><a href="http://www.openwall.com/lists/oss-security/2024/03/11/1">http://www.openwall.com/lists/oss-security/2024/03/11/1</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20240503-0011/">https://security.netapp.com/advisory/ntap-20240503-0011/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -2817,6 +2817,7 @@
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="https://bugs.busybox.net/show_bug.cgi?id=15874">https://bugs.busybox.net/show_bug.cgi?id=15874</a></li>
|
||||
<li><a href="https://security.netapp.com/advisory/ntap-20241206-0007/">https://security.netapp.com/advisory/ntap-20241206-0007/</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:26:39 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:26:08 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:26:44 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:26:12 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:27:07 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:26:30 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -707,6 +707,8 @@
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-10041">https://access.redhat.com/security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2319212">https://bugzilla.redhat.com/show_bug.cgi?id=2319212</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9941">https://access.redhat.com/errata/RHSA-2024:9941</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:10379">https://access.redhat.com/errata/RHSA-2024:10379</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -951,170 +953,6 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-PAM-8352843">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--medium">
|
||||
<span class="label__text">medium severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.12.7/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7 and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">CVE-2024-26462</h2>
|
||||
@@ -2196,6 +2034,170 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-OPENSSL-7838291">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
<span class="label__text">low severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.12.7/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7 and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.12.7
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">CVE-2024-26458</h2>
|
||||
@@ -3072,7 +3074,7 @@
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">CVE-2024-9681</h2>
|
||||
<h2 class="card__title">Insufficient Comparison</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:27:13 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:26:35 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:25:52 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:25:26 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:26:02 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:25:35 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:23:46 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:27 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:23:53 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:34 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:23:58 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:37 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:24:02 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:41 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:24:22 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:23:59 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
@@ -707,6 +707,8 @@
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-10041">https://access.redhat.com/security/cve/CVE-2024-10041</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2319212">https://bugzilla.redhat.com/show_bug.cgi?id=2319212</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9941">https://access.redhat.com/errata/RHSA-2024:9941</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:10379">https://access.redhat.com/errata/RHSA-2024:10379</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@@ -951,170 +953,6 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-PAM-8352843">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--medium">
|
||||
<span class="label__text">medium severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.13.1/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1 and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
|
||||
<h2 class="card__title">CVE-2024-26462</h2>
|
||||
@@ -2086,6 +1924,170 @@
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-OPENSSL-7838291">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">Information Exposure</h2>
|
||||
<div class="card__section">
|
||||
|
||||
<div class="label label--low">
|
||||
<span class="label__text">low severity</span>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<ul class="card__meta">
|
||||
<li class="card__meta__item">
|
||||
Manifest file: quay.io/argoproj/argocd:v2.13.1/argoproj/argocd <span class="list-paths__item__arrow">›</span> Dockerfile
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Package Manager: ubuntu:24.04
|
||||
</li>
|
||||
<li class="card__meta__item">
|
||||
Vulnerable module:
|
||||
|
||||
libgcrypt20
|
||||
</li>
|
||||
|
||||
<li class="card__meta__item">Introduced through:
|
||||
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1 and libgcrypt20@1.10.3-2build1
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h3 class="card__section__title">Detailed paths</h3>
|
||||
|
||||
<ul class="card__meta__paths">
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/dirmngr@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg-agent@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt/libapt-pkg6.0t64@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgv@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpg@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
gnupg2/gpgconf@2.4.4-2ubuntu17
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="list-paths__item__introduced"><em>Introduced through</em>:
|
||||
docker-image|quay.io/argoproj/argocd@v2.13.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
apt@2.7.14build2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
adduser@3.137ubuntu1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
shadow/passwd@1:4.13+dfsg1-4ubuntu3.2
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
pam/libpam-modules@1.5.3-5ubuntu5.1
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
systemd/libsystemd0@255.4-1ubuntu8.4
|
||||
<span class="list-paths__item__arrow">›</span>
|
||||
libgcrypt20@1.10.3-2build1
|
||||
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul><!-- .list-paths -->
|
||||
|
||||
</div><!-- .card__section -->
|
||||
|
||||
<hr/>
|
||||
<!-- Overview -->
|
||||
<h2 id="nvd-description">NVD Description</h2>
|
||||
<p><strong><em>Note:</em></strong> <em>Versions mentioned in the description apply only to the upstream <code>libgcrypt20</code> package and not the <code>libgcrypt20</code> package as distributed by <code>Ubuntu</code>.</em>
|
||||
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
|
||||
<p>A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.</p>
|
||||
<h2 id="remediation">Remediation</h2>
|
||||
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libgcrypt20</code>.</p>
|
||||
<h2 id="references">References</h2>
|
||||
<ul>
|
||||
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://access.redhat.com/errata/RHSA-2024:9404">https://access.redhat.com/errata/RHSA-2024:9404</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2268268">https://bugzilla.redhat.com/show_bug.cgi?id=2268268</a></li>
|
||||
<li><a href="https://access.redhat.com/security/cve/CVE-2024-2236">https://access.redhat.com/security/cve/CVE-2024-2236</a></li>
|
||||
<li><a href="https://bugzilla.redhat.com/show_bug.cgi?id=2245218">https://bugzilla.redhat.com/show_bug.cgi?id=2245218</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="cta card__cta">
|
||||
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2404-LIBGCRYPT20-6693674">More about this vulnerability</a></p>
|
||||
</div>
|
||||
|
||||
</div><!-- .card -->
|
||||
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
|
||||
<h2 class="card__title">CVE-2024-26458</h2>
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">November 24th 2024, 12:24:27 am (UTC+00:00)</p>
|
||||
<p class="timestamp">December 8th 2024, 12:24:03 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following paths:</span>
|
||||
|
||||
@@ -12,13 +12,13 @@ argocd admin proj generate-spec PROJECT [flags]
|
||||
|
||||
```
|
||||
# Generate a YAML configuration for a project named "myproject"
|
||||
argocd admin projects generate-spec myproject
|
||||
argocd admin proj generate-spec myproject
|
||||
|
||||
# Generate a JSON configuration for a project named "anotherproject" and specify an output file
|
||||
argocd admin projects generate-spec anotherproject --output json --file config.json
|
||||
argocd admin proj generate-spec anotherproject --output json --file config.json
|
||||
|
||||
# Generate a YAML configuration for a project named "someproject" and write it back to the input file
|
||||
argocd admin projects generate-spec someproject --inline
|
||||
argocd admin proj generate-spec someproject --inline
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
@@ -12,10 +12,10 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags]
|
||||
|
||||
```
|
||||
# Add policy that allows executing any action (action/*) to roles which name matches to *deployer* in all projects
|
||||
argocd admin projects update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow
|
||||
argocd admin proj update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow
|
||||
|
||||
# Remove policy that which manages running (action/*) from all roles which name matches *deployer* in all projects
|
||||
argocd admin projects update-role-policy '*' remove override --role '*deployer*'
|
||||
argocd admin proj update-role-policy '*' remove override --role '*deployer*'
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -2,7 +2,31 @@
|
||||
|
||||
Sync windows are configurable windows of time where syncs will either be blocked or allowed. These are defined
|
||||
by a kind, which can be either `allow` or `deny`, a `schedule` in cron format and a duration along with one or
|
||||
more of either `applications`, `namespaces` and `clusters`. Wildcards are supported. These windows affect the running
|
||||
more of either `applications`, `namespaces` and `clusters`. Wildcards are supported.
|
||||
|
||||
## Relationship between Sync Windows and Applications
|
||||
|
||||
The relationship between Sync Windows and Application resources is many-to-many. This means that an Application resource
|
||||
may be affected by multiple Sync Windows, and that a single Sync Window definition may apply to multiple Application
|
||||
resources.
|
||||
|
||||
The relationship between Sync Window and Application is established as part of the definition of Sync Window.
|
||||
Sync Window definition includes a section defining the Application resources to which it applies. There
|
||||
are three mechanisms for selecting the Application resources to which a Sync Window applies:
|
||||
|
||||
- By name of Application resource
|
||||
- By cluster into which resources are installed by Application resource. This is specified by `Application.spec.destination.name` and `.server` fields
|
||||
- By namespace into which resources are installed by Application resource. This is specified by `Application.spec.destination.namespace` field.
|
||||
|
||||
All three mechanisms allow usage of wildcards. The mechanisms are not mutually exclusive, and all three of them can be used in single
|
||||
Sync Window definition.
|
||||
|
||||
When multiple selection mechanisms are used, they are effectively `ORed`, meaning that if any of the selector selects the Application,
|
||||
then the Application is affected by the Sync Window.
|
||||
|
||||
## Effect of Sync Windows
|
||||
|
||||
These windows affect the running
|
||||
of both manual and automated syncs but allow an override for manual syncs which is useful if you are only interested
|
||||
in preventing automated syncs or if you need to temporarily override a window to perform a sync.
|
||||
|
||||
|
||||
@@ -2883,7 +2883,7 @@
|
||||
"datasource": {
|
||||
"uid": "$datasource"
|
||||
},
|
||||
"expr": "go_memstats_heap_alloc_bytes{job=\"argocd-repo-server-metrics\",namespace=~\"$namespace\"}",
|
||||
"expr": "go_memstats_heap_alloc_bytes{job=\"argocd-server-metrics\",namespace=~\"$namespace\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{pod}}",
|
||||
@@ -2968,7 +2968,7 @@
|
||||
"datasource": {
|
||||
"uid": "$datasource"
|
||||
},
|
||||
"expr": "go_goroutines{job=\"argocd-repo-server-metrics\",namespace=~\"$namespace\"}",
|
||||
"expr": "go_goroutines{job=\"argocd-server-metrics\",namespace=~\"$namespace\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{pod}}",
|
||||
@@ -3270,7 +3270,7 @@
|
||||
"datasource": {
|
||||
"uid": "$datasource"
|
||||
},
|
||||
"expr": "go_gc_duration_seconds{job=\"argocd-repo-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}",
|
||||
"expr": "go_gc_duration_seconds{job=\"argocd-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{pod}}",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user