Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support multiple ArgoCD instances with ApplicationTrackingAnnotations #1637

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions api/v1alpha1/argocd_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,10 @@ type ArgoCDSpec struct {
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Application Instance Label Key'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
ApplicationInstanceLabelKey string `json:"applicationInstanceLabelKey,omitempty"`

// InstallationID uniquely identifies an Argo CD instance in multi-instance clusters.
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Installation ID",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
InstallationID string `json:"installationID,omitempty"`

// ConfigManagementPlugins is used to specify additional config management plugins.
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Config Management Plugins'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
ConfigManagementPlugins string `json:"configManagementPlugins,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/argocd_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,10 @@ type ArgoCDSpec struct {
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Application Instance Label Key'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
ApplicationInstanceLabelKey string `json:"applicationInstanceLabelKey,omitempty"`

// InstallationID uniquely identifies an Argo CD instance in multi-instance clusters.
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Installation ID",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
InstallationID string `json:"installationID,omitempty"`

// ConfigManagementPlugins is used to specify additional config management plugins.
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Config Management Plugins'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
ConfigManagementPlugins string `json:"configManagementPlugins,omitempty"`
Expand Down
16 changes: 15 additions & 1 deletion bundle/manifests/argocd-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ metadata:
capabilities: Deep Insights
categories: Integration & Delivery
certified: "false"
createdAt: "2024-12-20T09:48:39Z"
createdAt: "2025-02-04T21:18:01Z"
description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
operators.operatorframework.io/builder: operator-sdk-v1.35.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
Expand Down Expand Up @@ -611,6 +611,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down Expand Up @@ -1189,6 +1196,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down
8 changes: 8 additions & 0 deletions bundle/manifests/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down Expand Up @@ -14371,6 +14375,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down
3 changes: 3 additions & 0 deletions common/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,7 @@ const (

// Label Selector is an env variable for ArgoCD instance reconcilliation.
ArgoCDLabelSelectorKey = "ARGOCD_LABEL_SELECTOR"

// ArgoCDKeyInstallationID is the configuration key for the installation ID.
ArgoCDKeyInstallationID = "installationID"
)
8 changes: 8 additions & 0 deletions config/crd/bases/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down Expand Up @@ -14360,6 +14364,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down
14 changes: 14 additions & 0 deletions config/manifests/bases/argocd-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down Expand Up @@ -1028,6 +1035,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down
6 changes: 5 additions & 1 deletion controllers/argocd/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ func (r *ReconcileArgoCD) reconcileCAConfigMap(cr *argoproj.ArgoCD) error {
// reconcileConfiguration will ensure that the main ConfigMap for ArgoCD is present.
func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoproj.ArgoCD) error {
cm := newConfigMapWithName(common.ArgoCDConfigMapName, cr)

cm.Data = make(map[string]string)
cm.Data = setRespectRBAC(cr, cm.Data)
cm.Data[common.ArgoCDKeyApplicationInstanceLabelKey] = getApplicationInstanceLabelKey(cr)
Expand All @@ -391,6 +390,11 @@ func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoproj.ArgoCD) error {
cm.Data[common.ArgoCDKeyHelpChatText] = getHelpChatText(cr)
cm.Data[common.ArgoCDKeyKustomizeBuildOptions] = getKustomizeBuildOptions(cr)

// Set installationID as a top-level key
if cr.Spec.InstallationID != "" {
cm.Data[common.ArgoCDKeyInstallationID] = cr.Spec.InstallationID
}

if len(cr.Spec.KustomizeVersions) > 0 {
for _, kv := range cr.Spec.KustomizeVersions {
cm.Data["kustomize.version."+kv.Version] = kv.Path
Expand Down
112 changes: 110 additions & 2 deletions controllers/argocd/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,6 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te
assert.NoError(t, err)

cm := &corev1.ConfigMap{}

t.Run("Check default tracking method", func(t *testing.T) {
err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Expand Down Expand Up @@ -1029,7 +1028,6 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withRespectRBAC(t *testing.T) {
assert.NoError(t, err)

cm := &corev1.ConfigMap{}

assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: common.ArgoCDConfigMapName, Namespace: testNamespace}, cm))

if c := cm.Data["resource.respectRBAC"]; c != "normal" {
Expand Down Expand Up @@ -1154,3 +1152,113 @@ func Test_validateOwnerReferences(t *testing.T) {
assert.Equal(t, cm.OwnerReferences[0].Name, "argocd")
assert.Equal(t, cm.OwnerReferences[0].UID, uid)
}

func TestReconcileArgoCD_reconcileArgoConfigMap_withInstallationID(t *testing.T) {
logf.SetLogger(ZapLogger(true))

a := makeTestArgoCD(func(a *argoproj.ArgoCD) {
a.Spec.InstallationID = "test-id"
})

resObjs := []client.Object{a}
subresObjs := []client.Object{a}
runtimeObjs := []runtime.Object{}
sch := makeTestReconcilerScheme(argoproj.AddToScheme)
cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
r := makeTestReconciler(cl, sch)

// Test initial installationID
err := r.reconcileArgoConfigMap(a)
assert.NoError(t, err)

cm := &corev1.ConfigMap{}
err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Namespace: testNamespace,
}, cm)
assert.NoError(t, err)

// Verify installationID is set as a top-level key
assert.Equal(t, "test-id", cm.Data[common.ArgoCDKeyInstallationID])

//Test updating installationID
a.Spec.InstallationID = "test-id-2"
err = r.reconcileArgoConfigMap(a)
assert.NoError(t, err)

cm = &corev1.ConfigMap{}
err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Namespace: testNamespace,
}, cm)
assert.NoError(t, err)

assert.Equal(t, "test-id-2", cm.Data[common.ArgoCDKeyInstallationID])

// Test removing installationID
a.Spec.InstallationID = ""
err = r.reconcileArgoConfigMap(a)
assert.NoError(t, err)

err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Namespace: testNamespace,
}, cm)
assert.NoError(t, err)

// Verify installationID was removed
assert.NotContains(t, cm.Data, common.ArgoCDKeyInstallationID)
}

func TestReconcileArgoCD_reconcileArgoConfigMap_withMultipleInstances(t *testing.T) {
logf.SetLogger(ZapLogger(true))

// Create first ArgoCD instance
argocd1 := makeTestArgoCD(func(a *argoproj.ArgoCD) {
a.Name = "argocd-1"
a.Namespace = testNamespace
a.Spec.InstallationID = "instance-1"
})

// Create second ArgoCD instance
argocd2 := makeTestArgoCD(func(a *argoproj.ArgoCD) {
a.Name = "argocd-2"
a.Namespace = testNamespace
a.Spec.InstallationID = "instance-2"
})

resObjs := []client.Object{argocd1, argocd2}
subresObjs := []client.Object{argocd1, argocd2}
runtimeObjs := []runtime.Object{}
sch := makeTestReconcilerScheme(argoproj.AddToScheme)
cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
r := makeTestReconciler(cl, sch)

// Test first instance
err := r.reconcileArgoConfigMap(argocd1)
assert.NoError(t, err)

cm1 := &corev1.ConfigMap{}
err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Namespace: testNamespace,
}, cm1)
assert.NoError(t, err)

// Verify first instance's installationID
assert.Equal(t, "instance-1", cm1.Data[common.ArgoCDKeyInstallationID])

// Test second instance
err = r.reconcileArgoConfigMap(argocd2)
assert.NoError(t, err)

cm2 := &corev1.ConfigMap{}
err = r.Client.Get(context.TODO(), types.NamespacedName{
Name: common.ArgoCDConfigMapName,
Namespace: testNamespace,
}, cm2)
assert.NoError(t, err)

// Verify second instance's installationID
assert.Equal(t, "instance-2", cm2.Data[common.ArgoCDKeyInstallationID])
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ metadata:
capabilities: Deep Insights
categories: Integration & Delivery
certified: "false"
createdAt: "2024-12-20T09:48:39Z"
createdAt: "2025-02-04T21:18:01Z"
description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
operators.operatorframework.io/builder: operator-sdk-v1.35.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
Expand Down Expand Up @@ -611,6 +611,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down Expand Up @@ -1189,6 +1196,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: InstallationID uniquely identifies an Argo CD instance in multi-instance
clusters.
displayName: Installation ID
path: installationID
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: KustomizeVersions is a listing of configured versions of Kustomize
to be made available within ArgoCD.
displayName: Kustomize Build Options'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down Expand Up @@ -14371,6 +14375,10 @@ spec:
have included in your ArgoCD server.
type: string
type: object
installationID:
description: InstallationID uniquely identifies an Argo CD instance
in multi-instance clusters.
type: string
kustomizeBuildOptions:
description: KustomizeBuildOptions is used to specify build options/parameters
to use with `kustomize build`.
Expand Down
4 changes: 2 additions & 2 deletions tests/k8s/1-006_validate-managed-by-chain/01-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ kind: TestAssert
timeout: 720
---
# Wait for the Operator to become available
apiVersion: argoproj.io/v1alpha1
apiVersion: argoproj.io/v1beta1
kind: ArgoCD
metadata:
name: argocd
status:
phase: Available
phase: Available
Loading