mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
Compare commits
54 Commits
650fa6a10e
...
v3.0.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db93798d66 | ||
|
|
fc271d4f24 | ||
|
|
d98a0caf5e | ||
|
|
59d4519c61 | ||
|
|
0ef49b6a5a | ||
|
|
a31d5c915b | ||
|
|
f72ac787b6 | ||
|
|
001848ee69 | ||
|
|
5c24b6bd7a | ||
|
|
af9ebac0bb | ||
|
|
fe5869d59a | ||
|
|
0e20cb60a8 | ||
|
|
5328bd58e6 | ||
|
|
040ed44b20 | ||
|
|
c27a9d3360 | ||
|
|
a14b0125fe | ||
|
|
866db14e30 | ||
|
|
af3d9266a8 | ||
|
|
ddd6df5d44 | ||
|
|
927ed3504e | ||
|
|
b1cafa9d76 | ||
|
|
8a7c0f0c86 | ||
|
|
3fb34b99de | ||
|
|
90e9d1a5ad | ||
|
|
cca991a018 | ||
|
|
3d37cfac04 | ||
|
|
2bcef48772 | ||
|
|
cb5d6f5ef7 | ||
|
|
2913d5fcb5 | ||
|
|
edd2358f79 | ||
|
|
e98f483bfd | ||
|
|
e2250bad87 | ||
|
|
a444a05e8f | ||
|
|
f075c5acd3 | ||
|
|
f58b8070f1 | ||
|
|
b2e875323c | ||
|
|
6fea008447 | ||
|
|
ffbf9d5911 | ||
|
|
ebeae20ff4 | ||
|
|
3ae374ce22 | ||
|
|
3d2c010dbe | ||
|
|
b6e6104dbc | ||
|
|
a8ce6772b8 | ||
|
|
5d131c5251 | ||
|
|
d6a04a3642 | ||
|
|
4f37dd880a | ||
|
|
20f0fc6786 | ||
|
|
4ced513335 | ||
|
|
0d2471b3f9 | ||
|
|
226a670fe6 | ||
|
|
2933154a5c | ||
|
|
ba866bfc16 | ||
|
|
6e4c8fd53d | ||
|
|
15046b992e |
2
.github/workflows/ci-build.yaml
vendored
2
.github/workflows/ci-build.yaml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
env:
|
||||
# Golang version to use across CI steps
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.24.1'
|
||||
GOLANG_VERSION: '1.24.4'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
4
.github/workflows/image.yaml
vendored
4
.github/workflows/image.yaml
vendored
@@ -53,7 +53,7 @@ jobs:
|
||||
with:
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.24.1
|
||||
go-version: 1.24.4
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: false
|
||||
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.24.1
|
||||
go-version: 1.24.4
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: true
|
||||
secrets:
|
||||
|
||||
7
.github/workflows/release.yaml
vendored
7
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ permissions: {}
|
||||
|
||||
env:
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.24.1' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
GOLANG_VERSION: '1.24.4' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
|
||||
jobs:
|
||||
argocd-image:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.24.1
|
||||
go-version: 1.24.4
|
||||
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
|
||||
push: true
|
||||
secrets:
|
||||
@@ -77,7 +77,8 @@ jobs:
|
||||
- name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in release branches.
|
||||
run: |
|
||||
set -xue
|
||||
echo "GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }})" >> $GITHUB_ENV
|
||||
GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }}) || exit 1
|
||||
echo "GORELEASER_PREVIOUS_TAG=$GORELEASER_PREVIOUS_TAG" >> $GITHUB_ENV
|
||||
|
||||
- name: Set environment variables for ldflags
|
||||
id: set_ldflag
|
||||
|
||||
@@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b
|
||||
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
|
||||
# Also used as the image in CI jobs so needs all dependencies
|
||||
####################################################################################################
|
||||
FROM docker.io/library/golang:1.24.1@sha256:c5adecdb7b3f8c5ca3c88648a861882849cc8b02fed68ece31e25de88ad13418 AS builder
|
||||
FROM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS builder
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
@@ -103,7 +103,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
|
||||
####################################################################################################
|
||||
# Argo CD Build stage which performs the actual build of Argo CD binaries
|
||||
####################################################################################################
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.1@sha256:c5adecdb7b3f8c5ca3c88648a861882849cc8b02fed68ece31e25de88ad13418 AS argocd-build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS argocd-build
|
||||
|
||||
WORKDIR /go/src/github.com/argoproj/argo-cd
|
||||
|
||||
|
||||
1
Makefile
1
Makefile
@@ -486,6 +486,7 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local
|
||||
ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \
|
||||
ARGOCD_E2E_TEST=true \
|
||||
ARGOCD_HYDRATOR_ENABLED=true \
|
||||
ARGOCD_CLUSTER_CACHE_EVENTS_PROCESSING_INTERVAL=1ms \
|
||||
goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START}
|
||||
ls -lrt /tmp/coverage
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: gcr.io/heptio-images/ks-guestbook-demo
|
||||
repository: quay.io/argoprojlabs/argocd-e2e-container
|
||||
tag: 0.1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -26,7 +26,11 @@ func NewGithubService(token, url, owner, repo string, labels []string) (PullRequ
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
if token == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
} else {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -25,7 +25,11 @@ func NewGithubProvider(organization string, token string, url string, allBranche
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
if token == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
} else {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -68,6 +68,7 @@ func NewCommand() *cobra.Command {
|
||||
selfHealBackoffTimeoutSeconds int
|
||||
selfHealBackoffFactor int
|
||||
selfHealBackoffCapSeconds int
|
||||
selfHealBackoffCooldownSeconds int
|
||||
syncTimeout int
|
||||
statusProcessors int
|
||||
operationProcessors int
|
||||
@@ -201,6 +202,7 @@ func NewCommand() *cobra.Command {
|
||||
time.Duration(appResyncJitter)*time.Second,
|
||||
time.Duration(selfHealTimeoutSeconds)*time.Second,
|
||||
selfHealBackoff,
|
||||
time.Duration(selfHealBackoffCooldownSeconds)*time.Second,
|
||||
time.Duration(syncTimeout)*time.Second,
|
||||
time.Duration(repoErrorGracePeriod)*time.Second,
|
||||
metricsPort,
|
||||
@@ -272,6 +274,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(&selfHealBackoffCooldownSeconds, "self-heal-backoff-cooldown-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS", 330, 0, math.MaxInt32), "Specifies period of time the app needs to stay synced before the self heal backoff can reset")
|
||||
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")
|
||||
|
||||
@@ -99,7 +99,7 @@ func NewGenAppSpecCommand() *cobra.Command {
|
||||
argocd admin app generate-spec nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc
|
||||
|
||||
# Generate declarative config for a Kustomize app
|
||||
argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
|
||||
# Generate declarative config for a app using a custom tool:
|
||||
argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane
|
||||
@@ -389,7 +389,7 @@ func reconcileApplications(
|
||||
return true
|
||||
}, func(_ *http.Request) error {
|
||||
return nil
|
||||
}, []string{}, []string{})
|
||||
}, []string{}, []string{}, argoDB)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error starting new metrics server: %w", err)
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
|
||||
argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc
|
||||
|
||||
# Create a Kustomize app
|
||||
argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
|
||||
# Create a MultiSource app while yaml file contains an application with multiple sources
|
||||
argocd app create guestbook --file <path-to-yaml-file>
|
||||
|
||||
@@ -2,6 +2,10 @@ package apiclient
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/util/env"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
@@ -10,6 +14,9 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
// MaxGRPCMessageSize contains max grpc message size
|
||||
var MaxGRPCMessageSize = env.ParseNumFromEnv(common.EnvGRPCMaxSizeMB, 100, 0, math.MaxInt32) * 1024 * 1024
|
||||
|
||||
// Clientset represents commit server api clients
|
||||
type Clientset interface {
|
||||
NewCommitServerClient() (io.Closer, CommitServiceClient, error)
|
||||
|
||||
@@ -25,7 +25,7 @@ func NewServer(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *Arg
|
||||
|
||||
// CreateGRPC creates a new gRPC server.
|
||||
func (a *ArgoCDCommitServer) CreateGRPC() *grpc.Server {
|
||||
server := grpc.NewServer()
|
||||
server := grpc.NewServer(grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize))
|
||||
versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) {
|
||||
return true, nil
|
||||
}))
|
||||
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
commitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
@@ -133,6 +134,7 @@ type ApplicationController struct {
|
||||
statusRefreshJitter time.Duration
|
||||
selfHealTimeout time.Duration
|
||||
selfHealBackOff *wait.Backoff
|
||||
selfHealBackoffCooldown time.Duration
|
||||
syncTimeout time.Duration
|
||||
db db.ArgoDB
|
||||
settingsMgr *settings_util.SettingsManager
|
||||
@@ -168,6 +170,7 @@ func NewApplicationController(
|
||||
appResyncJitter time.Duration,
|
||||
selfHealTimeout time.Duration,
|
||||
selfHealBackoff *wait.Backoff,
|
||||
selfHealBackoffCooldown time.Duration,
|
||||
syncTimeout time.Duration,
|
||||
repoErrorGracePeriod time.Duration,
|
||||
metricsPort int,
|
||||
@@ -214,6 +217,7 @@ func NewApplicationController(
|
||||
settingsMgr: settingsMgr,
|
||||
selfHealTimeout: selfHealTimeout,
|
||||
selfHealBackOff: selfHealBackoff,
|
||||
selfHealBackoffCooldown: selfHealBackoffCooldown,
|
||||
syncTimeout: syncTimeout,
|
||||
clusterSharding: clusterSharding,
|
||||
projByNameCache: sync.Map{},
|
||||
@@ -321,7 +325,7 @@ func NewApplicationController(
|
||||
|
||||
metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort)
|
||||
|
||||
ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, readinessHealthCheck, metricsApplicationLabels, metricsApplicationConditions)
|
||||
ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, readinessHealthCheck, metricsApplicationLabels, metricsApplicationConditions, ctrl.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1571,7 +1575,16 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta
|
||||
messages = append(messages, "failed:", state.Message)
|
||||
}
|
||||
ctrl.logAppEvent(context.TODO(), app, eventInfo, strings.Join(messages, " "))
|
||||
ctrl.metricsServer.IncSync(app, state)
|
||||
|
||||
destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db)
|
||||
if err != nil {
|
||||
logCtx.Warnf("Unable to get destination cluster, setting dest_server label to empty string in sync metric: %v", err)
|
||||
}
|
||||
destServer := ""
|
||||
if destCluster != nil {
|
||||
destServer = destCluster.Server
|
||||
}
|
||||
ctrl.metricsServer.IncSync(app, destServer, state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1644,9 +1657,17 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
|
||||
startTime := time.Now()
|
||||
ts := stats.NewTimingStats()
|
||||
var destCluster *appv1.Cluster
|
||||
defer func() {
|
||||
reconcileDuration := time.Since(startTime)
|
||||
ctrl.metricsServer.IncReconcile(origApp, reconcileDuration)
|
||||
|
||||
// We may or may not get to the point in the code where destCluster is set. Populate the dest_server label on a
|
||||
// best-effort basis.
|
||||
destServer := ""
|
||||
if destCluster != nil {
|
||||
destServer = destCluster.Server
|
||||
}
|
||||
ctrl.metricsServer.IncReconcile(origApp, destServer, reconcileDuration)
|
||||
for k, v := range ts.Timings() {
|
||||
logCtx = logCtx.WithField(k, v.Milliseconds())
|
||||
}
|
||||
@@ -1659,7 +1680,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
|
||||
if comparisonLevel == ComparisonWithNothing {
|
||||
// If the destination cluster is invalid, fallback to the normal reconciliation flow
|
||||
if destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db); err == nil {
|
||||
if destCluster, err = argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db); err == nil {
|
||||
managedResources := make([]*appv1.ResourceDiff, 0)
|
||||
if err := ctrl.cache.GetAppManagedResources(app.InstanceName(ctrl.namespace), &managedResources); err == nil {
|
||||
var tree *appv1.ApplicationTree
|
||||
@@ -1681,11 +1702,9 @@ 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 {
|
||||
@@ -1698,7 +1717,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
return
|
||||
}
|
||||
|
||||
destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db)
|
||||
destCluster, err = argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db)
|
||||
if err != nil {
|
||||
logCtx.Errorf("Failed to get destination cluster: %v", err)
|
||||
// exit the reconciliation. ctrl.refreshAppConditions should have caught the error
|
||||
@@ -1782,6 +1801,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
ts.AddCheckpoint("auto_sync_ms")
|
||||
|
||||
if app.Status.ReconciledAt == nil || comparisonLevel >= CompareWithLatest {
|
||||
now := metav1.Now()
|
||||
app.Status.ReconciledAt = &now
|
||||
}
|
||||
app.Status.Sync = *compareResult.syncStatus
|
||||
@@ -2012,9 +2032,15 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new
|
||||
ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message)
|
||||
}
|
||||
if orig.Status.Health.Status != newStatus.Health.Status {
|
||||
now := metav1.Now()
|
||||
newStatus.Health.LastTransitionTime = &now
|
||||
message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status)
|
||||
ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message)
|
||||
} else {
|
||||
// make sure the last transition time is the same and populated if the health is the same
|
||||
newStatus.Health.LastTransitionTime = orig.Status.Health.LastTransitionTime
|
||||
}
|
||||
|
||||
var newAnnotations map[string]string
|
||||
if orig.GetAnnotations() != nil {
|
||||
newAnnotations = make(map[string]string)
|
||||
@@ -2240,17 +2266,22 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application, alread
|
||||
return true, time.Duration(0)
|
||||
}
|
||||
|
||||
// Reset counter if the prior sync was successful OR if the revision has changed
|
||||
if !alreadyAttempted || app.Status.Sync.Status == appv1.SyncStatusCodeSynced {
|
||||
var timeSinceOperation *time.Duration
|
||||
if app.Status.OperationState.FinishedAt != nil {
|
||||
timeSinceOperation = ptr.To(time.Since(app.Status.OperationState.FinishedAt.Time))
|
||||
}
|
||||
|
||||
// Reset counter if the prior sync was successful and the cooldown period is over OR if the revision has changed
|
||||
if !alreadyAttempted || (timeSinceOperation != nil && *timeSinceOperation >= ctrl.selfHealBackoffCooldown && app.Status.Sync.Status == appv1.SyncStatusCodeSynced) {
|
||||
app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount = 0
|
||||
}
|
||||
|
||||
var retryAfter time.Duration
|
||||
if ctrl.selfHealBackOff == nil {
|
||||
if app.Status.OperationState.FinishedAt == nil {
|
||||
if timeSinceOperation == nil {
|
||||
retryAfter = ctrl.selfHealTimeout
|
||||
} else {
|
||||
retryAfter = ctrl.selfHealTimeout - time.Since(app.Status.OperationState.FinishedAt.Time)
|
||||
retryAfter = ctrl.selfHealTimeout - *timeSinceOperation
|
||||
}
|
||||
} else {
|
||||
backOff := *ctrl.selfHealBackOff
|
||||
@@ -2260,10 +2291,11 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application, alread
|
||||
for i := 0; i < steps; i++ {
|
||||
delay = backOff.Step()
|
||||
}
|
||||
if app.Status.OperationState.FinishedAt == nil {
|
||||
|
||||
if timeSinceOperation == nil {
|
||||
retryAfter = delay
|
||||
} else {
|
||||
retryAfter = delay - time.Since(app.Status.OperationState.FinishedAt.Time)
|
||||
retryAfter = delay - *timeSinceOperation
|
||||
}
|
||||
}
|
||||
return retryAfter <= 0, retryAfter
|
||||
|
||||
@@ -172,6 +172,7 @@ func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration,
|
||||
time.Second,
|
||||
time.Minute,
|
||||
nil,
|
||||
time.Minute,
|
||||
0,
|
||||
time.Second*10,
|
||||
common.DefaultPortArgoCDMetrics,
|
||||
@@ -1826,7 +1827,7 @@ apps/Deployment:
|
||||
hs = {}
|
||||
hs.status = ""
|
||||
hs.message = ""
|
||||
|
||||
|
||||
if obj.metadata ~= nil then
|
||||
if obj.metadata.labels ~= nil then
|
||||
current_status = obj.metadata.labels["status"]
|
||||
@@ -2607,10 +2608,18 @@ func TestSelfHealExponentialBackoff(t *testing.T) {
|
||||
alreadyAttempted: false,
|
||||
expectedAttempts: 0,
|
||||
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
|
||||
}, {
|
||||
}, { // backoff will not reset as finished tme isn't >= cooldown
|
||||
attempts: 6,
|
||||
finishedAt: nil,
|
||||
expectedDuration: 0,
|
||||
finishedAt: ptr.To(metav1.Now()),
|
||||
expectedDuration: 120 * time.Second,
|
||||
shouldSelfHeal: false,
|
||||
alreadyAttempted: true,
|
||||
expectedAttempts: 6,
|
||||
syncStatus: v1alpha1.SyncStatusCodeSynced,
|
||||
}, { // backoff will reset as finished time is >= cooldown
|
||||
attempts: 40,
|
||||
finishedAt: &metav1.Time{Time: time.Now().Add(-(1 * time.Minute))},
|
||||
expectedDuration: -60 * time.Second,
|
||||
shouldSelfHeal: true,
|
||||
alreadyAttempted: true,
|
||||
expectedAttempts: 0,
|
||||
|
||||
6
controller/cache/cache.go
vendored
6
controller/cache/cache.go
vendored
@@ -242,6 +242,10 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
trackingMethod, err := c.settingsMgr.GetTrackingMethod()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installationID, err := c.settingsMgr.GetInstallationID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -267,7 +271,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
|
||||
ResourcesFilter: resourcesFilter,
|
||||
}
|
||||
|
||||
return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil
|
||||
return &cacheSettings{clusterSettings, appInstanceLabelKey, appv1.TrackingMethod(trackingMethod), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil
|
||||
}
|
||||
|
||||
func asResourceNode(r *clustercache.Resource) appv1.ResourceNode {
|
||||
|
||||
@@ -8,7 +8,6 @@ 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/v3/common"
|
||||
@@ -22,7 +21,9 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
|
||||
var savedErr error
|
||||
var errCount uint
|
||||
|
||||
appHealth := appv1.HealthStatus{Status: health.HealthStatusHealthy}
|
||||
appHealth := app.Status.Health.DeepCopy()
|
||||
appHealth.Status = health.HealthStatusHealthy
|
||||
|
||||
for i, res := range resources {
|
||||
if res.Target != nil && hookutil.Skip(res.Target) {
|
||||
continue
|
||||
@@ -82,18 +83,11 @@ 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
|
||||
}
|
||||
if savedErr != nil && errCount > 1 {
|
||||
savedErr = fmt.Errorf("see application-controller logs for %d other errors; most recent error was: %w", errCount-1, savedErr)
|
||||
}
|
||||
return &appHealth, savedErr
|
||||
return appHealth, savedErr
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ func TestSetApplicationHealth(t *testing.T) {
|
||||
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
|
||||
@@ -81,9 +80,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)
|
||||
// change in health, timestamp should change
|
||||
assert.NotEqual(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
|
||||
previousLastTransitionTime = healthStatus.LastTransitionTime
|
||||
// timestamp should be the same in case health did not change
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
app.Status.Health = *healthStatus
|
||||
|
||||
// now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target.
|
||||
@@ -94,8 +92,7 @@ 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)
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
|
||||
@@ -109,6 +106,7 @@ func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status)
|
||||
assert.NotNil(t, healthStatus.LastTransitionTime)
|
||||
|
||||
assert.Nil(t, resourceStatuses[0].Health)
|
||||
}
|
||||
@@ -124,7 +122,7 @@ 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())
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestSetApplicationHealth_HealthImproves(t *testing.T) {
|
||||
@@ -156,7 +154,7 @@ func TestSetApplicationHealth_HealthImproves(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)
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -173,6 +171,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
assert.Equal(t, health.HealthStatusMissing, resourceStatuses[0].Health.Status)
|
||||
})
|
||||
|
||||
@@ -184,7 +183,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())
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
applister "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/healthz"
|
||||
@@ -149,7 +150,7 @@ var (
|
||||
)
|
||||
|
||||
// NewMetricsServer returns a new prometheus server which collects application metrics
|
||||
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj any) bool, healthCheck func(r *http.Request) error, appLabels []string, appConditions []string) (*MetricsServer, error) {
|
||||
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj any) bool, healthCheck func(r *http.Request) error, appLabels []string, appConditions []string, db db.ArgoDB) (*MetricsServer, error) {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -175,7 +176,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
registry := NewAppRegistry(appLister, appFilter, appLabels, appConditions)
|
||||
registry := NewAppRegistry(appLister, appFilter, appLabels, appConditions, db)
|
||||
|
||||
mux.Handle(MetricsPath, promhttp.HandlerFor(prometheus.Gatherers{
|
||||
// contains app controller specific metrics
|
||||
@@ -235,11 +236,11 @@ func (m *MetricsServer) RegisterClustersInfoSource(ctx context.Context, source H
|
||||
}
|
||||
|
||||
// IncSync increments the sync counter for an application
|
||||
func (m *MetricsServer) IncSync(app *argoappv1.Application, state *argoappv1.OperationState) {
|
||||
func (m *MetricsServer) IncSync(app *argoappv1.Application, destServer string, state *argoappv1.OperationState) {
|
||||
if !state.Phase.Completed() {
|
||||
return
|
||||
}
|
||||
m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), app.Spec.Destination.Server, string(state.Phase)).Inc()
|
||||
m.syncCounter.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject(), destServer, string(state.Phase)).Inc()
|
||||
}
|
||||
|
||||
func (m *MetricsServer) IncKubectlExec(command string) {
|
||||
@@ -293,8 +294,8 @@ func (m *MetricsServer) ObserveResourceEventsProcessingDuration(server string, d
|
||||
}
|
||||
|
||||
// IncReconcile increments the reconcile counter for an application
|
||||
func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.Duration) {
|
||||
m.reconcileHistogram.WithLabelValues(app.Namespace, app.Spec.Destination.Server).Observe(duration.Seconds())
|
||||
func (m *MetricsServer) IncReconcile(app *argoappv1.Application, destServer string, duration time.Duration) {
|
||||
m.reconcileHistogram.WithLabelValues(app.Namespace, destServer).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// HasExpiration return true if expiration is set
|
||||
@@ -336,22 +337,24 @@ type appCollector struct {
|
||||
appFilter func(obj any) bool
|
||||
appLabels []string
|
||||
appConditions []string
|
||||
db db.ArgoDB
|
||||
}
|
||||
|
||||
// NewAppCollector returns a prometheus collector for application metrics
|
||||
func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string) prometheus.Collector {
|
||||
func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string, db db.ArgoDB) prometheus.Collector {
|
||||
return &appCollector{
|
||||
store: appLister,
|
||||
appFilter: appFilter,
|
||||
appLabels: appLabels,
|
||||
appConditions: appConditions,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// NewAppRegistry creates a new prometheus registry that collects applications
|
||||
func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string) *prometheus.Registry {
|
||||
func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj any) bool, appLabels []string, appConditions []string, db db.ArgoDB) *prometheus.Registry {
|
||||
registry := prometheus.NewRegistry()
|
||||
registry.MustRegister(NewAppCollector(appLister, appFilter, appLabels, appConditions))
|
||||
registry.MustRegister(NewAppCollector(appLister, appFilter, appLabels, appConditions, db))
|
||||
return registry
|
||||
}
|
||||
|
||||
@@ -375,7 +378,15 @@ func (c *appCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
}
|
||||
for _, app := range apps {
|
||||
if c.appFilter(app) {
|
||||
c.collectApps(ch, app)
|
||||
destCluster, err := argo.GetDestinationCluster(context.Background(), app.Spec.Destination, c.db)
|
||||
if err != nil {
|
||||
log.Warnf("Failed to get destination cluster for application %s: %v", app.Name, err)
|
||||
}
|
||||
destServer := ""
|
||||
if destCluster != nil {
|
||||
destServer = destCluster.Server
|
||||
}
|
||||
c.collectApps(ch, app, destServer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,7 +398,7 @@ func boolFloat64(b bool) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application) {
|
||||
func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application, destServer string) {
|
||||
addConstMetric := func(desc *prometheus.Desc, t prometheus.ValueType, v float64, lv ...string) {
|
||||
project := app.Spec.GetProject()
|
||||
lv = append([]string{app.Namespace, app.Name, project}, lv...)
|
||||
@@ -414,7 +425,7 @@ func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.A
|
||||
|
||||
autoSyncEnabled := app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.Automated != nil
|
||||
|
||||
addGauge(descAppInfo, 1, strconv.FormatBool(autoSyncEnabled), git.NormalizeGitURL(app.Spec.GetSource().RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation)
|
||||
addGauge(descAppInfo, 1, strconv.FormatBool(autoSyncEnabled), git.NormalizeGitURL(app.Spec.GetSource().RepoURL), destServer, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation)
|
||||
|
||||
if len(c.appLabels) > 0 {
|
||||
labelValues := []string{}
|
||||
|
||||
@@ -9,6 +9,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/db/mocks"
|
||||
|
||||
gitopsCache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -40,7 +44,7 @@ metadata:
|
||||
spec:
|
||||
destination:
|
||||
namespace: dummy-namespace
|
||||
server: https://localhost:6443
|
||||
name: cluster1
|
||||
project: important-project
|
||||
source:
|
||||
path: some/path
|
||||
@@ -65,7 +69,7 @@ metadata:
|
||||
spec:
|
||||
destination:
|
||||
namespace: dummy-namespace
|
||||
server: https://localhost:6443
|
||||
name: cluster1
|
||||
project: important-project
|
||||
source:
|
||||
path: some/path
|
||||
@@ -100,7 +104,7 @@ metadata:
|
||||
spec:
|
||||
destination:
|
||||
namespace: dummy-namespace
|
||||
server: https://localhost:6443
|
||||
name: cluster1
|
||||
project: important-project
|
||||
source:
|
||||
path: some/path
|
||||
@@ -129,7 +133,7 @@ metadata:
|
||||
spec:
|
||||
destination:
|
||||
namespace: dummy-namespace
|
||||
server: https://localhost:6443
|
||||
name: cluster1
|
||||
project: important-project
|
||||
source:
|
||||
path: some/path
|
||||
@@ -160,7 +164,7 @@ metadata:
|
||||
spec:
|
||||
destination:
|
||||
namespace: dummy-namespace
|
||||
server: https://localhost:6443
|
||||
name: cluster1
|
||||
source:
|
||||
path: some/path
|
||||
repoURL: https://github.com/argoproj/argocd-example-apps.git
|
||||
@@ -252,7 +256,10 @@ func runTest(t *testing.T, cfg TestMetricServerConfig) {
|
||||
t.Helper()
|
||||
cancel, appLister := newFakeLister(cfg.FakeAppYAMLs...)
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, cfg.AppLabels, cfg.AppConditions)
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
mockDB.On("GetClusterServersByName", mock.Anything, "cluster1").Return([]string{"https://localhost:6443"}, nil)
|
||||
mockDB.On("GetCluster", mock.Anything, "https://localhost:6443").Return(&argoappv1.Cluster{Name: "cluster1", Server: "https://localhost:6443"}, nil)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, cfg.AppLabels, cfg.AppConditions, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
if len(cfg.ClustersInfo) > 0 {
|
||||
@@ -402,7 +409,8 @@ argocd_app_condition{condition="ExcludedResourceWarning",name="my-app-4",namespa
|
||||
func TestMetricsSyncCounter(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
appSyncTotal := `
|
||||
@@ -414,11 +422,11 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa
|
||||
`
|
||||
|
||||
fakeApp := newFakeApp(fakeApp)
|
||||
metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationRunning})
|
||||
metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationFailed})
|
||||
metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationError})
|
||||
metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationSucceeded})
|
||||
metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationSucceeded})
|
||||
metricsServ.IncSync(fakeApp, "https://localhost:6443", &argoappv1.OperationState{Phase: common.OperationRunning})
|
||||
metricsServ.IncSync(fakeApp, "https://localhost:6443", &argoappv1.OperationState{Phase: common.OperationFailed})
|
||||
metricsServ.IncSync(fakeApp, "https://localhost:6443", &argoappv1.OperationState{Phase: common.OperationError})
|
||||
metricsServ.IncSync(fakeApp, "https://localhost:6443", &argoappv1.OperationState{Phase: common.OperationSucceeded})
|
||||
metricsServ.IncSync(fakeApp, "https://localhost:6443", &argoappv1.OperationState{Phase: common.OperationSucceeded})
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "/metrics", nil)
|
||||
require.NoError(t, err)
|
||||
@@ -455,7 +463,8 @@ func assertMetricsNotPrinted(t *testing.T, expectedLines, body string) {
|
||||
func TestReconcileMetrics(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
appReconcileMetrics := `
|
||||
@@ -473,7 +482,7 @@ argocd_app_reconcile_sum{dest_server="https://localhost:6443",namespace="argocd"
|
||||
argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argocd"} 1
|
||||
`
|
||||
fakeApp := newFakeApp(fakeApp)
|
||||
metricsServ.IncReconcile(fakeApp, 5*time.Second)
|
||||
metricsServ.IncReconcile(fakeApp, "https://localhost:6443", 5*time.Second)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "/metrics", nil)
|
||||
require.NoError(t, err)
|
||||
@@ -488,7 +497,8 @@ argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argoc
|
||||
func TestOrphanedResourcesMetric(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedMetrics := `
|
||||
@@ -513,7 +523,8 @@ argocd_app_orphaned_resources_count{name="my-app-4",namespace="argocd",project="
|
||||
func TestMetricsReset(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
appSyncTotal := `
|
||||
@@ -550,7 +561,8 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa
|
||||
func TestWorkqueueMetrics(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedMetrics := `
|
||||
@@ -585,7 +597,8 @@ workqueue_unfinished_work_seconds{controller="test",name="test"}
|
||||
func TestGoMetrics(t *testing.T) {
|
||||
cancel, appLister := newFakeLister()
|
||||
defer cancel()
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{})
|
||||
mockDB := mocks.NewArgoDB(t)
|
||||
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}, mockDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedMetrics := `
|
||||
|
||||
@@ -163,6 +163,11 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
|
||||
return nil, nil, false, fmt.Errorf("failed to get Helm settings: %w", err)
|
||||
}
|
||||
|
||||
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
|
||||
if err != nil {
|
||||
return nil, nil, false, fmt.Errorf("failed to get trackingMethod: %w", err)
|
||||
}
|
||||
|
||||
installationID, err := m.settingsMgr.GetInstallationID()
|
||||
if err != nil {
|
||||
return nil, nil, false, fmt.Errorf("failed to get installation ID: %w", err)
|
||||
@@ -249,7 +254,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
|
||||
ApplicationSource: &source,
|
||||
KubeVersion: serverVersion,
|
||||
ApiVersions: apiVersions,
|
||||
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
|
||||
TrackingMethod: trackingMethod,
|
||||
RefSources: refSources,
|
||||
HasMultipleSources: app.Spec.HasMultipleSources(),
|
||||
InstallationID: installationID,
|
||||
@@ -286,7 +291,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
|
||||
ApiVersions: apiVersions,
|
||||
VerifySignature: verifySignature,
|
||||
HelmRepoCreds: permittedHelmCredentials,
|
||||
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
|
||||
TrackingMethod: trackingMethod,
|
||||
EnabledSourceTypes: enabledSourceTypes,
|
||||
HelmOptions: helmOptions,
|
||||
HasMultipleSources: app.Spec.HasMultipleSources(),
|
||||
@@ -435,24 +440,28 @@ func normalizeClusterScopeTracking(targetObjs []*unstructured.Unstructured, info
|
||||
|
||||
// getComparisonSettings will return the system level settings related to the
|
||||
// diff/normalization process.
|
||||
func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, error) {
|
||||
func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, string, error) {
|
||||
resourceOverrides, err := m.settingsMgr.GetResourceOverrides()
|
||||
if err != nil {
|
||||
return "", nil, nil, "", err
|
||||
return "", nil, nil, "", "", err
|
||||
}
|
||||
appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey()
|
||||
if err != nil {
|
||||
return "", nil, nil, "", err
|
||||
return "", nil, nil, "", "", err
|
||||
}
|
||||
resFilter, err := m.settingsMgr.GetResourcesFilter()
|
||||
if err != nil {
|
||||
return "", nil, nil, "", err
|
||||
return "", nil, nil, "", "", err
|
||||
}
|
||||
installationID, err := m.settingsMgr.GetInstallationID()
|
||||
if err != nil {
|
||||
return "", nil, nil, "", err
|
||||
return "", nil, nil, "", "", err
|
||||
}
|
||||
return appLabelKey, resourceOverrides, resFilter, installationID, nil
|
||||
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
|
||||
if err != nil {
|
||||
return "", nil, nil, "", "", err
|
||||
}
|
||||
return appLabelKey, resourceOverrides, resFilter, installationID, trackingMethod, nil
|
||||
}
|
||||
|
||||
// verifyGnuPGSignature verifies the result of a GnuPG operation for a given git
|
||||
@@ -503,13 +512,12 @@ func isManagedNamespace(ns *unstructured.Unstructured, app *v1alpha1.Application
|
||||
// revision and overrides in the app spec.
|
||||
func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool, rollback bool) (*comparisonResult, error) {
|
||||
ts := stats.NewTimingStats()
|
||||
appLabelKey, resourceOverrides, resFilter, installationID, err := m.getComparisonSettings()
|
||||
appLabelKey, resourceOverrides, resFilter, installationID, trackingMethod, err := m.getComparisonSettings()
|
||||
|
||||
ts.AddCheckpoint("settings_ms")
|
||||
|
||||
// return unknown comparison result if basic comparison settings cannot be loaded
|
||||
if err != nil {
|
||||
now := metav1.Now()
|
||||
if hasMultipleSources {
|
||||
return &comparisonResult{
|
||||
syncStatus: &v1alpha1.SyncStatus{
|
||||
@@ -517,7 +525,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
Status: v1alpha1.SyncStatusCodeUnknown,
|
||||
Revisions: revisions,
|
||||
},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
|
||||
}, nil
|
||||
}
|
||||
return &comparisonResult{
|
||||
@@ -526,7 +534,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
Status: v1alpha1.SyncStatusCodeUnknown,
|
||||
Revision: revisions[0],
|
||||
},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
|
||||
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -615,10 +623,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
infoProvider = &resourceInfoProviderStub{}
|
||||
}
|
||||
|
||||
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
|
||||
|
||||
err = normalizeClusterScopeTracking(targetObjs, infoProvider, func(u *unstructured.Unstructured) error {
|
||||
return m.resourceTracking.SetAppInstance(u, appLabelKey, app.InstanceName(m.namespace), app.Spec.Destination.Namespace, trackingMethod, installationID)
|
||||
return m.resourceTracking.SetAppInstance(u, appLabelKey, app.InstanceName(m.namespace), app.Spec.Destination.Namespace, v1alpha1.TrackingMethod(trackingMethod), installationID)
|
||||
})
|
||||
if err != nil {
|
||||
msg := "Failed to normalize cluster-scoped resource tracking: " + err.Error()
|
||||
@@ -685,7 +691,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
|
||||
for _, liveObj := range liveObjByKey {
|
||||
if liveObj != nil {
|
||||
appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod, installationID)
|
||||
appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, v1alpha1.TrackingMethod(trackingMethod), installationID)
|
||||
if appInstanceName != "" && appInstanceName != app.InstanceName(m.namespace) {
|
||||
fqInstanceName := strings.ReplaceAll(appInstanceName, "_", "/")
|
||||
conditions = append(conditions, v1alpha1.ApplicationCondition{
|
||||
@@ -824,7 +830,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
|
||||
}
|
||||
gvk := obj.GroupVersionKind()
|
||||
|
||||
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), trackingMethod, installationID)
|
||||
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), v1alpha1.TrackingMethod(trackingMethod), installationID)
|
||||
|
||||
resState := v1alpha1.ResourceStatus{
|
||||
Namespace: obj.GetNamespace(),
|
||||
@@ -1148,7 +1154,7 @@ func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstruc
|
||||
|
||||
// If tracking method doesn't contain required metadata for this check,
|
||||
// we are not able to determine and just assume the object to be managed.
|
||||
if trackingMethod == argo.TrackingMethodLabel {
|
||||
if trackingMethod == v1alpha1.TrackingMethodLabel {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v3/test"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
)
|
||||
|
||||
// TestCompareAppStateEmpty tests comparison when both git and live have no objects
|
||||
@@ -719,7 +718,7 @@ func TestSetHealth(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
|
||||
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestPreserveStatusTimestamp(t *testing.T) {
|
||||
@@ -794,7 +793,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())
|
||||
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
|
||||
}
|
||||
|
||||
func TestSetManagedResourcesWithOrphanedResources(t *testing.T) {
|
||||
@@ -870,7 +869,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, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
|
||||
assert.Equal(t, v1alpha1.SyncStatusCodeUnknown, compRes.syncStatus.Status)
|
||||
}
|
||||
|
||||
@@ -1415,8 +1414,8 @@ func TestIsLiveResourceManaged(t *testing.T) {
|
||||
configObj := managedObj.DeepCopy()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
t.Run("will return true if tracked with label", func(t *testing.T) {
|
||||
// given
|
||||
@@ -1424,43 +1423,43 @@ func TestIsLiveResourceManaged(t *testing.T) {
|
||||
configObj := managedObjWithLabel.DeepCopy()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong resource name and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong resource group and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong kind and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
t.Run("will handle if trackingId has wrong namespace and config is nil", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, argo.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, argo.TrackingMethodAnnotationAndLabel, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, v1alpha1.TrackingMethodLabel, ""))
|
||||
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, v1alpha1.TrackingMethodAnnotationAndLabel, ""))
|
||||
})
|
||||
t.Run("will return true if live is nil", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
|
||||
t.Run("will handle upgrade in desired state APIGroup", func(t *testing.T) {
|
||||
@@ -1470,7 +1469,7 @@ func TestIsLiveResourceManaged(t *testing.T) {
|
||||
delete(config.GetAnnotations(), common.AnnotationKeyAppInstance)
|
||||
|
||||
// then
|
||||
assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, argo.TrackingMethodAnnotation, ""))
|
||||
assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, v1alpha1.TrackingMethodAnnotation, ""))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,11 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
log.Errorf("Could not get installation ID: %v", err)
|
||||
return
|
||||
}
|
||||
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
|
||||
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
|
||||
if err != nil {
|
||||
log.Errorf("Could not get trackingMethod: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
impersonationEnabled, err := m.settingsMgr.IsImpersonationEnabled()
|
||||
if err != nil {
|
||||
@@ -360,7 +364,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
return (len(syncOp.Resources) == 0 ||
|
||||
isPostDeleteHook(target) ||
|
||||
argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) &&
|
||||
m.isSelfReferencedObj(live, target, app.GetName(), trackingMethod, installationID)
|
||||
m.isSelfReferencedObj(live, target, app.GetName(), v1alpha1.TrackingMethod(trackingMethod), installationID)
|
||||
}),
|
||||
sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)),
|
||||
sync.WithSyncWaveHook(delayBetweenSyncWaves),
|
||||
|
||||
@@ -6,7 +6,7 @@ metadata:
|
||||
deployment.kubernetes.io/revision: '9'
|
||||
iksm-version: '2.0'
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}}
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}}
|
||||
creationTimestamp: '2022-01-05T15:45:21Z'
|
||||
generation: 119
|
||||
managedFields:
|
||||
@@ -137,7 +137,7 @@ spec:
|
||||
- env:
|
||||
- name: SOME_ENV_VAR
|
||||
value: some_value
|
||||
image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
|
||||
4
controller/testdata/live-deployment.yaml
vendored
4
controller/testdata/live-deployment.yaml
vendored
@@ -6,7 +6,7 @@ metadata:
|
||||
deployment.kubernetes.io/revision: '9'
|
||||
iksm-version: '2.0'
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}}
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"guestbook:apps/Deployment:default/kustomize-guestbook-ui","iksm-version":"2.0"},"name":"kustomize-guestbook-ui","namespace":"default"},"spec":{"replicas":4,"revisionHistoryLimit":3,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui"}},"spec":{"containers":[{"env":[{"name":"SOME_ENV_VAR","value":"some_value"}],"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-ui","ports":[{"containerPort":80}],"resources":{"requests":{"cpu":"50m","memory":"100Mi"}}}]}}}}
|
||||
creationTimestamp: '2022-01-05T15:45:21Z'
|
||||
generation: 119
|
||||
managedFields:
|
||||
@@ -137,7 +137,7 @@ spec:
|
||||
- env:
|
||||
- name: SOME_ENV_VAR
|
||||
value: some_value
|
||||
image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
|
||||
@@ -25,7 +25,7 @@ spec:
|
||||
value: yet_another_value
|
||||
- name: SOME_ENV_VAR
|
||||
value: different_value!
|
||||
image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -19,7 +19,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: guestbook-ui
|
||||
image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
env:
|
||||
- name: SOME_ENV_VAR
|
||||
value: some_value
|
||||
|
||||
2
controller/testdata/target-deployment.yaml
vendored
2
controller/testdata/target-deployment.yaml
vendored
@@ -21,7 +21,7 @@ spec:
|
||||
- env:
|
||||
- name: SOME_ENV_VAR
|
||||
value: some_value
|
||||
image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -127,7 +127,7 @@ spec:
|
||||
forceCommonLabels: false
|
||||
forceCommonAnnotations: false
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
- my-app=gcr.io/my-repo/my-app:0.1
|
||||
namespace: custom-namespace
|
||||
replicas:
|
||||
|
||||
@@ -71,6 +71,7 @@ argocd-application-controller [flags]
|
||||
--repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60)
|
||||
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
|
||||
--self-heal-backoff-cap-seconds int Specifies max timeout of exponential backoff between application self heal attempts (default 300)
|
||||
--self-heal-backoff-cooldown-seconds int Specifies period of time the app needs to stay synced before the self heal backoff can reset (default 330)
|
||||
--self-heal-backoff-factor int Specifies factor of exponential timeout between application self heal attempts (default 3)
|
||||
--self-heal-backoff-timeout-seconds int Specifies initial timeout of exponential backoff between self heal attempts (default 2)
|
||||
--self-heal-timeout-seconds int Specifies timeout between application self heal attempts
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
This page is populated for released Argo CD versions. Use the version selector to view this table for a specific
|
||||
version.
|
||||
| Argo CD version | Kubernetes versions |
|
||||
|-----------------|---------------------|
|
||||
| 3.0 | v1.32, v1.31, v1.30, v1.29 |
|
||||
| 2.14 | v1.31, v1.30, v1.29, v1.28 |
|
||||
| 2.13 | v1.30, v1.29, v1.28, v1.27 |
|
||||
|
||||
@@ -35,25 +35,27 @@ Starting from 3.0, this flag is removed and the logs RBAC is enforced by default
|
||||
|
||||
#### Detection
|
||||
|
||||
Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change.
|
||||
Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change.
|
||||
|
||||
Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected.
|
||||
Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected.
|
||||
|
||||
Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps.
|
||||
Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps.
|
||||
|
||||
After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade.
|
||||
After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade.
|
||||
|
||||
#### Remediation
|
||||
|
||||
##### Quick remediation (global change)
|
||||
For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:<YOUR_DEFAULT_ROLE>, logs, get, */*, allow`.
|
||||
For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer`
|
||||
##### Quick remediation (global change)
|
||||
|
||||
For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:<YOUR_DEFAULT_ROLE>, logs, get, */*, allow`.
|
||||
For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer`
|
||||
|
||||
##### Recommended remediation (per-policy change)
|
||||
Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`.
|
||||
This is the recommended way to maintain the principle of least privilege.
|
||||
Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level.
|
||||
See this [example](../upgrading/2.3-2.4.md#example-1) for more details.
|
||||
|
||||
Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`.
|
||||
This is the recommended way to maintain the principle of least privilege.
|
||||
Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level.
|
||||
See this [example](../upgrading/2.3-2.4.md#example-1) for more details.
|
||||
|
||||
### Default `resource.exclusions` configurations
|
||||
|
||||
@@ -63,7 +65,7 @@ which we exclude for performance reasons, reducing connections and load to the K
|
||||
|
||||
The excluded Kinds are:
|
||||
|
||||
- **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `APIService`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`.
|
||||
- **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`.
|
||||
- **Cert Manager**: `CertificateRequest`.
|
||||
- **Kyverno**: `EphemeralReport`, `ClusterEphemeralReport`, `AdmissionReport`, `ClusterAdmissionReport`, `BackgroundScanReport`, `ClusterBackgroundScanReport` and `UpdateRequest`.
|
||||
- **Cilium**: `CiliumIdentity`, `CiliumEndpoint` and `CiliumEndpointSlice`.
|
||||
@@ -133,7 +135,7 @@ been deprecated for some time and is no longer available in Argo CD 3.0.
|
||||
To check whether you have any repositories configured in argocd-cm, run the following command:
|
||||
|
||||
```shell
|
||||
kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository.credentials']}, {.data['helm.repositories']}]"
|
||||
kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository\.credentials']}, {.data['helm\.repositories']}]"
|
||||
```
|
||||
|
||||
If you have no repositories configured in argocd-cm, the output will be `[, , ]`, and you are not impacted by this
|
||||
@@ -216,26 +218,28 @@ spec:
|
||||
namespace: guestbook
|
||||
```
|
||||
|
||||
### Upgraded Helm version with breaking changes
|
||||
Helm was upgraded to 3.17.1.
|
||||
This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object.
|
||||
See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469)
|
||||
See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1)
|
||||
Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files)
|
||||
### Upgraded Helm version with breaking changes
|
||||
|
||||
Helm was upgraded to 3.17.1.
|
||||
This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object.
|
||||
See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469)
|
||||
See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1)
|
||||
Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files)
|
||||
Explanation:
|
||||
|
||||
- Prior to Helm 3.17.1, `null` object in `values.yaml` resulted in a warning: `cannot overwrite table with non table` upon performing `helm template`, and the resulting K8s object was not overridden with the invalid `null` value.
|
||||
- In Helm 3.17.1, this behavior changed and `null` object in `values.yaml` still results in this warning upon performing `helm template`, but the resulting K8s object will be overridden with the invalid `null` value.
|
||||
- To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values.
|
||||
- To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values.
|
||||
|
||||
### Use Annotation-Based Tracking by Default
|
||||
|
||||
The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based
|
||||
tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by
|
||||
The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based
|
||||
tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by
|
||||
external code copying tracking labels from one resource to another.
|
||||
|
||||
#### Detection
|
||||
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it
|
||||
unset or is set to `label`, you are using label-based tracking. If it is set to `annotation`, you are already using
|
||||
annotation-based tracking and are not impacted by this change.
|
||||
|
||||
@@ -315,6 +319,7 @@ Example of a status field in the Application CR persisting health:
|
||||
status:
|
||||
health:
|
||||
status: Healthy
|
||||
lastTransitionTime: '2025-01-01T00:00:00Z'
|
||||
resources:
|
||||
- group: apps
|
||||
health:
|
||||
@@ -334,6 +339,7 @@ Example of a status field in the Application CR _not_ persisting health:
|
||||
status:
|
||||
health:
|
||||
status: Healthy
|
||||
lastTransitionTime: '2025-01-01T00:00:00Z'
|
||||
resourceHealthSource: appTree
|
||||
resources:
|
||||
- group: apps
|
||||
@@ -367,6 +373,9 @@ kubectl get applications.argoproj.io <my app> -n argocd -o jsonpath='{.status.re
|
||||
|
||||
Any tools or CLI commands parsing the `.status.resources[].health` need to be updated to use the argocd cli/API to get the health status.
|
||||
|
||||
!!! note
|
||||
The application list API (argocd app list) no longer returns the individual health status of resources.
|
||||
|
||||
```sh
|
||||
argocd app get <my app> -o json
|
||||
```
|
||||
@@ -428,4 +437,30 @@ data:
|
||||
ignoreResourceStatusField: crd
|
||||
```
|
||||
|
||||
More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.
|
||||
### Removing default ignores of `preserveUnknownFields` for CRD
|
||||
|
||||
The `spec.preserveUnknownFields` has been deprecated in favor of `x-kubernetes-preserve-unknown-fields: true` in the CRD v1.
|
||||
|
||||
This means that CRD deployed with Argo CD containing `spec.preserveUnknownFields: false` will be out of sync. To address this problem,
|
||||
the `preserveUnknownFields` field can be removed from the CRD spec.
|
||||
|
||||
Until this is completed, if you want your Application not to be out of sync, you can add the following configuration to the Application manifest.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
ignoreDifferences:
|
||||
- group: apiextensions.k8s.io
|
||||
kind: CustomResourceDefinition
|
||||
jsonPointers:
|
||||
- /spec/preserveUnknownFields
|
||||
```
|
||||
|
||||
You can also configure it globally in the `argocd-cm` ConfigMap.
|
||||
|
||||
```yaml
|
||||
resource.customizations.ignoreDifferences.apiextensions.k8s.io_CustomResourceDefinition: |
|
||||
jsonPointers:
|
||||
- /spec/preserveUnknownFields
|
||||
```
|
||||
|
||||
More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.
|
||||
@@ -25,7 +25,7 @@ argocd admin app generate-spec APPNAME [flags]
|
||||
argocd admin app generate-spec nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc
|
||||
|
||||
# Generate declarative config for a Kustomize app
|
||||
argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
argocd admin app generate-spec kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
|
||||
# Generate declarative config for a app using a custom tool:
|
||||
argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane
|
||||
|
||||
2
docs/user-guide/commands/argocd_app_create.md
generated
2
docs/user-guide/commands/argocd_app_create.md
generated
@@ -24,7 +24,7 @@ argocd app create APPNAME [flags]
|
||||
argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc
|
||||
|
||||
# Create a Kustomize app
|
||||
argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
|
||||
# Create a MultiSource app while yaml file contains an application with multiple sources
|
||||
argocd app create guestbook --file <path-to-yaml-file>
|
||||
|
||||
@@ -65,7 +65,7 @@ Example:
|
||||
```yaml
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
```
|
||||
|
||||
The `.argocd-source` is trying to solve two following main use cases:
|
||||
|
||||
10
go.mod
10
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/argoproj/argo-cd/v3
|
||||
|
||||
go 1.24.1
|
||||
go 1.24.4
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.20.0
|
||||
@@ -12,7 +12,7 @@ require (
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/TomOnTime/utfutil v1.0.0
|
||||
github.com/alicebob/miniredis/v2 v2.34.0
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250314164314-7258614f5041
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872
|
||||
github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5
|
||||
github.com/aws/aws-sdk-go v1.55.6
|
||||
@@ -42,7 +42,7 @@ require (
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/btree v1.1.3
|
||||
github.com/google/go-cmp v0.7.0
|
||||
@@ -90,7 +90,7 @@ require (
|
||||
go.uber.org/automaxprocs v1.6.0
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
|
||||
golang.org/x/net v0.37.0
|
||||
golang.org/x/net v0.38.0
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/term v0.30.0
|
||||
@@ -185,7 +185,7 @@ require (
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang/glog v1.2.4 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@@ -114,8 +114,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250314164314-7258614f5041 h1:2QuxuGZ7ZLokBqmwr02MHhI2N3ffShms/IxSbvaFtVM=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250314164314-7258614f5041/go.mod h1:4KL2HCRSGA/yLM8nOCcv+NbFsYohxmT9Lb47kWFhWYw=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e h1:65x5+7Vz3HPjFoj7+mFyCckgHrAhPwy4rnDp/AveD18=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e/go.mod h1:duVhxDW7M7M7+19IBCVth2REOS11gmqzTWwj4u8N7aQ=
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872 h1:ADGAdyN9ty0+RmTT/yn+xV9vwkqvLn9O1ccqeP0Zeas=
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE=
|
||||
github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5 h1:YBoLSjpoaJXaXAldVvBRKJuOPvIXz9UOv6S96gMJM/Q=
|
||||
@@ -362,10 +362,10 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
|
||||
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
@@ -979,8 +979,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -52,61 +51,59 @@ func extractPatchAndRC(tag string) (string, string, error) {
|
||||
return patch, rc, nil
|
||||
}
|
||||
|
||||
func findPreviousTag(proposedTag string, tags []string) (string, error) {
|
||||
var previousTag string
|
||||
proposedMajor := semver.Major(proposedTag)
|
||||
proposedMinor := semver.MajorMinor(proposedTag)
|
||||
|
||||
proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// If the current tag is a .0 patch release or a 1 release candidate, adjust to the previous minor release series.
|
||||
if (proposedPatch == "0" && proposedRC == "0") || proposedRC == "1" {
|
||||
proposedMinorInt, err := strconv.Atoi(strings.TrimPrefix(proposedMinor, proposedMajor+"."))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid minor version: %v", err)
|
||||
}
|
||||
if proposedMinorInt > 0 {
|
||||
proposedMinor = fmt.Sprintf("%s.%d", proposedMajor, proposedMinorInt-1)
|
||||
}
|
||||
}
|
||||
|
||||
func removeInvalidTags(tags []string) []string {
|
||||
var validTags []string
|
||||
for _, tag := range tags {
|
||||
if tag == proposedTag {
|
||||
continue
|
||||
}
|
||||
tagMajor := semver.Major(tag)
|
||||
tagMinor := semver.MajorMinor(tag)
|
||||
tagPatch, tagRC, err := extractPatchAndRC(tag)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Only bother considering tags with the same major and minor version.
|
||||
if tagMajor == proposedMajor && tagMinor == proposedMinor {
|
||||
// If it's a non-RC release...
|
||||
if proposedRC == "0" {
|
||||
// Only consider non-RC tags.
|
||||
if tagRC == "0" {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if tagRC != "0" && tagPatch == proposedPatch {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
} else if tagRC == "0" {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, _, err := extractPatchAndRC(tag); err == nil {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func removeNewerOrEqualTags(proposedTag string, tags []string) []string {
|
||||
var validTags []string
|
||||
for _, tag := range tags {
|
||||
if semver.Compare(tag, proposedTag) < 0 {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func removeTagsFromSameMinorSeries(proposedTag string, tags []string) []string {
|
||||
var validTags []string
|
||||
proposedMinor := semver.MajorMinor(proposedTag)
|
||||
for _, tag := range tags {
|
||||
if semver.MajorMinor(tag) != proposedMinor {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func getMostRecentTag(tags []string) string {
|
||||
var mostRecentTag string
|
||||
for _, tag := range tags {
|
||||
if mostRecentTag == "" || semver.Compare(tag, mostRecentTag) > 0 {
|
||||
mostRecentTag = tag
|
||||
}
|
||||
}
|
||||
return mostRecentTag
|
||||
}
|
||||
|
||||
func findPreviousTag(proposedTag string, tags []string) (string, error) {
|
||||
tags = removeInvalidTags(tags)
|
||||
tags = removeNewerOrEqualTags(proposedTag, tags)
|
||||
|
||||
proposedPatch, proposedRC, _ := extractPatchAndRC(proposedTag) // Ignore the error, we already filtered out invalid tags.
|
||||
if proposedRC == "0" && proposedPatch == "0" {
|
||||
// If we're cutting the first patch of a new minor release series, don't consider tags in the same minor release
|
||||
// series. We want to compare to the latest tag in the previous minor release series.
|
||||
tags = removeTagsFromSameMinorSeries(proposedTag, tags)
|
||||
}
|
||||
|
||||
previousTag := getMostRecentTag(tags)
|
||||
if previousTag == "" {
|
||||
return "", fmt.Errorf("no matching tag found for tags: " + strings.Join(tags, ", "))
|
||||
}
|
||||
|
||||
@@ -76,6 +76,13 @@ func TestFindPreviousTagRules(t *testing.T) {
|
||||
{"Rule 3: 1 release candidate", "v2.14.0-rc1", "v2.13.0-rc3", false},
|
||||
// Rule 4: If we're releasing a non-1 release candidate, get the most recent rc tag on the current minor release series.
|
||||
{"Rule 4: non-1 release candidate", "v2.13.0-rc4", "v2.13.0-rc3", false},
|
||||
// Rule 5: If we're releasing a major version RC, get the most recent tag on the previous major release series.
|
||||
{"Rule 5: major version RC", "v3.0.0-rc1", "v2.13.0-rc3", false},
|
||||
// Rule 6: If we're releasing a major version, get the most recent tag on the previous major release series,
|
||||
// even if it's an RC.
|
||||
{"Rule 6: major version", "v3.0.0", "v2.13.0-rc3", false},
|
||||
// Rule 7: If the proposed tag already exists, don't return it.
|
||||
{"Rule 7: proposed tag already exists", "v2.12.5", "v2.12.4", false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -35,6 +35,10 @@ cd ${SRCROOT}/manifests/base && $KUSTOMIZE edit set image quay.io/argoproj/argoc
|
||||
cd ${SRCROOT}/manifests/ha/base && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
|
||||
cd ${SRCROOT}/manifests/core-install && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
|
||||
|
||||
# Because commit-server is added as a resource outside the base, we have to explicitly set the image override here.
|
||||
# If/when commit-server is added to the base, this can be removed.
|
||||
cd ${SRCROOT}/manifests/base/commit-server && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
|
||||
|
||||
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/install.yaml"
|
||||
$KUSTOMIZE build "${SRCROOT}/manifests/cluster-install" >> "${SRCROOT}/manifests/install.yaml"
|
||||
|
||||
|
||||
@@ -7,8 +7,9 @@ argocd_minor_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//')
|
||||
argocd_major_version_num=$(echo "$argocd_minor_version" | sed -E 's/\.[0-9]+//')
|
||||
argocd_minor_version_num=$(echo "$argocd_minor_version" | sed -E 's/[0-9]+\.//')
|
||||
|
||||
for n in 0 1 2; do
|
||||
minor_version_num=$((argocd_minor_version_num - n))
|
||||
minor_version_decrement=0
|
||||
for _ in {1..3}; do
|
||||
minor_version_num=$((argocd_minor_version_num - minor_version_decrement))
|
||||
minor_version="${argocd_major_version_num}.${minor_version_num}"
|
||||
git checkout "release-$minor_version" > /dev/null || exit 1
|
||||
|
||||
@@ -19,9 +20,22 @@ for n in 0 1 2; do
|
||||
jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"')
|
||||
out+="$line\n"
|
||||
|
||||
minor_version_decrement=$((minor_version_decrement + 1))
|
||||
|
||||
# If we're at minor version 0, there's no further version back in this series. Instead, move to the latest version in
|
||||
# the previous major release series.
|
||||
if [ "$argocd_minor_version_num" -eq 0 ]; then
|
||||
argocd_major_version_num=$((argocd_major_version_num - 1))
|
||||
# Get the latest minor version in the previous series.
|
||||
argocd_minor_version_num=$(git tag -l "v$argocd_major_version_num.*" | sort -V | tail -n 1 | sed -E 's/\.[0-9]+$//' | sed -E 's/^v[0-9]+\.//')
|
||||
|
||||
# Don't decrement the minor version, since we're switching to the previous major release series. We want the latest
|
||||
# minor version in that series.
|
||||
minor_version_decrement=0
|
||||
fi
|
||||
done
|
||||
|
||||
git checkout "release-$argocd_minor_version"
|
||||
|
||||
|
||||
printf "$out" > docs/operator-manual/tested-kubernetes-versions.md
|
||||
|
||||
@@ -121,6 +121,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
|
||||
@@ -124,6 +124,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
|
||||
@@ -6,3 +6,10 @@ resources:
|
||||
- argocd-commit-server-deployment.yaml
|
||||
- argocd-commit-server-service.yaml
|
||||
- argocd-commit-server-network-policy.yaml
|
||||
|
||||
# Because commit-server is added as a resource outside the base, we have to explicitly set the image override here.
|
||||
# If/when commit-server is added to the base, this can be removed.
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v3.0.6
|
||||
|
||||
@@ -70,10 +70,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.0.6
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
24
manifests/core-install-with-hydrator.yaml
generated
24
manifests/core-install-with-hydrator.yaml
generated
@@ -24217,10 +24217,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -24613,7 +24609,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24739,7 +24735,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -24785,7 +24781,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -24889,7 +24885,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25162,7 +25158,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25214,7 +25210,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25404,6 +25400,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -25544,7 +25546,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
20
manifests/core-install.yaml
generated
20
manifests/core-install.yaml
generated
@@ -24208,10 +24208,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -24581,7 +24577,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24701,7 +24697,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -24974,7 +24970,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25026,7 +25022,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25216,6 +25212,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -25356,7 +25358,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
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: v3.0.6
|
||||
|
||||
@@ -12,7 +12,7 @@ patches:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.0.6
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -701,6 +701,10 @@ data:
|
||||
stats enable
|
||||
stats uri /stats
|
||||
stats refresh 10s
|
||||
# Additional configuration
|
||||
global
|
||||
maxconn 4096
|
||||
|
||||
haproxy_init.sh: |
|
||||
HAPROXY_CONF=/data/haproxy.cfg
|
||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
||||
@@ -1092,7 +1096,7 @@ spec:
|
||||
prometheus.io/port: "9101"
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/path: "/metrics"
|
||||
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
|
||||
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
|
||||
spec:
|
||||
# Needed when using unmodified rbac-setup.yml
|
||||
|
||||
@@ -1101,7 +1105,7 @@ spec:
|
||||
fsGroup: 99
|
||||
runAsNonRoot: true
|
||||
runAsUser: 99
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
nodeSelector:
|
||||
{}
|
||||
tolerations:
|
||||
|
||||
@@ -21,6 +21,11 @@ redis-ha:
|
||||
checkInterval: 3s
|
||||
metrics:
|
||||
enabled: true
|
||||
extraConfig: |
|
||||
global
|
||||
maxconn 4096
|
||||
serviceAccount:
|
||||
automountToken: true
|
||||
image:
|
||||
tag: 7.2.7-alpine
|
||||
sentinel:
|
||||
|
||||
37
manifests/ha/install-with-hydrator.yaml
generated
37
manifests/ha/install-with-hydrator.yaml
generated
@@ -24626,10 +24626,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25043,7 +25039,8 @@ data:
|
||||
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
|
||||
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
|
||||
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
|
||||
Additional configuration\nglobal\n maxconn 4096\n"
|
||||
haproxy_init.sh: |
|
||||
HAPROXY_CONF=/data/haproxy.cfg
|
||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
||||
@@ -25978,7 +25975,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26104,7 +26101,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26150,7 +26147,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26277,7 +26274,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26373,7 +26370,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26433,7 +26430,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
|
||||
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "9101"
|
||||
prometheus.io/scrape: "true"
|
||||
@@ -26448,7 +26445,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -26497,7 +26494,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26796,7 +26793,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26848,7 +26845,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27222,7 +27219,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27448,6 +27445,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -27588,7 +27591,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
33
manifests/ha/install.yaml
generated
33
manifests/ha/install.yaml
generated
@@ -24617,10 +24617,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25034,7 +25030,8 @@ data:
|
||||
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
|
||||
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
|
||||
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
|
||||
Additional configuration\nglobal\n maxconn 4096\n"
|
||||
haproxy_init.sh: |
|
||||
HAPROXY_CONF=/data/haproxy.cfg
|
||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
||||
@@ -25948,7 +25945,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26091,7 +26088,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26187,7 +26184,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26247,7 +26244,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
|
||||
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "9101"
|
||||
prometheus.io/scrape: "true"
|
||||
@@ -26262,7 +26259,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -26311,7 +26308,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26610,7 +26607,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26662,7 +26659,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27036,7 +27033,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27262,6 +27259,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -27402,7 +27405,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
37
manifests/ha/namespace-install-with-hydrator.yaml
generated
37
manifests/ha/namespace-install-with-hydrator.yaml
generated
@@ -513,10 +513,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -930,7 +926,8 @@ data:
|
||||
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
|
||||
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
|
||||
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
|
||||
Additional configuration\nglobal\n maxconn 4096\n"
|
||||
haproxy_init.sh: |
|
||||
HAPROXY_CONF=/data/haproxy.cfg
|
||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
||||
@@ -1865,7 +1862,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1991,7 +1988,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2037,7 +2034,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2164,7 +2161,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2260,7 +2257,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2320,7 +2317,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
|
||||
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "9101"
|
||||
prometheus.io/scrape: "true"
|
||||
@@ -2335,7 +2332,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -2384,7 +2381,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2683,7 +2680,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2735,7 +2732,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -3109,7 +3106,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3335,6 +3332,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -3475,7 +3478,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
33
manifests/ha/namespace-install.yaml
generated
33
manifests/ha/namespace-install.yaml
generated
@@ -504,10 +504,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -921,7 +917,8 @@ data:
|
||||
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
|
||||
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
|
||||
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
|
||||
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
|
||||
Additional configuration\nglobal\n maxconn 4096\n"
|
||||
haproxy_init.sh: |
|
||||
HAPROXY_CONF=/data/haproxy.cfg
|
||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
||||
@@ -1835,7 +1832,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1978,7 +1975,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2074,7 +2071,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2134,7 +2131,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
|
||||
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "9101"
|
||||
prometheus.io/scrape: "true"
|
||||
@@ -2149,7 +2146,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -2198,7 +2195,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2497,7 +2494,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2549,7 +2546,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2923,7 +2920,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3149,6 +3146,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -3289,7 +3292,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
30
manifests/install-with-hydrator.yaml
generated
30
manifests/install-with-hydrator.yaml
generated
@@ -24577,10 +24577,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25073,7 +25069,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25199,7 +25195,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25245,7 +25241,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25372,7 +25368,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25468,7 +25464,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25570,7 +25566,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25843,7 +25839,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25895,7 +25891,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26267,7 +26263,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26493,6 +26489,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -26633,7 +26635,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
26
manifests/install.yaml
generated
26
manifests/install.yaml
generated
@@ -24568,10 +24568,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25041,7 +25037,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25184,7 +25180,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25280,7 +25276,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25382,7 +25378,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25655,7 +25651,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25707,7 +25703,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26079,7 +26075,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26305,6 +26301,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -26445,7 +26447,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
30
manifests/namespace-install-with-hydrator.yaml
generated
30
manifests/namespace-install-with-hydrator.yaml
generated
@@ -464,10 +464,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -960,7 +956,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1086,7 +1082,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1132,7 +1128,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1259,7 +1255,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1355,7 +1351,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1457,7 +1453,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1730,7 +1726,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1782,7 +1778,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2154,7 +2150,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2380,6 +2376,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -2520,7 +2522,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
26
manifests/namespace-install.yaml
generated
26
manifests/namespace-install.yaml
generated
@@ -455,10 +455,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -928,7 +924,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1071,7 +1067,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1167,7 +1163,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1269,7 +1265,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1542,7 +1538,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:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1594,7 +1590,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1966,7 +1962,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2192,6 +2188,12 @@ spec:
|
||||
key: controller.self.heal.backoff.cap.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: controller.self.heal.backoff.cooldown.seconds
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -2332,7 +2334,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.6
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -130,6 +130,7 @@ nav:
|
||||
- operator-manual/server-commands/additional-configuration-method.md
|
||||
- Upgrading:
|
||||
- operator-manual/upgrading/overview.md
|
||||
- operator-manual/upgrading/2.14-3.0.md
|
||||
- operator-manual/upgrading/2.13-2.14.md
|
||||
- operator-manual/upgrading/2.12-2.13.md
|
||||
- operator-manual/upgrading/2.11-2.12.md
|
||||
|
||||
@@ -102,6 +102,12 @@ func (id IgnoreDifferences) Equals(other IgnoreDifferences) bool {
|
||||
|
||||
type TrackingMethod string
|
||||
|
||||
const (
|
||||
TrackingMethodAnnotation TrackingMethod = "annotation"
|
||||
TrackingMethodLabel TrackingMethod = "label"
|
||||
TrackingMethodAnnotationAndLabel TrackingMethod = "annotation+label"
|
||||
)
|
||||
|
||||
// ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
|
||||
type ResourceIgnoreDifferences struct {
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
|
||||
|
||||
5
reposerver/cache/cache.go
vendored
5
reposerver/cache/cache.go
vendored
@@ -18,7 +18,6 @@ import (
|
||||
|
||||
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
cacheutil "github.com/argoproj/argo-cd/v3/util/cache"
|
||||
"github.com/argoproj/argo-cd/v3/util/env"
|
||||
"github.com/argoproj/argo-cd/v3/util/hash"
|
||||
@@ -305,7 +304,7 @@ func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs
|
||||
|
||||
func trackingKey(appLabelKey string, trackingMethod string) string {
|
||||
trackingKey := appLabelKey
|
||||
if text.FirstNonEmpty(trackingMethod, string(argo.TrackingMethodLabel)) != string(argo.TrackingMethodLabel) {
|
||||
if text.FirstNonEmpty(trackingMethod, string(appv1.TrackingMethodLabel)) != string(appv1.TrackingMethodLabel) {
|
||||
trackingKey = trackingMethod + ":" + trackingKey
|
||||
}
|
||||
return trackingKey
|
||||
@@ -399,7 +398,7 @@ func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource
|
||||
|
||||
func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, trackingMethod appv1.TrackingMethod, refSourceCommitSHAs ResolvedRevisions) string {
|
||||
if trackingMethod == "" {
|
||||
trackingMethod = argo.TrackingMethodLabel
|
||||
trackingMethod = appv1.TrackingMethodLabel
|
||||
}
|
||||
return fmt.Sprintf("appdetails|%s|%d|%s", revision, appSourceKey(appSrc, srcRefs, refSourceCommitSHAs), trackingMethod)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/TomOnTime/utfutil"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
textutils "github.com/argoproj/gitops-engine/pkg/utils/text"
|
||||
@@ -60,6 +59,7 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/util/kustomize"
|
||||
"github.com/argoproj/argo-cd/v3/util/manifeststream"
|
||||
"github.com/argoproj/argo-cd/v3/util/text"
|
||||
"github.com/argoproj/argo-cd/v3/util/versions"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -338,7 +338,7 @@ func (s *Service) runRepoOperation(
|
||||
|
||||
if source.IsHelm() {
|
||||
if settings.noCache {
|
||||
err = helmClient.CleanChartCache(source.Chart, revision, repo.Project)
|
||||
err = helmClient.CleanChartCache(source.Chart, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -347,7 +347,7 @@ func (s *Service) runRepoOperation(
|
||||
if source.Helm != nil {
|
||||
helmPassCredentials = source.Helm.PassCredentials
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, repo.Project, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1155,7 +1155,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
|
||||
referencedSource := getReferencedSource(p.Path, q.RefSources)
|
||||
if referencedSource != nil {
|
||||
// If the $-prefixed path appears to reference another source, do env substitution _after_ resolving the source
|
||||
resolvedPath, err = getResolvedRefValueFile(p.Path, env, q.GetValuesFileSchemes(), referencedSource.Repo.Repo, gitRepoPaths, referencedSource.Repo.Project)
|
||||
resolvedPath, err = getResolvedRefValueFile(p.Path, env, q.GetValuesFileSchemes(), referencedSource.Repo.Repo, gitRepoPaths)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error resolving set-file path: %w", err)
|
||||
}
|
||||
@@ -1276,7 +1276,7 @@ func getResolvedValueFiles(
|
||||
referencedSource := getReferencedSource(rawValueFile, refSources)
|
||||
if referencedSource != nil {
|
||||
// If the $-prefixed path appears to reference another source, do env substitution _after_ resolving that source.
|
||||
resolvedPath, err = getResolvedRefValueFile(rawValueFile, env, allowedValueFilesSchemas, referencedSource.Repo.Repo, gitRepoPaths, referencedSource.Repo.Project)
|
||||
resolvedPath, err = getResolvedRefValueFile(rawValueFile, env, allowedValueFilesSchemas, referencedSource.Repo.Repo, gitRepoPaths)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error resolving value file path: %w", err)
|
||||
}
|
||||
@@ -1309,15 +1309,9 @@ func getResolvedRefValueFile(
|
||||
allowedValueFilesSchemas []string,
|
||||
refSourceRepo string,
|
||||
gitRepoPaths io.TempPaths,
|
||||
project string,
|
||||
) (pathutil.ResolvedFilePath, error) {
|
||||
pathStrings := strings.Split(rawValueFile, "/")
|
||||
|
||||
keyData, err := json.Marshal(map[string]string{"url": git.NormalizeGitURL(refSourceRepo), "project": project})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
repoPath := gitRepoPaths.GetPathIfExists(string(keyData))
|
||||
repoPath := gitRepoPaths.GetPathIfExists(git.NormalizeGitURL(refSourceRepo))
|
||||
if repoPath == "" {
|
||||
return "", fmt.Errorf("failed to find repo %q", refSourceRepo)
|
||||
}
|
||||
@@ -2353,7 +2347,7 @@ func (s *Service) GetRevisionChartDetails(_ context.Context, q *apiclient.RepoSe
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("helm client error: %w", err)
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, q.Repo.Project, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting chart: %w", err)
|
||||
}
|
||||
@@ -2383,11 +2377,7 @@ func fileParameters(q *apiclient.RepoServerAppDetailsQuery) []v1alpha1.HelmFileP
|
||||
}
|
||||
|
||||
func (s *Service) newClient(repo *v1alpha1.Repository, opts ...git.ClientOpts) (git.Client, error) {
|
||||
keyData, err := json.Marshal(map[string]string{"url": git.NormalizeGitURL(repo.Repo), "project": repo.Project})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repoPath, err := s.gitRepoPaths.GetPath(string(keyData))
|
||||
repoPath, err := s.gitRepoPaths.GetPath(git.NormalizeGitURL(repo.Repo))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2413,40 +2403,37 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s
|
||||
func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string, noRevisionCache bool) (helm.Client, string, error) {
|
||||
enableOCI := repo.EnableOCI || helm.IsHelmOciRepo(repo.Repo)
|
||||
helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, repo.NoProxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths))
|
||||
if helm.IsVersion(revision) {
|
||||
|
||||
// Note: This check runs the risk of returning a version which is not found in the helm registry.
|
||||
if versions.IsVersion(revision) {
|
||||
return helmClient, revision, nil
|
||||
}
|
||||
constraints, err := semver.NewConstraint(revision)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("invalid revision '%s': %w", revision, err)
|
||||
}
|
||||
|
||||
var tags []string
|
||||
if enableOCI {
|
||||
tags, err := helmClient.GetTags(chart, noRevisionCache)
|
||||
var err error
|
||||
tags, err = helmClient.GetTags(chart, noRevisionCache)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unable to get tags: %w", err)
|
||||
}
|
||||
|
||||
version, err := tags.MaxVersion(constraints)
|
||||
} else {
|
||||
index, err := helmClient.GetIndex(noRevisionCache, s.initConstants.HelmRegistryMaxIndexSize)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("no version for constraints: %w", err)
|
||||
return nil, "", err
|
||||
}
|
||||
return helmClient, version.String(), nil
|
||||
entries, err := index.GetEntries(chart)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
tags = entries.Tags()
|
||||
}
|
||||
|
||||
index, err := helmClient.GetIndex(noRevisionCache, s.initConstants.HelmRegistryMaxIndexSize)
|
||||
maxV, err := versions.MaxVersion(revision, tags)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return nil, "", fmt.Errorf("invalid revision: %w", err)
|
||||
}
|
||||
entries, err := index.GetEntries(chart)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
version, err := entries.MaxVersion(constraints)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return helmClient, version.String(), nil
|
||||
|
||||
return helmClient, maxV, nil
|
||||
}
|
||||
|
||||
// directoryPermissionInitializer ensures the directory has read/write/execute permissions and returns
|
||||
@@ -2574,13 +2561,10 @@ func (s *Service) GetHelmCharts(_ context.Context, q *apiclient.HelmChartsReques
|
||||
}
|
||||
res := apiclient.HelmChartsResponse{}
|
||||
for chartName, entries := range index.Entries {
|
||||
chart := apiclient.HelmChart{
|
||||
Name: chartName,
|
||||
}
|
||||
for _, entry := range entries {
|
||||
chart.Versions = append(chart.Versions, entry.Version)
|
||||
}
|
||||
res.Items = append(res.Items, &chart)
|
||||
res.Items = append(res.Items, &apiclient.HelmChart{
|
||||
Name: chartName,
|
||||
Versions: entries.Tags(),
|
||||
})
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
@@ -126,10 +126,11 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git
|
||||
chart: {{Version: "1.0.0"}, {Version: version}},
|
||||
oobChart: {{Version: "1.0.0"}, {Version: version}},
|
||||
}}, nil)
|
||||
helmClient.On("ExtractChart", chart, version, "", false, int64(0), false).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("ExtractChart", oobChart, version, "", false, int64(0), false).Return("./testdata2/out-of-bounds-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version, "").Return(nil)
|
||||
helmClient.On("CleanChartCache", oobChart, version, "").Return(nil)
|
||||
helmClient.On("GetTags", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
helmClient.On("ExtractChart", chart, version, false, int64(0), false).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("ExtractChart", oobChart, version, false, int64(0), false).Return("./testdata2/out-of-bounds-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version).Return(nil)
|
||||
helmClient.On("CleanChartCache", oobChart, version).Return(nil)
|
||||
helmClient.On("DependencyBuild").Return(nil)
|
||||
|
||||
paths.On("Add", mock.Anything, mock.Anything).Return(root, nil)
|
||||
@@ -1595,7 +1596,7 @@ func TestGetAppDetailsHelm(t *testing.T) {
|
||||
assert.NotNil(t, res.Helm)
|
||||
|
||||
assert.Equal(t, "Helm", res.Type)
|
||||
assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles)
|
||||
assert.Equal(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles)
|
||||
}
|
||||
|
||||
func TestGetAppDetailsHelmUsesCache(t *testing.T) {
|
||||
@@ -1612,7 +1613,7 @@ func TestGetAppDetailsHelmUsesCache(t *testing.T) {
|
||||
assert.NotNil(t, res.Helm)
|
||||
|
||||
assert.Equal(t, "Helm", res.Type)
|
||||
assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles)
|
||||
assert.Equal(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles)
|
||||
}
|
||||
|
||||
func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) {
|
||||
@@ -1630,7 +1631,7 @@ func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "Helm", res.Type)
|
||||
assert.Empty(t, res.Helm.ValueFiles)
|
||||
assert.Equal(t, "", res.Helm.Values)
|
||||
assert.Empty(t, res.Helm.Values)
|
||||
}
|
||||
|
||||
func TestGetAppDetailsKustomize(t *testing.T) {
|
||||
@@ -1647,7 +1648,7 @@ func TestGetAppDetailsKustomize(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "Kustomize", res.Type)
|
||||
assert.NotNil(t, res.Kustomize)
|
||||
assert.EqualValues(t, []string{"nginx:1.15.4", "registry.k8s.io/nginx-slim:0.8"}, res.Kustomize.Images)
|
||||
assert.Equal(t, []string{"nginx:1.15.4", "registry.k8s.io/nginx-slim:0.8"}, res.Kustomize.Images)
|
||||
}
|
||||
|
||||
func TestGetHelmCharts(t *testing.T) {
|
||||
@@ -1664,11 +1665,11 @@ func TestGetHelmCharts(t *testing.T) {
|
||||
|
||||
item := res.Items[0]
|
||||
assert.Equal(t, "my-chart", item.Name)
|
||||
assert.EqualValues(t, []string{"1.0.0", "1.1.0"}, item.Versions)
|
||||
assert.Equal(t, []string{"1.0.0", "1.1.0"}, item.Versions)
|
||||
|
||||
item2 := res.Items[1]
|
||||
assert.Equal(t, "out-of-bounds-chart", item2.Name)
|
||||
assert.EqualValues(t, []string{"1.0.0", "1.1.0"}, item2.Versions)
|
||||
assert.Equal(t, []string{"1.0.0", "1.1.0"}, item2.Versions)
|
||||
}
|
||||
|
||||
func TestGetRevisionMetadata(t *testing.T) {
|
||||
@@ -1692,7 +1693,7 @@ func TestGetRevisionMetadata(t *testing.T) {
|
||||
assert.Equal(t, "test", res.Message)
|
||||
assert.Equal(t, now, res.Date.Time)
|
||||
assert.Equal(t, "author", res.Author)
|
||||
assert.EqualValues(t, []string{"tag1", "tag2"}, res.Tags)
|
||||
assert.Equal(t, []string{"tag1", "tag2"}, res.Tags)
|
||||
assert.NotEmpty(t, res.SignatureInfo)
|
||||
|
||||
// Check for truncated revision value
|
||||
@@ -1706,7 +1707,7 @@ func TestGetRevisionMetadata(t *testing.T) {
|
||||
assert.Equal(t, "test", res.Message)
|
||||
assert.Equal(t, now, res.Date.Time)
|
||||
assert.Equal(t, "author", res.Author)
|
||||
assert.EqualValues(t, []string{"tag1", "tag2"}, res.Tags)
|
||||
assert.Equal(t, []string{"tag1", "tag2"}, res.Tags)
|
||||
assert.NotEmpty(t, res.SignatureInfo)
|
||||
|
||||
// Cache hit - signature info should not be in result
|
||||
@@ -1826,12 +1827,12 @@ func TestService_newHelmClientResolveRevision(t *testing.T) {
|
||||
service := newService(t, ".")
|
||||
|
||||
t.Run("EmptyRevision", func(t *testing.T) {
|
||||
_, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "", "", true)
|
||||
assert.EqualError(t, err, "invalid revision '': improper constraint: ")
|
||||
_, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "", "my-chart", true)
|
||||
assert.EqualError(t, err, "invalid revision: failed to determine semver constraint: improper constraint: ")
|
||||
})
|
||||
t.Run("InvalidRevision", func(t *testing.T) {
|
||||
_, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "???", "", true)
|
||||
assert.EqualError(t, err, "invalid revision '???': improper constraint: ???", true)
|
||||
_, _, err := service.newHelmClientResolveRevision(&v1alpha1.Repository{}, "???", "my-chart", true)
|
||||
assert.EqualError(t, err, "invalid revision: failed to determine semver constraint: improper constraint: ???")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1847,7 +1848,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) {
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.2"}, details.Kustomize.Images)
|
||||
assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.2"}, details.Kustomize.Images)
|
||||
})
|
||||
})
|
||||
t.Run("No app specific override", func(t *testing.T) {
|
||||
@@ -1862,7 +1863,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) {
|
||||
AppName: "testapp",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.2"}, details.Kustomize.Images)
|
||||
assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.2"}, details.Kustomize.Images)
|
||||
})
|
||||
})
|
||||
t.Run("Only app specific override", func(t *testing.T) {
|
||||
@@ -1877,7 +1878,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) {
|
||||
AppName: "testapp",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images)
|
||||
assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images)
|
||||
})
|
||||
})
|
||||
t.Run("App specific override", func(t *testing.T) {
|
||||
@@ -1892,7 +1893,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) {
|
||||
AppName: "testapp",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images)
|
||||
assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images)
|
||||
})
|
||||
})
|
||||
t.Run("App specific overrides containing non-mergeable field", func(t *testing.T) {
|
||||
@@ -1907,7 +1908,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) {
|
||||
AppName: "unmergeable",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, []string{"gcr.io/heptio-images/ks-guestbook-demo:0.3"}, details.Kustomize.Images)
|
||||
assert.Equal(t, []string{"quay.io/argoprojlabs/argocd-e2e-container:0.3"}, details.Kustomize.Images)
|
||||
})
|
||||
})
|
||||
t.Run("Broken app-specific overrides", func(t *testing.T) {
|
||||
@@ -1979,7 +1980,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image)
|
||||
assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.2", image)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2009,7 +2010,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image)
|
||||
assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.2", image)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2040,7 +2041,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.3", image)
|
||||
assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.3", image)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2093,7 +2094,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
image, ok, _ := unstructured.NestedString(containers[0].(map[string]any), "image")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.1", image)
|
||||
assert.Equal(t, "quay.io/argoprojlabs/argocd-e2e-container:0.1", image)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3270,8 +3271,7 @@ func Test_getResolvedValueFiles(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
paths := io.NewRandomizedTempPaths(tempDir)
|
||||
|
||||
key, _ := json.Marshal(map[string]string{"url": git.NormalizeGitURL("https://github.com/org/repo1"), "project": ""})
|
||||
paths.Add(string(key), path.Join(tempDir, "repo1"))
|
||||
paths.Add(git.NormalizeGitURL("https://github.com/org/repo1"), path.Join(tempDir, "repo1"))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -4102,7 +4102,7 @@ func TestGetRefs_CacheLockTryLockGitRefCacheError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetRevisionChartDetails(t *testing.T) {
|
||||
t.Run("Test revision semvar", func(t *testing.T) {
|
||||
t.Run("Test revision semver", func(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
service := newService(t, root)
|
||||
_, err := service.GetRevisionChartDetails(t.Context(), &apiclient.RepoServerRevisionChartDetailsRequest{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
aloi
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.3
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
repo: https://somewhere
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.3
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.3
|
||||
invalid:
|
||||
- I don't know
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
@@ -12,7 +12,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -4,5 +4,5 @@ kind: Kustomization
|
||||
resources:
|
||||
- guestbook.yaml
|
||||
images:
|
||||
- name: gcr.io/heptio-images/ks-guestbook-demo
|
||||
- name: quay.io/argoprojlabs/argocd-e2e-container
|
||||
newTag: "0.1"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.3
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.3
|
||||
|
||||
@@ -12,7 +12,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -4,5 +4,5 @@ kind: Kustomization
|
||||
resources:
|
||||
- guestbook.yaml
|
||||
images:
|
||||
- name: gcr.io/heptio-images/ks-guestbook-demo
|
||||
- name: quay.io/argoprojlabs/argocd-e2e-container
|
||||
newTag: "0.1"
|
||||
|
||||
@@ -12,7 +12,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:{{.Values.image.tag}}
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:{{.Values.image.tag}}
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kustomize:
|
||||
images:
|
||||
- gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
@@ -12,7 +12,7 @@ spec:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -4,5 +4,5 @@ kind: Kustomization
|
||||
resources:
|
||||
- guestbook.yaml
|
||||
images:
|
||||
- name: gcr.io/heptio-images/ks-guestbook-demo
|
||||
- name: quay.io/argoprojlabs/argocd-e2e-container
|
||||
newTag: "0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
containerPort: 80,
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
|
||||
image: "quay.io/argoprojlabs/argocd-e2e-container:0.2",
|
||||
name: "guestbook-ui",
|
||||
replicas: 1,
|
||||
servicePort: 80,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
containerPort: 80,
|
||||
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
|
||||
image: "quay.io/argoprojlabs/argocd-e2e-container:0.2",
|
||||
name: "guestbook-ui",
|
||||
replicas: 1,
|
||||
servicePort: 80,
|
||||
|
||||
@@ -28,7 +28,7 @@ spec:
|
||||
app: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-bluegreen
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -28,7 +28,7 @@ spec:
|
||||
app: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-bluegreen
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -28,7 +28,7 @@ spec:
|
||||
app: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-bluegreen
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
app: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-bluegreen
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -28,7 +28,7 @@ spec:
|
||||
app: guestbook-bluegreen
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: guestbook-bluegreen
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -32,7 +32,7 @@ spec:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.2
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -31,7 +31,7 @@ spec:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 83
|
||||
|
||||
@@ -32,7 +32,7 @@ spec:
|
||||
app: ks-guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
|
||||
- image: quay.io/argoprojlabs/argocd-e2e-container:0.1
|
||||
name: ks-guestbook-ui
|
||||
ports:
|
||||
- containerPort: 83
|
||||
|
||||
@@ -32,7 +32,7 @@ spec:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2'
|
||||
- image: 'quay.io/argoprojlabs/argocd-e2e-container:0.2'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -3,7 +3,7 @@ kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '1'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
@@ -39,7 +39,7 @@ spec:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
- image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -3,7 +3,7 @@ kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '1'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
@@ -39,7 +39,7 @@ spec:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.1'
|
||||
- image: 'quay.io/argoprojlabs/argocd-e2e-container:0.1'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -3,7 +3,7 @@ kind: Rollout
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: >
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
{"apiVersion":"argoproj.io/v1alpha1","kind":"Rollout","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-canary","ksonnet.io/component":"guestbook-ui"},"name":"guestbook-canary","namespace":"default"},"spec":{"minReadySeconds":10,"replicas":5,"selector":{"matchLabels":{"app":"guestbook-canary"}},"strategy":{"canary":{"maxSurge":1,"maxUnavailable":0,"steps":[{"setWeight":20},{"pause":{"duration":30}},{"setWeight":40},{"pause":{}}]}},"template":{"metadata":{"labels":{"app":"guestbook-canary"}},"spec":{"containers":[{"image":"quay.io/argoprojlabs/argocd-e2e-container:0.1","name":"guestbook-canary","ports":[{"containerPort":80}]}]}}}}
|
||||
rollout.argoproj.io/revision: '2'
|
||||
clusterName: ''
|
||||
creationTimestamp: '2019-05-01T21:55:30Z'
|
||||
@@ -33,7 +33,7 @@ spec:
|
||||
app: guestbook-canary
|
||||
spec:
|
||||
containers:
|
||||
- image: 'gcr.io/heptio-images/ks-guestbook-demo:0.2'
|
||||
- image: 'quay.io/argoprojlabs/argocd-e2e-container:0.2'
|
||||
name: guestbook-canary
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user