diff --git a/pkg/sync/sync_context.go b/pkg/sync/sync_context.go index 8ff2b339d..abd4379f7 100644 --- a/pkg/sync/sync_context.go +++ b/pkg/sync/sync_context.go @@ -154,11 +154,10 @@ func WithResourceModificationChecker(enabled bool, diffResults *diff.DiffResultL } // WithNamespaceCreation will create non-exist namespace -func WithNamespaceCreation(createNamespace bool, namespaceModifier func(*unstructured.Unstructured) bool, namespaceCreator func(*unstructured.Unstructured) bool) SyncOpt { +func WithNamespaceCreation(createNamespace bool, namespaceModifier func(*unstructured.Unstructured) bool) SyncOpt { return func(ctx *syncContext) { ctx.createNamespace = createNamespace ctx.namespaceModifier = namespaceModifier - ctx.namespaceCreator = namespaceCreator } } @@ -352,7 +351,6 @@ type syncContext struct { createNamespace bool namespaceModifier func(*unstructured.Unstructured) bool - namespaceCreator func(*unstructured.Unstructured) bool syncWaveHook common.SyncWaveHook @@ -818,9 +816,7 @@ func (sc *syncContext) autoCreateNamespace(tasks syncTasks) syncTasks { } } } else if apierr.IsNotFound(err) { - if sc.namespaceCreator(unstructuredObj) { - tasks = append(tasks, &syncTask{phase: common.SyncPhasePreSync, targetObj: unstructuredObj, liveObj: nil}) - } + tasks = append(tasks, &syncTask{phase: common.SyncPhasePreSync, targetObj: unstructuredObj, liveObj: nil}) } else { task := &syncTask{phase: common.SyncPhasePreSync, targetObj: unstructuredObj} sc.setResourceResult(task, common.ResultCodeSyncFailed, common.OperationError, fmt.Sprintf("Namespace auto creation failed: %s", err)) diff --git a/pkg/sync/sync_context_test.go b/pkg/sync/sync_context_test.go index d43bdce9d..6d3832279 100644 --- a/pkg/sync/sync_context_test.go +++ b/pkg/sync/sync_context_test.go @@ -1,12 +1,9 @@ package sync import ( - "context" "encoding/json" "errors" "fmt" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime/schema" "net/http" "net/http/httptest" "reflect" @@ -38,7 +35,7 @@ import ( var standardVerbs = v1.Verbs{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"} -func newTestSyncCtx(getResourceFunc *func(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error), opts ...SyncOpt) *syncContext { +func newTestSyncCtx(opts ...SyncOpt) *syncContext { fakeDisco := &fakedisco.FakeDiscovery{Fake: &testcore.Fake{}} fakeDisco.Resources = append(make([]*v1.APIResourceList, 0), &v1.APIResourceList{ @@ -70,9 +67,6 @@ func newTestSyncCtx(getResourceFunc *func(ctx context.Context, config *rest.Conf return nil } mockKubectl := kubetest.MockKubectlCmd{} - if getResourceFunc != nil { - mockKubectl.WithGetResourceFunc(*getResourceFunc) - } sc.kubectl = &mockKubectl sc.resourceOps = &mockKubectl for _, opt := range opts { @@ -83,7 +77,7 @@ func newTestSyncCtx(getResourceFunc *func(ctx context.Context, config *rest.Conf // make sure Validate means we don't validate func TestSyncValidate(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() pod.SetNamespace("fake-argocd-ns") syncCtx.resources = groupResources(ReconciliationResult{ @@ -99,7 +93,7 @@ func TestSyncValidate(t *testing.T) { } func TestSyncNotPermittedNamespace(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error { + syncCtx := newTestSyncCtx(WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error { return fmt.Errorf("not permitted in project") })) targetPod := NewPod() @@ -115,7 +109,7 @@ func TestSyncNotPermittedNamespace(t *testing.T) { } func TestSyncCreateInSortedOrder(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.resources = groupResources(ReconciliationResult{ Live: []*unstructured.Unstructured{nil, nil}, Target: []*unstructured.Unstructured{NewPod(), NewService()}, @@ -177,7 +171,7 @@ func TestSyncCustomResources(t *testing.T) { knownCustomResourceTypes = append(knownCustomResourceTypes, v1.APIResource{Kind: "TestCrd", Group: "argoproj.io", Version: "v1", Namespaced: true, Verbs: standardVerbs}) } - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() fakeDisco := syncCtx.disco.(*fakedisco.FakeDiscovery) fakeDisco.Resources = []*v1.APIResourceList{{ GroupVersion: "argoproj.io/v1", @@ -239,7 +233,7 @@ func TestSyncCustomResources(t *testing.T) { } func TestSyncSuccessfully(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, true, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) pod := NewPod() pod.SetNamespace(FakeArgoCDNamespace) syncCtx.resources = groupResources(ReconciliationResult{ @@ -267,7 +261,7 @@ func TestSyncSuccessfully(t *testing.T) { } func TestSyncDeleteSuccessfully(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, true, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) svc := NewService() svc.SetNamespace(FakeArgoCDNamespace) pod := NewPod() @@ -296,7 +290,7 @@ func TestSyncDeleteSuccessfully(t *testing.T) { } func TestSyncCreateFailure(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() testSvc := NewService() mockKubectl := &kubetest.MockKubectlCmd{ Commands: map[string]kubetest.KubectlOutput{ @@ -330,7 +324,7 @@ func TestSync_ApplyOutOfSyncOnly(t *testing.T) { pod3 := NewPod() pod3.SetName("pod-3") - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.applyOutOfSyncOnly = true t.Run("modificationResult=nil", func(t *testing.T) { syncCtx.modificationResult = nil @@ -345,7 +339,7 @@ func TestSync_ApplyOutOfSyncOnly(t *testing.T) { assert.Len(t, resources, 3) }) - syncCtx = newTestSyncCtx(nil, WithResourceModificationChecker(true, diffResultList())) + syncCtx = newTestSyncCtx(WithResourceModificationChecker(true, diffResultList())) t.Run("applyOutOfSyncOnly=true", func(t *testing.T) { syncCtx.resources = groupResources(ReconciliationResult{ Live: []*unstructured.Unstructured{nil, pod2, pod3}, @@ -383,7 +377,7 @@ func TestSync_ApplyOutOfSyncOnly(t *testing.T) { }) t.Run("applyOutOfSyncOnly=true and prune=true", func(t *testing.T) { - syncCtx = newTestSyncCtx(nil, WithResourceModificationChecker(true, diffResultList())) + syncCtx = newTestSyncCtx(WithResourceModificationChecker(true, diffResultList())) syncCtx.applyOutOfSyncOnly = true syncCtx.prune = true syncCtx.resources = groupResources(ReconciliationResult{ @@ -408,7 +402,7 @@ func TestSync_ApplyOutOfSyncOnly(t *testing.T) { }) t.Run("applyOutOfSyncOnly=true and syncwaves", func(t *testing.T) { - syncCtx = newTestSyncCtx(nil, WithResourceModificationChecker(true, diffResultList())) + syncCtx = newTestSyncCtx(WithResourceModificationChecker(true, diffResultList())) syncCtx.applyOutOfSyncOnly = true syncCtx.prune = true pod1.SetAnnotations(map[string]string{synccommon.AnnotationSyncWave: "2"}) @@ -439,7 +433,7 @@ func TestSync_ApplyOutOfSyncOnly(t *testing.T) { } func TestSyncPruneFailure(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, true, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) mockKubectl := &kubetest.MockKubectlCmd{ Commands: map[string]kubetest.KubectlOutput{ "test-service": { @@ -525,7 +519,7 @@ func TestServerResourcesRetry(t *testing.T) { } setup := func(t *testing.T, apiFailuresCount int) *fixture { t.Helper() - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, false, false, true)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, false, false, true)) unauthorizedStatus := &metav1.Status{ Status: metav1.StatusFailure, @@ -653,7 +647,7 @@ func TestServerResourcesRetry(t *testing.T) { } func TestDoNotSyncOrPruneHooks(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, false, false, true)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, false, false, true)) targetPod := NewPod() targetPod.SetName("do-not-create-me") targetPod.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "PreSync"}) @@ -671,7 +665,7 @@ func TestDoNotSyncOrPruneHooks(t *testing.T) { // make sure that we do not prune resources with Prune=false func TestDoNotPrunePruneFalse(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, true, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) pod := NewPod() pod.SetAnnotations(map[string]string{synccommon.AnnotationSyncOptions: "Prune=false"}) pod.SetNamespace(FakeArgoCDNamespace) @@ -707,7 +701,7 @@ func TestSyncOptionValidate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() pod.SetAnnotations(map[string]string{synccommon.AnnotationSyncOptions: tt.annotationVal}) pod.SetNamespace(FakeArgoCDNamespace) @@ -743,7 +737,7 @@ func TestSync_Replace(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() tc.target.SetNamespace(FakeArgoCDNamespace) if tc.live != nil { @@ -791,7 +785,7 @@ func TestSync_ServerSideApply(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.serverSideApplyManager = tc.manager tc.target.SetNamespace(FakeArgoCDNamespace) @@ -818,7 +812,7 @@ func TestSelectiveSyncOnly(t *testing.T) { pod1.SetName("pod-1") pod2 := NewPod() pod2.SetName("pod-2") - syncCtx := newTestSyncCtx(nil, WithResourcesFilter(func(key kube.ResourceKey, _ *unstructured.Unstructured, _ *unstructured.Unstructured) bool { + syncCtx := newTestSyncCtx(WithResourcesFilter(func(key kube.ResourceKey, _ *unstructured.Unstructured, _ *unstructured.Unstructured) bool { return key.Kind == pod1.GetKind() && key.Name == pod1.GetName() })) syncCtx.resources = groupResources(ReconciliationResult{ @@ -834,7 +828,7 @@ func TestSelectiveSyncOnly(t *testing.T) { func TestUnnamedHooksGetUniqueNames(t *testing.T) { t.Run("Truncated revision", func(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() pod.SetName("") @@ -851,7 +845,7 @@ func TestUnnamedHooksGetUniqueNames(t *testing.T) { }) t.Run("Short revision", func(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() pod.SetName("") pod.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "PreSync,PostSync"}) @@ -868,7 +862,7 @@ func TestUnnamedHooksGetUniqueNames(t *testing.T) { } func TestManagedResourceAreNotNamed(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() pod.SetName("") @@ -886,7 +880,7 @@ func TestManagedResourceAreNotNamed(t *testing.T) { } func TestDeDupingTasks(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, true, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, true, false, false)) pod := NewPod() pod.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "Sync"}) syncCtx.resources = groupResources(ReconciliationResult{ @@ -902,7 +896,7 @@ func TestDeDupingTasks(t *testing.T) { } func TestObjectsGetANamespace(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() syncCtx.resources = groupResources(ReconciliationResult{ Live: []*unstructured.Unstructured{nil}, @@ -920,7 +914,7 @@ func TestObjectsGetANamespace(t *testing.T) { func TestNamespaceAutoCreation(t *testing.T) { pod := NewPod() namespace := NewNamespace() - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.createNamespace = true syncCtx.namespace = FakeArgoCDNamespace namespace.SetName(FakeArgoCDNamespace) @@ -988,54 +982,6 @@ func TestNamespaceAutoCreation(t *testing.T) { } -func TestNamespaceAutoCreationForNotExistNs(t *testing.T) { - getResourceFunc := func(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string) (*unstructured.Unstructured, error) { - return nil, apierrors.NewNotFound(schema.GroupResource{}, FakeArgoCDNamespace) - } - - pod := NewPod() - namespace := NewNamespace() - syncCtx := newTestSyncCtx(&getResourceFunc) - syncCtx.createNamespace = true - syncCtx.namespace = FakeArgoCDNamespace - namespace.SetName(FakeArgoCDNamespace) - - t.Run("pre-sync task should exist and namespace creator should be called", func(t *testing.T) { - syncCtx.resources = groupResources(ReconciliationResult{ - Live: []*unstructured.Unstructured{nil}, - Target: []*unstructured.Unstructured{pod}, - }) - creatorCalled := false - syncCtx.namespaceCreator = func(*unstructured.Unstructured) bool { - creatorCalled = true - return true - } - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, creatorCalled) - assert.True(t, successful) - assert.Len(t, tasks, 2) - }) - - t.Run("pre-sync task should be not created and namespace creator should be called", func(t *testing.T) { - syncCtx.resources = groupResources(ReconciliationResult{ - Live: []*unstructured.Unstructured{nil}, - Target: []*unstructured.Unstructured{pod}, - }) - creatorCalled := false - syncCtx.namespaceCreator = func(*unstructured.Unstructured) bool { - creatorCalled = true - return false - } - tasks, successful := syncCtx.getSyncTasks() - - assert.True(t, creatorCalled) - assert.True(t, successful) - assert.Len(t, tasks, 1) - }) - -} - func createNamespaceTask(namespace string) (*syncTask, error) { nsSpec := &corev1.Namespace{TypeMeta: v1.TypeMeta{APIVersion: "v1", Kind: kube.NamespaceKind}, ObjectMeta: v1.ObjectMeta{Name: namespace}} unstructuredObj, err := kube.ToUnstructured(nsSpec) @@ -1045,7 +991,7 @@ func createNamespaceTask(namespace string) (*syncTask, error) { } func TestSyncFailureHookWithSuccessfulSync(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.resources = groupResources(ReconciliationResult{ Live: []*unstructured.Unstructured{nil}, Target: []*unstructured.Unstructured{NewPod()}, @@ -1060,7 +1006,7 @@ func TestSyncFailureHookWithSuccessfulSync(t *testing.T) { } func TestSyncFailureHookWithFailedSync(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() syncCtx.resources = groupResources(ReconciliationResult{ Live: []*unstructured.Unstructured{nil}, @@ -1082,7 +1028,7 @@ func TestSyncFailureHookWithFailedSync(t *testing.T) { } func TestBeforeHookCreation(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() hook := Annotate(Annotate(NewPod(), synccommon.AnnotationKeyHook, "Sync"), synccommon.AnnotationKeyHookDeletePolicy, "BeforeHookCreation") hook.SetNamespace(FakeArgoCDNamespace) syncCtx.resources = groupResources(ReconciliationResult{ @@ -1103,7 +1049,7 @@ func TestBeforeHookCreation(t *testing.T) { func TestRunSyncFailHooksFailed(t *testing.T) { // Tests that other SyncFail Hooks run even if one of them fail. - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() pod := NewPod() successfulSyncFailHook := newHook(synccommon.HookTypeSyncFail) successfulSyncFailHook.SetName("successful-sync-fail-hook") @@ -1159,7 +1105,7 @@ func TestRunSync_HooksNotDeletedIfPhaseNotCompleted(t *testing.T) { inProgressHook.SetName("in-progress-hook") _ = Annotate(inProgressHook, synccommon.AnnotationKeyHookDeletePolicy, "HookSucceeded") - syncCtx := newTestSyncCtx(nil, + syncCtx := newTestSyncCtx( WithHealthOverride(resourceNameHealthOverride(map[string]health.HealthStatusCode{ inProgressHook.GetName(): health.HealthStatusProgressing, })), @@ -1208,7 +1154,7 @@ func TestRunSync_HooksDeletedAfterPhaseCompleted(t *testing.T) { completedHook2.SetName("completed-hook2") _ = Annotate(completedHook2, synccommon.AnnotationKeyHookDeletePolicy, "HookSucceeded") - syncCtx := newTestSyncCtx(nil, + syncCtx := newTestSyncCtx( WithInitialState(synccommon.OperationRunning, "", []synccommon.ResourceSyncResult{{ ResourceKey: kube.GetResourceKey(completedHook1), HookPhase: synccommon.OperationSucceeded, @@ -1254,7 +1200,7 @@ func TestRunSync_HooksDeletedAfterPhaseCompletedFailed(t *testing.T) { completedHook2.SetName("completed-hook2") _ = Annotate(completedHook2, synccommon.AnnotationKeyHookDeletePolicy, "HookFailed") - syncCtx := newTestSyncCtx(nil, + syncCtx := newTestSyncCtx( WithInitialState(synccommon.OperationRunning, "", []synccommon.ResourceSyncResult{{ ResourceKey: kube.GetResourceKey(completedHook1), HookPhase: synccommon.OperationSucceeded, @@ -1367,7 +1313,7 @@ func Test_setRunningPhase_pendingDeletion(t *testing.T) { } func TestSyncWaveHook(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, false, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, false, false, false)) pod1 := NewPod() pod1.SetName("pod-1") pod1.SetAnnotations(map[string]string{synccommon.AnnotationSyncWave: "-1"}) @@ -1438,7 +1384,7 @@ func TestSyncWaveHook(t *testing.T) { } func TestSyncWaveHookFail(t *testing.T) { - syncCtx := newTestSyncCtx(nil, WithOperationSettings(false, false, false, false)) + syncCtx := newTestSyncCtx(WithOperationSettings(false, false, false, false)) pod1 := NewPod() pod1.SetName("pod-1") @@ -1461,7 +1407,7 @@ func TestSyncWaveHookFail(t *testing.T) { } func TestPruneLast(t *testing.T) { - syncCtx := newTestSyncCtx(nil) + syncCtx := newTestSyncCtx() syncCtx.pruneLast = true pod1 := NewPod()