mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-22 10:38:51 +01:00
Compare commits
24 Commits
master
...
v2.6.0-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a9f37ca7d | ||
|
|
b357fd61c0 | ||
|
|
f8d275c50d | ||
|
|
053cfaf378 | ||
|
|
f869cc4feb | ||
|
|
fab4a3cb92 | ||
|
|
7dab9b23bf | ||
|
|
c8d010ceb0 | ||
|
|
3fa9a9197b | ||
|
|
af00900049 | ||
|
|
e67f4b151e | ||
|
|
3a8802f083 | ||
|
|
cdaf2b2c73 | ||
|
|
222cdf4711 | ||
|
|
c58d3843d5 | ||
|
|
383a65fe71 | ||
|
|
acfdc3d3be | ||
|
|
80f4ab9d7b | ||
|
|
44d13a73c9 | ||
|
|
a6469140b9 | ||
|
|
9a4179b1b6 | ||
|
|
0cd4854ffa | ||
|
|
81e40d53fe | ||
|
|
8532cfec4a |
34
.github/workflows/ci-build.yaml
vendored
34
.github/workflows/ci-build.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Download all Go modules
|
||||
@@ -47,11 +47,11 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Run golangci-lint
|
||||
@@ -96,7 +96,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@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -159,7 +159,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@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Install required packages
|
||||
@@ -179,7 +179,7 @@ jobs:
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
@@ -208,7 +208,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Create symlink in GOPATH
|
||||
@@ -257,7 +257,7 @@ jobs:
|
||||
node-version: '12.18.4'
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Restore node dependency cache
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ui/node_modules
|
||||
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -368,20 +368,12 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: GH actions workaround - Kill XSP4 process
|
||||
run: |
|
||||
sudo pkill mono || true
|
||||
# ubuntu-22.04 comes with kubectl, but the version is not pinned. The version as of 2022-12-05 is 1.26.0 which
|
||||
# breaks the `TestNamespacedResourceDiffing` e2e test. So we'll pin to 1.25 and then fix the underlying issue.
|
||||
- name: Install kubectl
|
||||
run: |
|
||||
rm /usr/local/bin/kubectl
|
||||
curl -LO https://dl.k8s.io/release/v1.25.4/bin/linux/amd64/kubectl
|
||||
mv kubectl /usr/local/bin/kubectl
|
||||
chmod +x /usr/local/bin/kubectl
|
||||
- name: Install K3S
|
||||
env:
|
||||
INSTALL_K3S_VERSION: ${{ matrix.k3s-version }}+k3s1
|
||||
@@ -394,7 +386,7 @@ jobs:
|
||||
sudo chown runner $HOME/.kube/config
|
||||
kubectl version
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
|
||||
uses: actions/cache@c17f4bf4666a8001b1a45c09eb7a485c41aa64c3 # v3.2.0
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
|
||||
13
.github/workflows/image.yaml
vendored
13
.github/workflows/image.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
env:
|
||||
GOPATH: /home/runner/work/argo-cd/argo-cd
|
||||
steps:
|
||||
- uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
- uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
|
||||
@@ -71,11 +71,18 @@ jobs:
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.8.1
|
||||
with:
|
||||
cosign-release: 'v1.13.0'
|
||||
cosign-release: 'v1.13.1'
|
||||
|
||||
- name: Install crane to get digest of image
|
||||
uses: imjasonh/setup-crane@e82f1b9a8007d399333baba4d75915558e9fb6a4
|
||||
|
||||
- name: Get digest of image
|
||||
run: |
|
||||
echo "IMAGE_DIGEST=$(crane digest quay.io/argoproj/argocd:latest)" >> $GITHUB_ENV
|
||||
|
||||
- name: Sign Argo CD latest image
|
||||
run: |
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/argocd:latest
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/argocd@${{ env.IMAGE_DIGEST }}
|
||||
# Displays the public key to share.
|
||||
cosign public-key --key env://COSIGN_PRIVATE_KEY
|
||||
env:
|
||||
|
||||
17
.github/workflows/release.yaml
vendored
17
.github/workflows/release.yaml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
- "!release-v0*"
|
||||
|
||||
env:
|
||||
GOLANG_VERSION: '1.18'
|
||||
GOLANG_VERSION: '1.18'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
echo "RELEASE_NOTES=${RELEASE_NOTES}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 # v3.4.0
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
|
||||
@@ -217,11 +217,18 @@ jobs:
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.8.1
|
||||
with:
|
||||
cosign-release: 'v1.13.0'
|
||||
cosign-release: 'v1.13.1'
|
||||
|
||||
- name: Install crane to get digest of image
|
||||
uses: imjasonh/setup-crane@e82f1b9a8007d399333baba4d75915558e9fb6a4
|
||||
|
||||
- name: Get digest of image
|
||||
run: |
|
||||
echo "IMAGE_DIGEST=$(crane digest quay.io/argoproj/argocd:v${TARGET_VERSION})" >> $GITHUB_ENV
|
||||
|
||||
- name: Sign Argo CD container images and assets
|
||||
run: |
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION}
|
||||
cosign sign --key env://COSIGN_PRIVATE_KEY ${IMAGE_NAMESPACE}/argocd@${{ env.IMAGE_DIGEST }}
|
||||
cosign sign-blob --key env://COSIGN_PRIVATE_KEY ./dist/argocd-${TARGET_VERSION}-checksums.txt > ./dist/argocd-${TARGET_VERSION}-checksums.sig
|
||||
# Retrieves the public key to release as an asset
|
||||
cosign public-key --key env://COSIGN_PRIVATE_KEY > ./dist/argocd-cosign.pub
|
||||
@@ -264,7 +271,7 @@ jobs:
|
||||
SIGS_BOM_VERSION: v0.2.1
|
||||
# comma delimited list of project relative folders to inspect for package
|
||||
# managers (gomod, yarn, npm).
|
||||
PROJECT_FOLDERS: ".,./ui"
|
||||
PROJECT_FOLDERS: ".,./ui"
|
||||
# full qualified name of the docker image to be inspected
|
||||
DOCKER_IMAGE: ${{env.IMAGE_NAMESPACE}}/argocd:v${{env.TARGET_VERSION}}
|
||||
run: |
|
||||
|
||||
@@ -207,7 +207,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json")
|
||||
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
|
||||
command.Flags().BoolVar(&dryRun, "dry-run", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN", false), "Enable dry run mode")
|
||||
command.Flags().BoolVar(&enableProgressiveRollouts, "enable-progressive-rollouts", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_ENABLE_PROGRESSIVE_ROLLOUTS", false), "Enable use of the experimental progressive rollouts feature.")
|
||||
command.Flags().BoolVar(&enableProgressiveRollouts, "enable-progressive-rollouts", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS", false), "Enable use of the experimental progressive rollouts feature.")
|
||||
return &command
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ spec:
|
||||
* `repo`: Required name of the GitHub repository.
|
||||
* `api`: If using GitHub Enterprise, the URL to access it. (Optional)
|
||||
* `tokenRef`: A `Secret` name and key containing the GitHub access token to use for requests. If not specified, will make anonymous requests which have a lower rate limit and can only see public repositories. (Optional)
|
||||
* `labels`: Labels is used to filter the PRs that you want to target. (Optional)
|
||||
* `labels`: Filter the PRs to those containing **all** of the labels listed. (Optional)
|
||||
* `appSecretName`: A `Secret` name containing a GitHub App secret in [repo-creds format][repo-creds].
|
||||
|
||||
[repo-creds]: ../declarative-setup.md#repository-credentials
|
||||
|
||||
@@ -12,8 +12,9 @@ The Progressive Rollouts feature set is intended to be light and flexible. The f
|
||||
|
||||
## Enabling Progressive Rollouts
|
||||
As an experimental feature, progressive rollouts must be explicitly enabled, in one of these ways.
|
||||
|
||||
1. Pass `--enable-progressive-rollouts` to the ApplicationSet controller args.
|
||||
1. Set `ARGOCD_APPLICATIONSET_ENABLE_PROGRESSIVE_ROLLOUTS=true` in the ApplicationSet controller environment variables.
|
||||
1. Set `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS=true` in the ApplicationSet controller environment variables.
|
||||
1. Set `applicationsetcontroller.enable.progressive.rollouts: true` in the ArgoCD ConfigMap.
|
||||
|
||||
## Strategies
|
||||
@@ -46,6 +47,7 @@ When the ApplicationSet changes, the changes will be applied to each group of Ap
|
||||
The following example illustrates how to stage a progressive rollout over Applications with explicitly configured environment labels.
|
||||
|
||||
Once a change is pushed, the following will happen in order.
|
||||
|
||||
* All `env-dev` Applications will be updated simultaneously.
|
||||
* The rollout will wait for all `env-qa` Applications to be manually synced via the `argocd` CLI or by clicking the Sync button in the UI.
|
||||
* 10% of all `env-prod` Applications will be updated at a time until all `env-prod` Applications have been updated.
|
||||
|
||||
@@ -47,7 +47,7 @@ data:
|
||||
help.download.windows-amd64: "path-or-url-to-download"
|
||||
|
||||
# A dex connector configuration (optional). See SSO configuration documentation:
|
||||
# https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/sso
|
||||
# https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/user-management/index.md#sso
|
||||
# https://dexidp.io/docs/connectors/
|
||||
dex.config: |
|
||||
connectors:
|
||||
@@ -330,4 +330,4 @@ data:
|
||||
resource.links: |
|
||||
- url: https://mycompany.splunk.com?search={{.metadata.namespace}}
|
||||
title: Splunk
|
||||
if: kind == "Pod" || kind == "Deployment"
|
||||
if: kind == "Pod" || kind == "Deployment"
|
||||
|
||||
@@ -51,7 +51,7 @@ following example builds an entirely customized repo-server from a Dockerfile, i
|
||||
dependencies that may be needed for generating manifests.
|
||||
|
||||
```Dockerfile
|
||||
FROM argoproj/argocd:latest
|
||||
FROM argoproj/argocd:v2.5.4 # Replace tag with the appropriate argo version
|
||||
|
||||
# Switch to root for the ability to perform install
|
||||
USER root
|
||||
|
||||
@@ -16,6 +16,8 @@ with at least one value for `hostname` or `IP`.
|
||||
### Ingress
|
||||
* The `status.loadBalancer.ingress` list is non-empty, with at least one value for `hostname` or `IP`.
|
||||
|
||||
### Job
|
||||
* If job `.spec.suspended` is set to 'true', then the job and app health will be marked as suspended.
|
||||
### PersistentVolumeClaim
|
||||
* The `status.phase` is `Bound`
|
||||
|
||||
@@ -38,7 +40,7 @@ metadata:
|
||||
data:
|
||||
resource.customizations: |
|
||||
argoproj.io/Application:
|
||||
health.lua: |
|
||||
health.lua: |
|
||||
hs = {}
|
||||
hs.status = "Progressing"
|
||||
hs.message = ""
|
||||
@@ -64,11 +66,11 @@ There are two ways to configure a custom health check. The next two sections des
|
||||
|
||||
### Way 1. Define a Custom Health Check in `argocd-cm` ConfigMap
|
||||
|
||||
Custom health checks can be defined in
|
||||
Custom health checks can be defined in
|
||||
```yaml
|
||||
resource.customizations: |
|
||||
<group/kind>:
|
||||
health.lua: |
|
||||
health.lua: |
|
||||
```
|
||||
field of `argocd-cm`. If you are using argocd-operator, this is overridden by [the argocd-operator resourceCustomizations](https://argocd-operator.readthedocs.io/en/latest/reference/argocd/#resource-customizations).
|
||||
|
||||
@@ -106,7 +108,7 @@ In order to prevent duplication of the same custom health check for potentially
|
||||
```yaml
|
||||
resource.customizations: |
|
||||
ec2.aws.crossplane.io/*:
|
||||
health.lua: |
|
||||
health.lua: |
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@ spec:
|
||||
- '*'
|
||||
|
||||
# Only permit applications to deploy to the guestbook namespace in the same cluster
|
||||
# Destination clusters can be identified by 'server', 'name', or both.
|
||||
destinations:
|
||||
- namespace: guestbook
|
||||
server: https://kubernetes.default.svc
|
||||
name: in-cluster
|
||||
|
||||
# Deny all cluster-scoped resources from being created, except for Namespace
|
||||
clusterResourceWhitelist:
|
||||
|
||||
@@ -6,3 +6,8 @@ Argo CD 2.5 introduced [Go templating in ApplicationSets](https://argo-cd.readth
|
||||
Argo CD 2.6 upgrades Sprig to v3. That upgrade includes an upgrade of [Masterminds/semver](https://github.com/Masterminds/semver/releases) to v3.
|
||||
|
||||
Masterminds/semver v3 changed the behavior of the `^` prefix in semantic version constraints. If you are using Go-templated ApplicationSets which include references to [Sprig's semver functions](https://masterminds.github.io/sprig/semver.html) and use the `^` prefix, read the [Masterminds/semver changelog](https://github.com/Masterminds/semver/releases/tag/v3.0.0) to understand how your ApplicationSets' behavior may change.
|
||||
|
||||
## Applications with suspended jobs now marked "Suspended" instead of "Progressing"
|
||||
Prior to Argo CD v2.6, an Application managing a suspended Job would be marked as "Progressing". This was confusing/unexpected behavior for many. Starting with v2.6, Argo CD will mark such Applications as "Suspended".
|
||||
|
||||
If you have processes which rely on the previous behavior (for example, a CI job with an argocd app wait call), update those before upgrading to v2.6.
|
||||
@@ -69,7 +69,7 @@ spec:
|
||||
source:
|
||||
repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||
targetRevision: HEAD
|
||||
path: guestbook-kustomize
|
||||
path: kustomize-guestbook
|
||||
|
||||
kustomize:
|
||||
version: v3.5.4
|
||||
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
sources:
|
||||
- chart: elasticsearch
|
||||
repoURL: https://helm.elastic.co
|
||||
targetRevision: 7.6.0
|
||||
targetRevision: 8.5.1
|
||||
- repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||
path: guestbook
|
||||
targetRevision: HEAD
|
||||
|
||||
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
github.com/Masterminds/semver/v3 v3.2.0
|
||||
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
|
||||
github.com/alicebob/miniredis/v2 v2.23.1
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6
|
||||
github.com/argoproj/pkg v0.13.7-0.20221115212233-27bd8ce31415
|
||||
github.com/aws/aws-sdk-go v1.44.156
|
||||
|
||||
4
go.sum
4
go.sum
@@ -137,8 +137,8 @@ github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96 h1:4CQn3gY9aAsQwHWGnADGyfGfBjE+yEw4zoy5SN7uuZc=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5 h1:iRpHi7X3q9G55KTaMjxKicgNnS2blFHaEfOOgsmP8lE=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6 h1:b92Xft7MQv/SP56FW08zt5CMTE1rySH8UPDKOAgSzOM=
|
||||
github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6/go.mod h1:pgPU59KCsBOMhyw9amRWPoSuBmUWvx3Xsc5r0mUriLg=
|
||||
github.com/argoproj/pkg v0.13.7-0.20221115212233-27bd8ce31415 h1:/5UtDHntvwPxbe/j2+xmQgvG83PQueGHko+9sf8+FA0=
|
||||
|
||||
@@ -86,6 +86,12 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- mountPath: /app/config/ssh
|
||||
name: ssh-known-hosts
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v2.6.0-rc2
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -15551,7 +15551,13 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -15815,7 +15821,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -15867,7 +15873,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -16074,7 +16080,7 @@ spec:
|
||||
key: application.namespaces
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v2.6.0-rc2
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v2.6.0-rc2
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -16793,7 +16793,13 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -16903,7 +16909,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -16956,7 +16962,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -17259,7 +17265,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -17311,7 +17317,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -17590,7 +17596,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -17826,7 +17832,7 @@ spec:
|
||||
key: application.namespaces
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -1597,7 +1597,13 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1707,7 +1713,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1760,7 +1766,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2063,7 +2069,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2115,7 +2121,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2394,7 +2400,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2630,7 +2636,7 @@ spec:
|
||||
key: application.namespaces
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -15871,7 +15871,13 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -15981,7 +15987,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -16034,7 +16040,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -16293,7 +16299,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -16345,7 +16351,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -16620,7 +16626,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -16854,7 +16860,7 @@ spec:
|
||||
key: application.namespaces
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -675,7 +675,13 @@ spec:
|
||||
key: applicationsetcontroller.enable.git.submodule
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.enable.progressive.rollouts
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -785,7 +791,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -838,7 +844,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1097,7 +1103,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1149,7 +1155,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1424,7 +1430,7 @@ spec:
|
||||
key: server.enable.proxy.extension
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1658,7 +1664,7 @@ spec:
|
||||
key: application.namespaces
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v2.6.0-rc2
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -47,6 +47,11 @@ type ApplicationSet struct {
|
||||
Status ApplicationSetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||
}
|
||||
|
||||
// RBACName formats fully qualified application name for RBAC check.
|
||||
func (a *ApplicationSet) RBACName() string {
|
||||
return fmt.Sprintf("%s/%s", a.Spec.Template.Spec.GetProject(), a.ObjectMeta.Name)
|
||||
}
|
||||
|
||||
// ApplicationSetSpec represents a class of application set state.
|
||||
type ApplicationSetSpec struct {
|
||||
GoTemplate bool `json:"goTemplate,omitempty" protobuf:"bytes,1,name=goTemplate"`
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/collections"
|
||||
"github.com/argoproj/argo-cd/v2/util/helm"
|
||||
"github.com/argoproj/argo-cd/v2/util/security"
|
||||
)
|
||||
|
||||
// Application is a definition of Application resource.
|
||||
@@ -2695,9 +2696,5 @@ func (a *Application) QualifiedName() string {
|
||||
// RBACName returns the full qualified RBAC resource name for the application
|
||||
// in a backwards-compatible way.
|
||||
func (a *Application) RBACName(defaultNS string) string {
|
||||
if defaultNS != "" && a.Namespace != defaultNS && a.Namespace != "" {
|
||||
return fmt.Sprintf("%s/%s/%s", a.Spec.GetProject(), a.Namespace, a.Name)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/%s", a.Spec.GetProject(), a.Name)
|
||||
}
|
||||
return security.AppRBACName(defaultNS, a.Spec.GetProject(), a.Namespace, a.Name)
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ func (s *Service) runRepoOperation(
|
||||
if hasMultipleSources && source.Path == "" && source.Chart == "" {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"source": source,
|
||||
}).Warnf("not generating manifests as path and chart fields are empty")
|
||||
}).Debugf("not generating manifests as path and chart fields are empty")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/lua"
|
||||
"github.com/argoproj/argo-cd/v2/util/manifeststream"
|
||||
"github.com/argoproj/argo-cd/v2/util/rbac"
|
||||
"github.com/argoproj/argo-cd/v2/util/security"
|
||||
"github.com/argoproj/argo-cd/v2/util/session"
|
||||
"github.com/argoproj/argo-cd/v2/util/settings"
|
||||
)
|
||||
@@ -210,7 +211,7 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
|
||||
appNs := s.appNamespaceOrDefault(a.Namespace)
|
||||
|
||||
if !s.isNamespaceEnabled(appNs) {
|
||||
return nil, namespaceNotPermittedError(appNs)
|
||||
return nil, security.NamespaceNotPermittedError(appNs)
|
||||
}
|
||||
|
||||
created, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Create(ctx, a, metav1.CreateOptions{})
|
||||
@@ -343,7 +344,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
|
||||
}
|
||||
|
||||
if !s.isNamespaceEnabled(a.Namespace) {
|
||||
return nil, namespaceNotPermittedError(a.Namespace)
|
||||
return nil, security.NamespaceNotPermittedError(a.Namespace)
|
||||
}
|
||||
|
||||
var manifestInfo *apiclient.ManifestResponse
|
||||
@@ -2350,9 +2351,5 @@ func (s *Server) appNamespaceOrDefault(appNs string) string {
|
||||
}
|
||||
|
||||
func (s *Server) isNamespaceEnabled(namespace string) bool {
|
||||
return namespace == s.ns || glob.MatchStringInList(s.enabledNamespaces, namespace, false)
|
||||
}
|
||||
|
||||
func namespaceNotPermittedError(namespace string) error {
|
||||
return fmt.Errorf("namespace '%s' is not permitted", namespace)
|
||||
return security.IsNamespaceEnabled(namespace, s.ns, s.enabledNamespaces)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@@ -24,6 +23,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
"github.com/argoproj/argo-cd/v2/util/db"
|
||||
"github.com/argoproj/argo-cd/v2/util/rbac"
|
||||
"github.com/argoproj/argo-cd/v2/util/security"
|
||||
sessionmgr "github.com/argoproj/argo-cd/v2/util/session"
|
||||
)
|
||||
|
||||
@@ -35,10 +35,11 @@ type terminalHandler struct {
|
||||
appResourceTreeFn func(ctx context.Context, app *appv1.Application) (*appv1.ApplicationTree, error)
|
||||
allowedShells []string
|
||||
namespace string
|
||||
enabledNamespaces []string
|
||||
}
|
||||
|
||||
// NewHandler returns a new terminal handler.
|
||||
func NewHandler(appLister applisters.ApplicationLister, namespace string, db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache,
|
||||
func NewHandler(appLister applisters.ApplicationLister, namespace string, enabledNamespaces []string, db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache,
|
||||
appResourceTree AppResourceTreeFn, allowedShells []string) *terminalHandler {
|
||||
return &terminalHandler{
|
||||
appLister: appLister,
|
||||
@@ -107,6 +108,8 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
appNamespace := q.Get("appNamespace")
|
||||
|
||||
if !isValidPodName(podName) {
|
||||
http.Error(w, "Pod name is not valid", http.StatusBadRequest)
|
||||
return
|
||||
@@ -127,11 +130,26 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Namespace name is not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !isValidNamespaceName(appNamespace) {
|
||||
http.Error(w, "App namespace name is not valid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
ns := appNamespace
|
||||
if ns == "" {
|
||||
ns = s.namespace
|
||||
}
|
||||
|
||||
if !security.IsNamespaceEnabled(ns, s.namespace, s.enabledNamespaces) {
|
||||
http.Error(w, security.NamespaceNotPermittedError(ns).Error(), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
shell := q.Get("shell") // No need to validate. Will only be used if it's in the allow-list.
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
appRBACName := fmt.Sprintf("%s/%s", project, app)
|
||||
appRBACName := security.AppRBACName(s.namespace, project, appNamespace, app)
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
@@ -143,9 +161,9 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
fieldLog := log.WithFields(log.Fields{"application": app, "userName": sessionmgr.Username(ctx), "container": container,
|
||||
"podName": podName, "namespace": namespace, "cluster": project})
|
||||
"podName": podName, "namespace": namespace, "project": project, "appNamespace": appNamespace})
|
||||
|
||||
a, err := s.appLister.Applications(s.namespace).Get(app)
|
||||
a, err := s.appLister.Applications(ns).Get(app)
|
||||
if err != nil {
|
||||
if apierr.IsNotFound(err) {
|
||||
http.Error(w, "App not found", http.StatusNotFound)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v2/util/security"
|
||||
)
|
||||
|
||||
func TestPodExists(t *testing.T) {
|
||||
@@ -195,24 +196,24 @@ func TestTerminalHandler_ServeHTTP_empty_params(t *testing.T) {
|
||||
for _, testValue := range testValues {
|
||||
testValueCopy := testValue
|
||||
|
||||
t.Run(testKeyCopy+ " " + testValueCopy, func(t *testing.T) {
|
||||
t.Run(testKeyCopy+" "+testValueCopy, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
handler := terminalHandler{}
|
||||
params := map[string]string{
|
||||
"pod": "valid",
|
||||
"pod": "valid",
|
||||
"container": "valid",
|
||||
"app": "valid",
|
||||
"project": "valid",
|
||||
"app": "valid",
|
||||
"project": "valid",
|
||||
"namespace": "valid",
|
||||
}
|
||||
params[testKeyCopy] = testValueCopy
|
||||
var paramsArray []string
|
||||
for key, value := range params {
|
||||
paramsArray = append(paramsArray, key + "=" + value)
|
||||
paramsArray = append(paramsArray, key+"="+value)
|
||||
}
|
||||
paramsString := strings.Join(paramsArray, "&")
|
||||
request := httptest.NewRequest("GET", "https://argocd.example.com/api/v1/terminal?" + paramsString, nil)
|
||||
request := httptest.NewRequest("GET", "https://argocd.example.com/api/v1/terminal?"+paramsString, nil)
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.ServeHTTP(recorder, request)
|
||||
response := recorder.Result()
|
||||
@@ -221,3 +222,13 @@ func TestTerminalHandler_ServeHTTP_empty_params(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTerminalHandler_ServeHTTP_disallowed_namespace(t *testing.T) {
|
||||
handler := terminalHandler{namespace: "argocd", enabledNamespaces: []string{"allowed"}}
|
||||
request := httptest.NewRequest("GET", "https://argocd.example.com/api/v1/terminal?pod=valid&container=valid&appName=valid&projectName=valid&namespace=test&appNamespace=disallowed", nil)
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.ServeHTTP(recorder, request)
|
||||
response := recorder.Result()
|
||||
assert.Equal(t, http.StatusForbidden, response.StatusCode)
|
||||
assert.Equal(t, security.NamespaceNotPermittedError("disallowed").Error()+"\n", recorder.Body.String())
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1"
|
||||
servercache "github.com/argoproj/argo-cd/v2/server/cache"
|
||||
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
|
||||
apputil "github.com/argoproj/argo-cd/v2/util/appset"
|
||||
"github.com/argoproj/argo-cd/v2/util/argo"
|
||||
argoutil "github.com/argoproj/argo-cd/v2/util/argo"
|
||||
"github.com/argoproj/argo-cd/v2/util/db"
|
||||
@@ -89,7 +88,7 @@ func (s *Server) Get(ctx context.Context, q *applicationset.ApplicationSetGetQue
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting ApplicationSet: %w", err)
|
||||
}
|
||||
if err = s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionGet, apputil.AppSetRBACName(a)); err != nil {
|
||||
if err = s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionGet, a.RBACName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -111,7 +110,7 @@ func (s *Server) List(ctx context.Context, q *applicationset.ApplicationSetListQ
|
||||
|
||||
newItems := make([]v1alpha1.ApplicationSet, 0)
|
||||
for _, a := range appsetList.Items {
|
||||
if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionGet, apputil.AppSetRBACName(&a)) {
|
||||
if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionGet, a.RBACName()) {
|
||||
newItems = append(newItems, a)
|
||||
}
|
||||
}
|
||||
@@ -182,7 +181,7 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre
|
||||
if !q.Upsert {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "existing ApplicationSet spec is different, use upsert flag to force update")
|
||||
}
|
||||
if err = s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionUpdate, apputil.AppSetRBACName(appset)); err != nil {
|
||||
if err = s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionUpdate, appset.RBACName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updated, err := s.updateAppSet(existing, appset, ctx, true)
|
||||
@@ -210,11 +209,11 @@ func (s *Server) updateAppSet(appset *v1alpha1.ApplicationSet, newAppset *v1alph
|
||||
if appset != nil && appset.Spec.Template.Spec.Project != newAppset.Spec.Template.Spec.Project {
|
||||
// When changing projects, caller must have applicationset create and update privileges in new project
|
||||
// NOTE: the update check was already verified in the caller to this function
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionCreate, apputil.AppSetRBACName(newAppset)); err != nil {
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionCreate, newAppset.RBACName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// They also need 'update' privileges in the old project
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionUpdate, apputil.AppSetRBACName(appset)); err != nil {
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionUpdate, appset.RBACName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -254,7 +253,7 @@ func (s *Server) Delete(ctx context.Context, q *applicationset.ApplicationSetDel
|
||||
return nil, fmt.Errorf("error getting ApplicationSets: %w", err)
|
||||
}
|
||||
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionDelete, apputil.AppSetRBACName(appset)); err != nil {
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionDelete, appset.RBACName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -290,7 +289,7 @@ func (s *Server) validateAppSet(ctx context.Context, appset *v1alpha1.Applicatio
|
||||
|
||||
func (s *Server) checkCreatePermissions(ctx context.Context, appset *v1alpha1.ApplicationSet, projectName string) error {
|
||||
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionCreate, apputil.AppSetRBACName(appset)); err != nil {
|
||||
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionCreate, appset.RBACName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -906,7 +906,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
}
|
||||
mux.Handle("/api/", handler)
|
||||
|
||||
terminalHandler := application.NewHandler(a.appLister, a.Namespace, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells)
|
||||
terminalHandler := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells)
|
||||
mux.HandleFunc("/terminal", func(writer http.ResponseWriter, request *http.Request) {
|
||||
argocdSettings, err := a.settingsMgr.GetSettings()
|
||||
if err != nil {
|
||||
|
||||
@@ -764,6 +764,17 @@ func TestNamespacedResourceDiffing(t *testing.T) {
|
||||
}).
|
||||
Given().
|
||||
When().
|
||||
// Now we migrate from client-side apply to server-side apply
|
||||
// This is necessary, as starting with kubectl 1.26, all previously
|
||||
// client-side owned fields have ownership migrated to the manager from
|
||||
// the first ssa.
|
||||
// More details: https://github.com/kubernetes/kubectl/issues/1337
|
||||
PatchApp(`[{
|
||||
"op": "add",
|
||||
"path": "/spec/syncPolicy",
|
||||
"value": { "syncOptions": ["ServerSideApply=true"] }
|
||||
}]`).
|
||||
Sync().
|
||||
And(func() {
|
||||
output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -742,6 +742,17 @@ func TestResourceDiffing(t *testing.T) {
|
||||
}).
|
||||
Given().
|
||||
When().
|
||||
// Now we migrate from client-side apply to server-side apply
|
||||
// This is necessary, as starting with kubectl 1.26, all previously
|
||||
// client-side owned fields have ownership migrated to the manager from
|
||||
// the first ssa.
|
||||
// More details: https://github.com/kubernetes/kubectl/issues/1337
|
||||
PatchApp(`[{
|
||||
"op": "add",
|
||||
"path": "/spec/syncPolicy",
|
||||
"value": { "syncOptions": ["ServerSideApply=true"] }
|
||||
}]`).
|
||||
Sync().
|
||||
And(func() {
|
||||
output, err := RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
|
||||
assert.NoError(t, err)
|
||||
|
||||
3
test/e2e/testdata/data.go
vendored
3
test/e2e/testdata/data.go
vendored
@@ -5,4 +5,7 @@ import _ "embed"
|
||||
var (
|
||||
//go:embed ssa-revision-history/deployment.yaml
|
||||
SSARevisionHistoryDeployment string
|
||||
|
||||
//go:embed guestbook/guestbook-ui-deployment.yaml
|
||||
GuestbookDeployment string
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {DropDownMenu, NotificationType, SlidingPanel} from 'argo-ui';
|
||||
import {DropDownMenu, NotificationType, SlidingPanel, Tooltip} from 'argo-ui';
|
||||
import * as classNames from 'classnames';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
@@ -24,7 +24,7 @@ import {ResourceDetails} from '../resource-details/resource-details';
|
||||
import * as AppUtils from '../utils';
|
||||
import {ApplicationResourceList} from './application-resource-list';
|
||||
import {Filters, FiltersProps} from './application-resource-filter';
|
||||
import {getAppDefaultSource, urlPattern} from '../utils';
|
||||
import {getAppDefaultSource, urlPattern, helpTip} from '../utils';
|
||||
import {ResourceStatus} from '../../../shared/models';
|
||||
import {ApplicationsDetailsAppDropdown} from './application-details-app-dropdown';
|
||||
import {useSidebarTarget} from '../../../sidebar/sidebar';
|
||||
@@ -613,6 +613,7 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
|
||||
const refreshing = app.metadata.annotations && app.metadata.annotations[appModels.AnnotationRefreshKey];
|
||||
const fullName = AppUtils.nodeKey({group: 'argoproj.io', kind: app.kind, name: app.metadata.name, namespace: app.metadata.namespace});
|
||||
const ActionMenuItem = (prop: {actionLabel: string}) => <span className={needOverlapLabelOnNarrowScreen ? 'show-for-large' : ''}>{prop.actionLabel}</span>;
|
||||
const hasMultipleSources = app.spec.sources && app.spec.sources.length > 0;
|
||||
return [
|
||||
{
|
||||
iconClassName: 'fa fa-info-circle',
|
||||
@@ -638,9 +639,18 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
|
||||
},
|
||||
{
|
||||
iconClassName: 'fa fa-history',
|
||||
title: <ActionMenuItem actionLabel='History and rollback' />,
|
||||
action: () => this.setRollbackPanelVisible(0),
|
||||
disabled: !app.status.operationState
|
||||
title: hasMultipleSources ? (
|
||||
<React.Fragment>
|
||||
<ActionMenuItem actionLabel=' History and rollback' />
|
||||
{helpTip('Rollback is not supported for apps with multiple sources')}
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<ActionMenuItem actionLabel='History and rollback' />
|
||||
),
|
||||
action: () => {
|
||||
this.setRollbackPanelVisible(0);
|
||||
},
|
||||
disabled: !app.status.operationState || hasMultipleSources
|
||||
},
|
||||
{
|
||||
iconClassName: 'fa fa-times-circle',
|
||||
|
||||
@@ -222,8 +222,8 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => {
|
||||
{
|
||||
title: 'PATH',
|
||||
view: (
|
||||
<Revision repoUrl={source.repoURL} revision={source.targetRevision || 'HEAD'} path={source.path}>
|
||||
{source.path}
|
||||
<Revision repoUrl={source.repoURL} revision={source.targetRevision || 'HEAD'} path={source.path} isForPath={true}>
|
||||
{source.path ?? ''}
|
||||
</Revision>
|
||||
),
|
||||
edit: (formApi: FormApi) => <FormField formApi={formApi} field='spec.source.path' component={Text} />
|
||||
|
||||
@@ -11,6 +11,7 @@ import {Context} from '../../../shared/context';
|
||||
import {ErrorNotification, NotificationType} from 'argo-ui';
|
||||
export interface PodTerminalViewerProps {
|
||||
applicationName: string;
|
||||
applicationNamespace: string;
|
||||
projectName: string;
|
||||
selectedNode: models.ResourceNode;
|
||||
podState: models.State;
|
||||
@@ -24,7 +25,15 @@ export interface ShellFrame {
|
||||
cols?: number;
|
||||
}
|
||||
|
||||
export const PodTerminalViewer: React.FC<PodTerminalViewerProps> = ({selectedNode, applicationName, projectName, podState, containerName, onClickContainer}) => {
|
||||
export const PodTerminalViewer: React.FC<PodTerminalViewerProps> = ({
|
||||
selectedNode,
|
||||
applicationName,
|
||||
applicationNamespace,
|
||||
projectName,
|
||||
podState,
|
||||
containerName,
|
||||
onClickContainer
|
||||
}) => {
|
||||
const terminalRef = React.useRef(null);
|
||||
const appContext = React.useContext(Context); // used to show toast
|
||||
const fitAddon = new FitAddon();
|
||||
@@ -145,7 +154,7 @@ export const PodTerminalViewer: React.FC<PodTerminalViewerProps> = ({selectedNod
|
||||
webSocket = new WebSocket(
|
||||
`${
|
||||
location.protocol === 'https:' ? 'wss' : 'ws'
|
||||
}://${url}/terminal?pod=${name}&container=${containerName}&appName=${applicationName}&projectName=${projectName}&namespace=${namespace}`
|
||||
}://${url}/terminal?pod=${name}&container=${containerName}&appName=${applicationName}&appNamespace=${applicationNamespace}&projectName=${projectName}&namespace=${namespace}`
|
||||
);
|
||||
webSocket.onopen = onConnectionOpen;
|
||||
webSocket.onclose = onConnectionClose;
|
||||
|
||||
@@ -129,6 +129,7 @@ export const ResourceDetails = (props: ResourceDetailsProps) => {
|
||||
content: (
|
||||
<PodTerminalViewer
|
||||
applicationName={application.metadata.name}
|
||||
applicationNamespace={application.metadata.namespace}
|
||||
projectName={application.spec.project}
|
||||
podState={podState}
|
||||
selectedNode={selectedNode}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import * as React from 'react';
|
||||
import {revisionUrl} from './urls';
|
||||
|
||||
export const Revision = ({repoUrl, revision, path, children}: {repoUrl: string; revision: string; path?: string; children?: React.ReactNode}) => {
|
||||
export const Revision = ({repoUrl, revision, path, isForPath, children}: {repoUrl: string; revision: string; path?: string; isForPath?: boolean; children?: React.ReactNode}) => {
|
||||
if (isForPath && !path) {
|
||||
// This source literally has no path, so we won't show one.
|
||||
return <span />;
|
||||
}
|
||||
revision = revision || '';
|
||||
const hasPath = path && path !== '.';
|
||||
let url = revisionUrl(repoUrl, revision, hasPath);
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package appset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
// AppRBACName formats fully qualified application name for RBAC check
|
||||
func AppSetRBACName(appSet *v1alpha1.ApplicationSet) string {
|
||||
return fmt.Sprintf("%s/%s", appSet.Spec.Template.Spec.GetProject(), appSet.ObjectMeta.Name)
|
||||
}
|
||||
@@ -348,9 +348,9 @@ func GetRefSources(ctx context.Context, spec argoappv1.ApplicationSpec, db db.Ar
|
||||
refKeys := make(map[string]bool)
|
||||
for _, source := range spec.Sources {
|
||||
if source.Ref != "" {
|
||||
isValidRefKey := regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString
|
||||
isValidRefKey := regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString
|
||||
if !isValidRefKey(source.Ref) {
|
||||
return nil, fmt.Errorf("source.ref %s cannot contain any special characters except '_' and '-'", source.Ref)
|
||||
return nil, fmt.Errorf("sources.ref %s cannot contain any special characters except '_' and '-'", source.Ref)
|
||||
}
|
||||
refKey := "$" + source.Ref
|
||||
if _, ok := refKeys[refKey]; ok {
|
||||
|
||||
@@ -1043,14 +1043,14 @@ func Test_GetRefSources(t *testing.T) {
|
||||
repoDB.On("GetRepository", context.Background(), repo.Repo).Return(repo, nil)
|
||||
|
||||
argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{
|
||||
{RepoURL: fmt.Sprintf("file://%s", repoPath), Ref: "source1"},
|
||||
{RepoURL: fmt.Sprintf("file://%s", repoPath), Ref: "source-1_2"},
|
||||
{RepoURL: fmt.Sprintf("file://%s", repoPath)},
|
||||
})
|
||||
|
||||
refSources, err := GetRefSources(context.TODO(), *argoSpec, repoDB)
|
||||
|
||||
expectedRefSource := argoappv1.RefTargetRevisionMapping{
|
||||
"$source1": &argoappv1.RefTarget{
|
||||
"$source-1_2": &argoappv1.RefTarget{
|
||||
Repo: *repo,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
"github.com/casbin/casbin/v2/util"
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
gocache "github.com/patrickmn/go-cache"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
|
||||
15
util/security/application_namespaces.go
Normal file
15
util/security/application_namespaces.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/argoproj/argo-cd/v2/util/glob"
|
||||
)
|
||||
|
||||
func IsNamespaceEnabled(namespace string, serverNamespace string, enabledNamespaces []string) bool {
|
||||
return namespace == serverNamespace || glob.MatchStringInList(enabledNamespaces, namespace, false)
|
||||
}
|
||||
|
||||
func NamespaceNotPermittedError(namespace string) error {
|
||||
return fmt.Errorf("namespace '%s' is not permitted", namespace)
|
||||
}
|
||||
62
util/security/application_namespaces_test.go
Normal file
62
util/security/application_namespaces_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_IsNamespaceEnabled(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
namespace string
|
||||
serverNamespace string
|
||||
enabledNamespaces []string
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
"namespace is empty",
|
||||
"argocd",
|
||||
"argocd",
|
||||
[]string{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"namespace is explicitly server namespace",
|
||||
"argocd",
|
||||
"argocd",
|
||||
[]string{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"namespace is allowed namespace",
|
||||
"allowed",
|
||||
"argocd",
|
||||
[]string{"allowed"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"namespace matches pattern",
|
||||
"test-ns",
|
||||
"argocd",
|
||||
[]string{"test-*"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"namespace is not allowed namespace",
|
||||
"disallowed",
|
||||
"argocd",
|
||||
[]string{"allowed"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tcc := tc
|
||||
t.Run(tcc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := IsNamespaceEnabled(tcc.namespace, tcc.serverNamespace, tcc.enabledNamespaces)
|
||||
assert.Equal(t, tcc.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
14
util/security/rbac.go
Normal file
14
util/security/rbac.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// AppRBACName constructs name of the app for use in RBAC checks.
|
||||
func AppRBACName(defaultNS string, project string, namespace string, name string) string {
|
||||
if defaultNS != "" && namespace != defaultNS && namespace != "" {
|
||||
return fmt.Sprintf("%s/%s/%s", project, namespace, name)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/%s", project, name)
|
||||
}
|
||||
}
|
||||
52
util/security/rbac_test.go
Normal file
52
util/security/rbac_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_AppRBACName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
defaultNS string
|
||||
project string
|
||||
namespace string
|
||||
appName string
|
||||
expectedResult string
|
||||
}{
|
||||
{
|
||||
"namespace is empty",
|
||||
"argocd",
|
||||
"default",
|
||||
"",
|
||||
"app",
|
||||
"default/app",
|
||||
},
|
||||
{
|
||||
"namespace is default namespace",
|
||||
"argocd",
|
||||
"default",
|
||||
"argocd",
|
||||
"app",
|
||||
"default/app",
|
||||
},
|
||||
{
|
||||
"namespace is not default namespace",
|
||||
"argocd",
|
||||
"default",
|
||||
"test",
|
||||
"app",
|
||||
"default/test/app",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tcc := tc
|
||||
t.Run(tcc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := AppRBACName(tcc.defaultNS, tcc.project, tcc.namespace, tcc.appName)
|
||||
assert.Equal(t, tcc.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user