Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
62995f0
feat(appset): add Support for AzureDevops Webhooks (#15047)
robinlieb Sep 22, 2023
1d27458
fix(cli): get latest app state before printing tree (#15639)
crenshaw-dev Sep 22, 2023
08e53e7
chore(deps): bump actions/setup-node from 3.8.0 to 3.8.1 (#15108)
dependabot[bot] Sep 22, 2023
03c6e1a
feat(kustomize): add patches field (#5114) (#14648)
crenshaw-dev Sep 23, 2023
30767ae
feat(health): Implement AnsibleJob CRD health checks (#14483)
mikeshng Sep 25, 2023
129cf53
feat(health): add PushSecret health status and force-sync action (#14…
agaudreault Sep 25, 2023
cbd8806
fix(kustomize): no concurrent processing if Kustomize patches are use…
crenshaw-dev Sep 25, 2023
61dc8b5
feat(appset): ignoreApplicationDifferences (#9101) (#14743)
crenshaw-dev Sep 25, 2023
8a2e0ba
fix(applicationset): cannot validate inherited project permissions (#…
agaudreault Sep 25, 2023
adcf784
chore(deps): bump semver from 5.7.1 to 5.7.2 in /ui-test (#14457)
dependabot[bot] Sep 26, 2023
bb8800d
chore(ci): free up disk space (#15674)
crenshaw-dev Sep 26, 2023
1a9cda0
fix: add a not found check for application controller deployment (#15…
ishitasequeira Sep 26, 2023
5f63246
[fix] sidebar style (#15652)
ymktmk Sep 26, 2023
a934772
fix(ci): free up disk space (#15683)
crenshaw-dev Sep 26, 2023
3557ec5
fix(ci): do not fail fast on e2e test failures (#15694)
crenshaw-dev Sep 27, 2023
b40d8cb
fix(ci): misplaced config option (#15698)
crenshaw-dev Sep 27, 2023
a1c9d6b
fix(applicationset): git generator ignores empty files (#15661)
agaudreault Sep 27, 2023
28ef096
fix(appset): don't emit k8s events for unchanged apps, log at debug (…
ericblackburn Sep 27, 2023
cc97a59
feat(ci): retry individual e2e tests (#15696)
crenshaw-dev Sep 28, 2023
80d1bb8
docs: Maintaining Uniformity In Documentation Writing Style (#15713)
PranitRout07 Sep 28, 2023
c975b0a
docs: add dynamic cluster distribution doc in the menu (#15716)
leoluz Sep 28, 2023
fd655e9
Converted italic text to normal text (#15692)
PranitRout07 Sep 29, 2023
b44400f
fix(action): populate all fields of Job from CronJob (#15259) (#15727)
SergeyLadutko Sep 29, 2023
0386027
fix(application-controller): Fix panic error when trying to scale app…
anandf Sep 29, 2023
672c127
docs: move self-signed certs gitlab scm docs (#15720)
leoluz Sep 29, 2023
9f25800
fix: only enable dynamic cluster sharding feature explicitly (#15734)
rbreeze Sep 30, 2023
48a4a77
Fixed Custom Link Text not Hyperlinked (#15747)
PranitRout07 Sep 30, 2023
2730170
docs: Add documentation for Zitadel SSO integration (#15029)
stephanrenggli Oct 1, 2023
599dfcd
chore: set proper struct tag for ApplicationSetTerminalGenerator.Plug…
chavacava Oct 2, 2023
792a785
chore: merge master
blakepettersson Oct 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
- name: Setup NodeJS
uses: actions/setup-node@bea5baf987ba7aa777a8a0b4ace377a21c45c381 # v3.8.0
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: '20.7.0'
- name: Restore node dependency cache
Expand Down Expand Up @@ -360,6 +360,7 @@ jobs:
name: Run end-to-end tests
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
k3s-version: [v1.27.2, v1.26.0, v1.25.4, v1.24.3]
needs:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/image-reuse.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ jobs:
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "GIT_TREE_STATE=$(if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi)" >> $GITHUB_ENV

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@4d9e71b726748f254fe64fa44d273194bd18ec91
with:
large-packages: false
docker-images: false
swap-storage: false
tool-cache: false

- name: Build and push container image
id: image
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 #v4.1.1
Expand Down
13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ARGOCD_E2E_DEX_PORT?=5556
ARGOCD_E2E_YARN_HOST?=localhost
ARGOCD_E2E_DISABLE_AUTH?=

ARGOCD_E2E_TEST_TIMEOUT?=45m
ARGOCD_E2E_TEST_TIMEOUT?=60m

ARGOCD_IN_CI?=false
ARGOCD_TEST_E2E?=true
Expand Down Expand Up @@ -386,9 +386,9 @@ test: test-tools-image
.PHONY: test-local
test-local:
if test "$(TEST_MODULE)" = ""; then \
./hack/test.sh -coverprofile=coverage.out `go list ./... | grep -v 'test/e2e'`; \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES=`go list ./... | grep -v 'test/e2e'` ./hack/test.sh -coverprofile=coverage.out; \
else \
./hack/test.sh -coverprofile=coverage.out "$(TEST_MODULE)"; \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES="$(TEST_MODULE)" ./hack/test.sh -coverprofile=coverage.out "$(TEST_MODULE)"; \
fi

.PHONY: test-race
Expand All @@ -400,9 +400,9 @@ test-race: test-tools-image
.PHONY: test-race-local
test-race-local:
if test "$(TEST_MODULE)" = ""; then \
./hack/test.sh -race -coverprofile=coverage.out `go list ./... | grep -v 'test/e2e'`; \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES=`go list ./... | grep -v 'test/e2e'` ./hack/test.sh -race -coverprofile=coverage.out; \
else \
./hack/test.sh -race -coverprofile=coverage.out "$(TEST_MODULE)"; \
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES="$(TEST_MODULE)" ./hack/test.sh -race -coverprofile=coverage.out; \
fi

# Run the E2E test suite. E2E test servers (see start-e2e target) must be
Expand All @@ -416,7 +416,7 @@ test-e2e:
test-e2e-local: cli-local
# NO_PROXY ensures all tests don't go out through a proxy if one is configured on the test system
export GO111MODULE=off
ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v ./test/e2e
DIST_DIR=${DIST_DIR} RERUN_FAILS=5 PACKAGES="./test/e2e" ARGOCD_E2E_RECORD=${ARGOCD_E2E_RECORD} ARGOCD_GPG_ENABLED=true NO_PROXY=* ./hack/test.sh -timeout $(ARGOCD_E2E_TEST_TIMEOUT) -v

# Spawns a shell in the test server container for debugging purposes
debug-test-server: test-tools-image
Expand Down Expand Up @@ -557,6 +557,7 @@ install-tools-local: install-test-tools-local install-codegen-tools-local instal
install-test-tools-local:
./hack/install.sh kustomize
./hack/install.sh helm-linux
./hack/install.sh gotestsum

# Installs all tools required for running codegen (Linux packages)
.PHONY: install-codegen-tools-local
Expand Down
83 changes: 70 additions & 13 deletions applicationset/controllers/applicationset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package controllers

import (
"context"
"encoding/json"
"fmt"
"reflect"
"time"
Expand All @@ -24,6 +25,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
Expand All @@ -44,6 +46,7 @@ import (
"github.com/argoproj/argo-cd/v2/applicationset/generators"
"github.com/argoproj/argo-cd/v2/applicationset/utils"
"github.com/argoproj/argo-cd/v2/common"
argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/glob"

Expand Down Expand Up @@ -436,8 +439,7 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con
errorsByIndex[i] = fmt.Errorf("ApplicationSet %s contains applications with duplicate name: %s", applicationSetInfo.Name, app.Name)
continue
}

proj, err := r.ArgoAppClientset.ArgoprojV1alpha1().AppProjects(r.ArgoCDNamespace).Get(ctx, app.Spec.GetProject(), metav1.GetOptions{})
_, err := r.ArgoAppClientset.ArgoprojV1alpha1().AppProjects(r.ArgoCDNamespace).Get(ctx, app.Spec.GetProject(), metav1.GetOptions{})
if err != nil {
if apierr.IsNotFound(err) {
errorsByIndex[i] = fmt.Errorf("application references project %s which does not exist", app.Spec.Project)
Expand All @@ -451,15 +453,6 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con
continue
}

conditions, err := argoutil.ValidatePermissions(ctx, &app.Spec, proj, r.ArgoDB)
if err != nil {
return nil, fmt.Errorf("error validating permissions: %s", err)
}
if len(conditions) > 0 {
errorsByIndex[i] = fmt.Errorf("application spec is invalid: %s", argoutil.FormatAppConditions(conditions))
continue
}

}

return errorsByIndex, nil
Expand Down Expand Up @@ -685,6 +678,14 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,

found.ObjectMeta.Finalizers = generatedApp.Finalizers
found.ObjectMeta.Labels = generatedApp.Labels

if found != nil && len(found.Spec.IgnoreDifferences) > 0 {
err := applyIgnoreDifferences(applicationSet.Spec.IgnoreApplicationDifferences, found, generatedApp)
if err != nil {
return fmt.Errorf("failed to apply ignore differences: %w", err)
}
}

return controllerutil.SetControllerReference(&applicationSet, found, r.Scheme)
})

Expand All @@ -696,12 +697,68 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
continue
}
r.updateCache(ctx, found, appLog)
r.Recorder.Eventf(&applicationSet, corev1.EventTypeNormal, fmt.Sprint(action), "%s Application %q", action, generatedApp.Name)
appLog.Logf(log.InfoLevel, "%s Application", action)

if action != controllerutil.OperationResultNone {
// Don't pollute etcd with "unchanged Application" events
r.Recorder.Eventf(&applicationSet, corev1.EventTypeNormal, fmt.Sprint(action), "%s Application %q", action, generatedApp.Name)
appLog.Logf(log.InfoLevel, "%s Application", action)
} else {
// "unchanged Application" can be inferred by Reconcile Complete with no action being listed
// Or enable debug logging
appLog.Logf(log.DebugLevel, "%s Application", action)
}
}
return firstError
}

// applyIgnoreDifferences applies the ignore differences rules to the found application. It modifies the found application in place.
func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.ApplicationSetIgnoreDifferences, found *argov1alpha1.Application, generatedApp argov1alpha1.Application) error {
diffConfig, err := argodiff.NewDiffConfigBuilder().
WithDiffSettings(applicationSetIgnoreDifferences.ToApplicationIgnoreDifferences(), nil, false).
WithNoCache().
Build()
if err != nil {
return fmt.Errorf("failed to build diff config: %w", err)
}
unstructuredFound, err := appToUnstructured(found)
if err != nil {
return fmt.Errorf("failed to convert found application to unstructured: %w", err)
}
unstructuredGenerated, err := appToUnstructured(&generatedApp)
if err != nil {
return fmt.Errorf("failed to convert found application to unstructured: %w", err)
}
result, err := argodiff.Normalize([]*unstructured.Unstructured{unstructuredFound}, []*unstructured.Unstructured{unstructuredGenerated}, diffConfig)
if err != nil {
return fmt.Errorf("failed to normalize application spec: %w", err)
}
if len(result.Targets) != 1 {
return fmt.Errorf("expected 1 normalized application, got %d", len(result.Targets))
}
jsonNormalized, err := json.Marshal(result.Targets[0].Object)
if err != nil {
return fmt.Errorf("failed to marshal normalized app to json: %w", err)
}
err = json.Unmarshal(jsonNormalized, &found)
if err != nil {
return fmt.Errorf("failed to unmarshal normalized app json to structured app: %w", err)
}
// Prohibit jq queries from mutating silly things.
found.TypeMeta = generatedApp.TypeMeta
found.Name = generatedApp.Name
found.Namespace = generatedApp.Namespace
found.Operation = generatedApp.Operation
return nil
}

func appToUnstructured(app *argov1alpha1.Application) (*unstructured.Unstructured, error) {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(app)
if err != nil {
return nil, fmt.Errorf("failed to convert app object to unstructured: %w", err)
}
return &unstructured.Unstructured{Object: u}, nil
}

// createInCluster will filter from the desiredApplications only the application that needs to be created
// Then it will call createOrUpdateInCluster to do the actual create
func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error {
Expand Down
Loading