Repository: argoproj-labs/argocd-operator
Pull request #845 (2023-01-24 10:25:49)

Progressive delivery of applications using ApplicationSets
**What type of PR is this?**
> /kind enhancement

**What does this PR do / why we need it**:
This is an experimental, alpha-quality feature that allows you to control the order in which the ApplicationSet controller will create or update the Applications owned by an ApplicationSet resource. It may be removed in future releases or modified in backwards-incompatible ways.

The feature only interacts with the health of managed Applications. It is **NOT** intended to support direct integrations with other Rollout controllers (such as the native ReplicaSet controller or Argo Rollouts).
Progressive Rollouts watch for the managed Application resources to become "Healthy" before proceeding to the next stage.

**Enabling Progressive Rollouts**
As an experimental feature, progressive rollouts must be explicitly enabled, in one of the below 3 ways.
1. Pass `--enable-progressive-rollouts` to the ApplicationSet controller args.
    To achieve this using the operator, Users can add the above argument in the Argo CD CR
```
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: example-argocd
  labels:
    example: basic
spec:
  applicationSet:
    extraCommandArgs:
     - --enable-progressive-rollouts
```
2. Set `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS=true` in the ApplicationSet controller environment variables in the below mentioned way.
```
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: example-argocd
  labels:
    example: basic
spec:
  applicationSet:
    env:
     - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_ROLLOUTS
       value: "true"
```
3. Set `applicationsetcontroller.enable.progressive.rollouts: true` in the ArgoCD `ConfigMap`.
```
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: example-argocd
  labels:
    example: basic
spec:
   extraConfig:
     applicationsetcontroller.enable.progressive.rollouts: true
```

**Have you updated the necessary documentation?**
* [x] Documentation update is required by this PR.
* [x] Documentation has been updated.

**How to test changes / Special notes to the reviewer**:
1. Run the operator manually using `make install run`
2. Once the operator is running, submit any one of the 3 Argo CD CRs mentioned above.
3. The expected behavior for each of the example is provided above. 

iam-veeramalla: > ting that fiel

Hi @jaideepr97 , the implementation is same as upstream.

Upstream also supports all the three ways and three are completely unique
iam-veeramalla: @jaideepr97 fyi
https://argo-cd.readthedocs.io/en/latest/operator-manual/applicationset/Progressive-Rollouts/#enabling-progressive-rollouts
jaideepr97: @iam-veeramalla I understand that 
I'm saying as an operator I think we can try and make things more user friendly 
what if we just had a toggle under `.spec.applicationSets.enableProgressiveRollout` that set all these fields to true under the hood? 
iam-veeramalla: > @iam-veeramalla I understand that I'm saying as an operator I think we can try and make things more user friendly what if we just had a toggle under `.spec.applicationSets.enableProgressiveRollout` that set all these fields to true under the hood?

@jaideepr97 Thanks for the suggestion.
The idea here is to implement the `extraCommandArgs` and `env` support so that in the future, we don't need to add more fields to the Argo CD CR w.r.t command arguments or env variable for ApplicationSets.
It might look like we are adding too many place holders for this PR but we are actually not. The applicationset controller lacks these options which are already supported by `controller`, `server`, `repo-server` and other components.
jaideepr97: @iam-veeramalla could we add unit tests as well?
iam-veeramalla: @jaideepr97 added new tests and removed an unintentional change. PTAL, Thanks :)


Patch:
diff --git a/api/v1alpha1/argocd_types.go b/api/v1alpha1/argocd_types.go
index 6a35a87b..fa1c2fa9 100644
--- a/api/v1alpha1/argocd_types.go
+++ b/api/v1alpha1/argocd_types.go
@@ -120,6 +120,15 @@ type ArgoCDApplicationControllerShardSpec struct {
 // ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed.
 type ArgoCDApplicationSet struct {
 
+	// Env lets you specify environment for applicationSet controller pods
+	Env []corev1.EnvVar `json:"env,omitempty"`
+
+	// ExtraCommandArgs allows users to pass command line arguments to ApplicationSet controller.
+	// They get added to default command line arguments provided by the operator.
+	// Please note that the command line arguments provided as part of ExtraCommandArgs
+	// will not overwrite the default command line arguments.
+	ExtraCommandArgs []string `json:"extraCommandArgs,omitempty"`
+
 	// Image is the Argo CD ApplicationSet image (optional)
 	Image string `json:"image,omitempty"`
 
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 81335716..2e7bdc70 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -124,6 +124,18 @@ func (in *ArgoCDApplicationControllerSpec) DeepCopy() *ArgoCDApplicationControll
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ArgoCDApplicationSet) DeepCopyInto(out *ArgoCDApplicationSet) {
 	*out = *in
+	if in.Env != nil {
+		in, out := &in.Env, &out.Env
+		*out = make([]v1.EnvVar, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	if in.ExtraCommandArgs != nil {
+		in, out := &in.ExtraCommandArgs, &out.ExtraCommandArgs
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	if in.Resources != nil {
 		in, out := &in.Resources, &out.Resources
 		*out = new(v1.ResourceRequirements)
diff --git a/build/util/Dockerfile b/build/util/Dockerfile
index 6159d553..ce91320e 100644
--- a/build/util/Dockerfile
+++ b/build/util/Dockerfile
@@ -1,5 +1,5 @@
-# Argo CD v2.5.4
-FROM quay.io/argoproj/argocd@sha256:d5c4f7542580f275ea92fd07da8569cfe9fb6e49b75bbefef01255ccc4b77d57 as argocd
+# Argo CD v2.6.0-rc2
+FROM quay.io/argoproj/argocd@sha256:782a6a571e4f9845a88cfc56ad244fef43edbc55476b76da0762d56ce01621f3 as argocd
 
 # Final Image
 FROM docker.io/library/ubuntu:22.04
diff --git a/bundle/manifests/argoproj.io_applicationsets.yaml b/bundle/manifests/argoproj.io_applicationsets.yaml
index ba1b8e1b..0d7bea54 100644
--- a/bundle/manifests/argoproj.io_applicationsets.yaml
+++ b/bundle/manifests/argoproj.io_applicationsets.yaml
@@ -6463,6 +6463,37 @@ spec:
                 type: array
               goTemplate:
                 type: boolean
+              strategy:
+                properties:
+                  rollingSync:
+                    properties:
+                      steps:
+                        items:
+                          properties:
+                            matchExpressions:
+                              items:
+                                properties:
+                                  key:
+                                    type: string
+                                  operator:
+                                    type: string
+                                  values:
+                                    items:
+                                      type: string
+                                    type: array
+                                type: object
+                              type: array
+                            maxUpdate:
+                              anyOf:
+                              - type: integer
+                              - type: string
+                              x-kubernetes-int-or-string: true
+                          type: object
+                        type: array
+                    type: object
+                  type:
+                    type: string
+                type: object
               syncPolicy:
                 properties:
                   preserveResourcesOnDeletion:
diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml
index c45f9dd0..9b86bd94 100644
--- a/bundle/manifests/argoproj.io_argocds.yaml
+++ b/bundle/manifests/argoproj.io_argocds.yaml
@@ -42,6 +42,126 @@ spec:
                 description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet
                   controller should be installed.
                 properties:
+                  env:
+                    description: Env lets you specify environment for applicationSet
+                      controller pods
+                    items:
+                      description: EnvVar represents an environment variable present
+                        in a Container.
+                      properties:
+                        name:
+                          description: Name of the environment variable. Must be a
+                            C_IDENTIFIER.
+                          type: string
+                        value:
+                          description: 'Variable references $(VAR_NAME) are expanded
+                            using the previously defined environment variables in
+                            the container and any service environment variables. If
+                            a variable cannot be resolved, the reference in the input
+                            string will be unchanged. Double $$ are reduced to a single
+                            $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+                            "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+                            Escaped references will never be expanded, regardless
+                            of whether the variable exists or not. Defaults to "".'
+                          type: string
+                        valueFrom:
+                          description: Source for the environment variable's value.
+                            Cannot be used if value is not empty.
+                          properties:
+                            configMapKeyRef:
+                              description: Selects a key of a ConfigMap.
+                              properties:
+                                key:
+                                  description: The key to select.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the ConfigMap or its
+                                    key must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                            fieldRef:
+                              description: 'Selects a field of the pod: supports metadata.name,
+                                metadata.namespace, `metadata.labels[''<KEY>'']`,
+                                `metadata.annotations[''<KEY>'']`, spec.nodeName,
+                                spec.serviceAccountName, status.hostIP, status.podIP,
+                                status.podIPs.'
+                              properties:
+                                apiVersion:
+                                  description: Version of the schema the FieldPath
+                                    is written in terms of, defaults to "v1".
+                                  type: string
+                                fieldPath:
+                                  description: Path of the field to select in the
+                                    specified API version.
+                                  type: string
+                              required:
+                              - fieldPath
+                              type: object
+                            resourceFieldRef:
+                              description: 'Selects a resource of the container: only
+                                resources limits and requests (limits.cpu, limits.memory,
+                                limits.ephemeral-storage, requests.cpu, requests.memory
+                                and requests.ephemeral-storage) are currently supported.'
+                              properties:
+                                containerName:
+                                  description: 'Container name: required for volumes,
+                                    optional for env vars'
+                                  type: string
+                                divisor:
+                                  anyOf:
+                                  - type: integer
+                                  - type: string
+                                  description: Specifies the output format of the
+                                    exposed resources, defaults to "1"
+                                  pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                  x-kubernetes-int-or-string: true
+                                resource:
+                                  description: 'Required: resource to select'
+                                  type: string
+                              required:
+                              - resource
+                              type: object
+                            secretKeyRef:
+                              description: Selects a key of a secret in the pod's
+                                namespace
+                              properties:
+                                key:
+                                  description: The key of the secret to select from.  Must
+                                    be a valid secret key.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the Secret or its key
+                                    must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                          type: object
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  extraCommandArgs:
+                    description: ExtraCommandArgs allows users to pass command line
+                      arguments to ApplicationSet controller. They get added to default
+                      command line arguments provided by the operator. Please note
+                      that the command line arguments provided as part of ExtraCommandArgs
+                      will not overwrite the default command line arguments.
+                    items:
+                      type: string
+                    type: array
                   image:
                     description: Image is the Argo CD ApplicationSet image (optional)
                     type: string
diff --git a/common/defaults.go b/common/defaults.go
index 7eb0f23b..d9efe72d 100644
--- a/common/defaults.go
+++ b/common/defaults.go
@@ -61,7 +61,7 @@ const (
 	ArgoCDDefaultArgoImage = "quay.io/argoproj/argocd"
 
 	// ArgoCDDefaultArgoVersion is the Argo CD container image digest to use when version not specified.
-	ArgoCDDefaultArgoVersion = "sha256:8283a9f06033c2377dc61b03daf4994a3ab961c53d79ed32b9aebadf79bb4858" // v2.5.3
+	ArgoCDDefaultArgoVersion = "sha256:782a6a571e4f9845a88cfc56ad244fef43edbc55476b76da0762d56ce01621f3" // v2.6.0-rc2
 
 	// ArgoCDDefaultBackupKeyLength is the length of the generated default backup key.
 	ArgoCDDefaultBackupKeyLength = 32
diff --git a/config/crd/bases/argoproj.io_applicationsets.yaml b/config/crd/bases/argoproj.io_applicationsets.yaml
index 748a4a18..2edb5dc2 100644
--- a/config/crd/bases/argoproj.io_applicationsets.yaml
+++ b/config/crd/bases/argoproj.io_applicationsets.yaml
@@ -6462,6 +6462,37 @@ spec:
                 type: array
               goTemplate:
                 type: boolean
+              strategy:
+                properties:
+                  rollingSync:
+                    properties:
+                      steps:
+                        items:
+                          properties:
+                            matchExpressions:
+                              items:
+                                properties:
+                                  key:
+                                    type: string
+                                  operator:
+                                    type: string
+                                  values:
+                                    items:
+                                      type: string
+                                    type: array
+                                type: object
+                              type: array
+                            maxUpdate:
+                              anyOf:
+                              - type: integer
+                              - type: string
+                              x-kubernetes-int-or-string: true
+                          type: object
+                        type: array
+                    type: object
+                  type:
+                    type: string
+                type: object
               syncPolicy:
                 properties:
                   preserveResourcesOnDeletion:
diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml
index 077131db..27ddb0cb 100644
--- a/config/crd/bases/argoproj.io_argocds.yaml
+++ b/config/crd/bases/argoproj.io_argocds.yaml
@@ -44,6 +44,126 @@ spec:
                 description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet
                   controller should be installed.
                 properties:
+                  env:
+                    description: Env lets you specify environment for applicationSet
+                      controller pods
+                    items:
+                      description: EnvVar represents an environment variable present
+                        in a Container.
+                      properties:
+                        name:
+                          description: Name of the environment variable. Must be a
+                            C_IDENTIFIER.
+                          type: string
+                        value:
+                          description: 'Variable references $(VAR_NAME) are expanded
+                            using the previously defined environment variables in
+                            the container and any service environment variables. If
+                            a variable cannot be resolved, the reference in the input
+                            string will be unchanged. Double $$ are reduced to a single
+                            $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+                            "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+                            Escaped references will never be expanded, regardless
+                            of whether the variable exists or not. Defaults to "".'
+                          type: string
+                        valueFrom:
+                          description: Source for the environment variable's value.
+                            Cannot be used if value is not empty.
+                          properties:
+                            configMapKeyRef:
+                              description: Selects a key of a ConfigMap.
+                              properties:
+                                key:
+                                  description: The key to select.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the ConfigMap or its
+                                    key must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                            fieldRef:
+                              description: 'Selects a field of the pod: supports metadata.name,
+                                metadata.namespace, `metadata.labels[''<KEY>'']`,
+                                `metadata.annotations[''<KEY>'']`, spec.nodeName,
+                                spec.serviceAccountName, status.hostIP, status.podIP,
+                                status.podIPs.'
+                              properties:
+                                apiVersion:
+                                  description: Version of the schema the FieldPath
+                                    is written in terms of, defaults to "v1".
+                                  type: string
+                                fieldPath:
+                                  description: Path of the field to select in the
+                                    specified API version.
+                                  type: string
+                              required:
+                              - fieldPath
+                              type: object
+                            resourceFieldRef:
+                              description: 'Selects a resource of the container: only
+                                resources limits and requests (limits.cpu, limits.memory,
+                                limits.ephemeral-storage, requests.cpu, requests.memory
+                                and requests.ephemeral-storage) are currently supported.'
+                              properties:
+                                containerName:
+                                  description: 'Container name: required for volumes,
+                                    optional for env vars'
+                                  type: string
+                                divisor:
+                                  anyOf:
+                                  - type: integer
+                                  - type: string
+                                  description: Specifies the output format of the
+                                    exposed resources, defaults to "1"
+                                  pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                  x-kubernetes-int-or-string: true
+                                resource:
+                                  description: 'Required: resource to select'
+                                  type: string
+                              required:
+                              - resource
+                              type: object
+                            secretKeyRef:
+                              description: Selects a key of a secret in the pod's
+                                namespace
+                              properties:
+                                key:
+                                  description: The key of the secret to select from.  Must
+                                    be a valid secret key.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the Secret or its key
+                                    must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                          type: object
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  extraCommandArgs:
+                    description: ExtraCommandArgs allows users to pass command line
+                      arguments to ApplicationSet controller. They get added to default
+                      command line arguments provided by the operator. Please note
+                      that the command line arguments provided as part of ExtraCommandArgs
+                      will not overwrite the default command line arguments.
+                    items:
+                      type: string
+                    type: array
                   image:
                     description: Image is the Argo CD ApplicationSet image (optional)
                     type: string
diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go
index 1c017f1b..e7828912 100644
--- a/controllers/argocd/applicationset.go
+++ b/controllers/argocd/applicationset.go
@@ -46,6 +46,15 @@ func getArgoApplicationSetCommand(cr *argoprojv1a1.ArgoCD) []string {
 	cmd = append(cmd, "--loglevel")
 	cmd = append(cmd, getLogLevel(cr.Spec.ApplicationSet.LogLevel))
 
+	// ApplicationSet command arguments provided by the user
+	extraArgs := cr.Spec.ApplicationSet.ExtraCommandArgs
+	err := isMergable(extraArgs, cmd)
+	if err != nil {
+		return cmd
+	}
+
+	cmd = append(cmd, extraArgs...)
+
 	return cmd
 }
 
@@ -186,6 +195,10 @@ func applicationSetContainer(cr *argoprojv1a1.ArgoCD) corev1.Container {
 			},
 		},
 	}}
+
+	// Merge ApplicationSet env vars provided by the user
+	// User should be able to override the default NAMESPACE environmental variable
+	appSetEnv = argoutil.EnvMerge(cr.Spec.ApplicationSet.Env, appSetEnv, true)
 	// Environment specified in the CR take precedence over everything else
 	appSetEnv = argoutil.EnvMerge(appSetEnv, proxyEnvVars(), false)
 
diff --git a/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_applicationsets.yaml b/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_applicationsets.yaml
index ba1b8e1b..0d7bea54 100644
--- a/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_applicationsets.yaml
+++ b/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_applicationsets.yaml
@@ -6463,6 +6463,37 @@ spec:
                 type: array
               goTemplate:
                 type: boolean
+              strategy:
+                properties:
+                  rollingSync:
+                    properties:
+                      steps:
+                        items:
+                          properties:
+                            matchExpressions:
+                              items:
+                                properties:
+                                  key:
+                                    type: string
+                                  operator:
+                                    type: string
+                                  values:
+                                    items:
+                                      type: string
+                                    type: array
+                                type: object
+                              type: array
+                            maxUpdate:
+                              anyOf:
+                              - type: integer
+                              - type: string
+                              x-kubernetes-int-or-string: true
+                          type: object
+                        type: array
+                    type: object
+                  type:
+                    type: string
+                type: object
               syncPolicy:
                 properties:
                   preserveResourcesOnDeletion:
diff --git a/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_argocds.yaml
index c45f9dd0..9b86bd94 100644
--- a/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_argocds.yaml
+++ b/deploy/olm-catalog/argocd-operator/0.6.0/argoproj.io_argocds.yaml
@@ -42,6 +42,126 @@ spec:
                 description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet
                   controller should be installed.
                 properties:
+                  env:
+                    description: Env lets you specify environment for applicationSet
+                      controller pods
+                    items:
+                      description: EnvVar represents an environment variable present
+                        in a Container.
+                      properties:
+                        name:
+                          description: Name of the environment variable. Must be a
+                            C_IDENTIFIER.
+                          type: string
+                        value:
+                          description: 'Variable references $(VAR_NAME) are expanded
+                            using the previously defined environment variables in
+                            the container and any service environment variables. If
+                            a variable cannot be resolved, the reference in the input
+                            string will be unchanged. Double $$ are reduced to a single
+                            $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+                            "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+                            Escaped references will never be expanded, regardless
+                            of whether the variable exists or not. Defaults to "".'
+                          type: string
+                        valueFrom:
+                          description: Source for the environment variable's value.
+                            Cannot be used if value is not empty.
+                          properties:
+                            configMapKeyRef:
+                              description: Selects a key of a ConfigMap.
+                              properties:
+                                key:
+                                  description: The key to select.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the ConfigMap or its
+                                    key must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                            fieldRef:
+                              description: 'Selects a field of the pod: supports metadata.name,
+                                metadata.namespace, `metadata.labels[''<KEY>'']`,
+                                `metadata.annotations[''<KEY>'']`, spec.nodeName,
+                                spec.serviceAccountName, status.hostIP, status.podIP,
+                                status.podIPs.'
+                              properties:
+                                apiVersion:
+                                  description: Version of the schema the FieldPath
+                                    is written in terms of, defaults to "v1".
+                                  type: string
+                                fieldPath:
+                                  description: Path of the field to select in the
+                                    specified API version.
+                                  type: string
+                              required:
+                              - fieldPath
+                              type: object
+                            resourceFieldRef:
+                              description: 'Selects a resource of the container: only
+                                resources limits and requests (limits.cpu, limits.memory,
+                                limits.ephemeral-storage, requests.cpu, requests.memory
+                                and requests.ephemeral-storage) are currently supported.'
+                              properties:
+                                containerName:
+                                  description: 'Container name: required for volumes,
+                                    optional for env vars'
+                                  type: string
+                                divisor:
+                                  anyOf:
+                                  - type: integer
+                                  - type: string
+                                  description: Specifies the output format of the
+                                    exposed resources, defaults to "1"
+                                  pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+                                  x-kubernetes-int-or-string: true
+                                resource:
+                                  description: 'Required: resource to select'
+                                  type: string
+                              required:
+                              - resource
+                              type: object
+                            secretKeyRef:
+                              description: Selects a key of a secret in the pod's
+                                namespace
+                              properties:
+                                key:
+                                  description: The key of the secret to select from.  Must
+                                    be a valid secret key.
+                                  type: string
+                                name:
+                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                                    TODO: Add other useful fields. apiVersion, kind,
+                                    uid?'
+                                  type: string
+                                optional:
+                                  description: Specify whether the Secret or its key
+                                    must be defined
+                                  type: boolean
+                              required:
+                              - key
+                              type: object
+                          type: object
+                      required:
+                      - name
+                      type: object
+                    type: array
+                  extraCommandArgs:
+                    description: ExtraCommandArgs allows users to pass command line
+                      arguments to ApplicationSet controller. They get added to default
+                      command line arguments provided by the operator. Please note
+                      that the command line arguments provided as part of ExtraCommandArgs
+                      will not overwrite the default command line arguments.
+                    items:
+                      type: string
+                    type: array
                   image:
                     description: Image is the Argo CD ApplicationSet image (optional)
                     type: string
diff --git a/docs/reference/argocd.md b/docs/reference/argocd.md
index 1633fad3..8d1a0427 100644
--- a/docs/reference/argocd.md
+++ b/docs/reference/argocd.md
@@ -75,6 +75,8 @@ The following properties are available for configuring the ApplicationSet contro
 
 Name | Default | Description
 --- | --- | ---
+Env | [Empty] | Environment to set for the applicationSet controller workloads
+[ExtraCommandArgs](#add-command-arguments-to-applicationsets-controller) | [Empty] | Extra Command arguments allows users to pass command line arguments to applicationSet workload. They get added to default command line arguments provided by the operator.
 Image | `quay.io/argoproj/argocd-applicationset` | The container image for the ApplicationSet controller. This overrides the `ARGOCD_APPLICATIONSET_IMAGE` environment variable.
 Version | *(recent ApplicationSet version)* | The tag to use with the ApplicationSet container image.
 Resources | [Empty] | The container compute resources.
@@ -97,6 +99,23 @@ spec:
   applicationSet: {}
 ```
 
+### Add Command Arguments to ApplicationSets Controller
+
+Below example shows how a user can add command arguments to the ApplicationSet controller. 
+
+``` yaml
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+  labels:
+    example: applicationset
+spec:
+  applicationSet:
+    extraCommandArgs:
+      - --foo
+      - bar
+```
 
 ## Config Management Plugins
 


Test patch:
diff --git a/controllers/argocd/applicationset_test.go b/controllers/argocd/applicationset_test.go
index b99bba01..eb0a7d90 100644
--- a/controllers/argocd/applicationset_test.go
+++ b/controllers/argocd/applicationset_test.go
@@ -497,3 +497,145 @@ func TestReconcileApplicationSet_Service(t *testing.T) {
 	assert.NoError(t, r.reconcileApplicationSetService(a))
 	assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Namespace: s.Namespace, Name: s.Name}, s))
 }
+
+func TestArgoCDApplicationSetCommand(t *testing.T) {
+	a := makeTestArgoCD()
+	a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{}
+	r := makeTestReconciler(t, a)
+
+	baseCommand := []string{
+		"entrypoint.sh",
+		"argocd-applicationset-controller",
+		"--argocd-repo-server",
+		"argocd-repo-server.argocd.svc.cluster.local:8081",
+		"--loglevel",
+		"info",
+	}
+
+	// When a single command argument is passed
+	a.Spec.ApplicationSet.ExtraCommandArgs = []string{
+		"--foo",
+		"bar",
+	}
+
+	deployment := &appsv1.Deployment{}
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	cmd := append(baseCommand, "--foo", "bar")
+	assert.Equal(t, cmd, deployment.Spec.Template.Spec.Containers[0].Command)
+
+	// When multiple command arguments are passed
+	a.Spec.ApplicationSet.ExtraCommandArgs = []string{
+		"--foo",
+		"bar",
+		"--ping",
+		"pong",
+		"test",
+	}
+
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	cmd = append(cmd, "--ping", "pong", "test")
+	assert.Equal(t, cmd, deployment.Spec.Template.Spec.Containers[0].Command)
+
+	// When one of the ExtraCommandArgs already exists in cmd with same or different value
+	a.Spec.ApplicationSet.ExtraCommandArgs = []string{
+		"--argocd-repo-server",
+		"foo.scv.cluster.local:6379",
+	}
+
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	assert.Equal(t, baseCommand, deployment.Spec.Template.Spec.Containers[0].Command)
+
+	// Remove all the command arguments that were added.
+	a.Spec.ApplicationSet.ExtraCommandArgs = []string{}
+
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	assert.Equal(t, baseCommand, deployment.Spec.Template.Spec.Containers[0].Command)
+}
+
+func TestArgoCDApplicationSetEnv(t *testing.T) {
+	a := makeTestArgoCD()
+	a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{}
+	r := makeTestReconciler(t, a)
+
+	defaultEnv := []corev1.EnvVar{
+		{
+			Name: "NAMESPACE",
+			ValueFrom: &corev1.EnvVarSource{
+				FieldRef: &corev1.ObjectFieldSelector{
+					APIVersion: "",
+					FieldPath:  "metadata.namespace",
+				},
+			},
+		},
+	}
+
+	// Pass an environment variable using Argo CD CR.
+	customEnv := []corev1.EnvVar{
+		{
+			Name:  "foo",
+			Value: "bar",
+		},
+	}
+	a.Spec.ApplicationSet.Env = customEnv
+
+	deployment := &appsv1.Deployment{}
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	expectedEnv := append(defaultEnv, customEnv...)
+	assert.Equal(t, expectedEnv, deployment.Spec.Template.Spec.Containers[0].Env)
+
+	// Remove all the env vars that were added.
+	a.Spec.ApplicationSet.Env = []corev1.EnvVar{}
+
+	assert.NoError(t, r.reconcileApplicationSetController(a))
+	assert.NoError(t, r.Client.Get(
+		context.TODO(),
+		types.NamespacedName{
+			Name:      "argocd-applicationset-controller",
+			Namespace: a.Namespace,
+		},
+		deployment))
+
+	assert.Equal(t, defaultEnv, deployment.Spec.Template.Spec.Containers[0].Env)
+}
diff --git a/tests/k8s/1-029_validate_applicationset_extra_command_args/01-assert.yaml b/tests/k8s/1-029_validate_applicationset_extra_command_args/01-assert.yaml
new file mode 100644
index 00000000..bf796a25
--- /dev/null
+++ b/tests/k8s/1-029_validate_applicationset_extra_command_args/01-assert.yaml
@@ -0,0 +1,16 @@
+---
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+  namespace: test-1-29-appsets-extra-command
+status:
+  phase: Available
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: example-argocd-applicationset-controller
+  namespace: test-1-29-appsets-extra-command
+status:
+  readyReplicas: 1
\ No newline at end of file
diff --git a/tests/k8s/1-029_validate_applicationset_extra_command_args/01-basic-argocd-install.yaml b/tests/k8s/1-029_validate_applicationset_extra_command_args/01-basic-argocd-install.yaml
new file mode 100644
index 00000000..c85a23db
--- /dev/null
+++ b/tests/k8s/1-029_validate_applicationset_extra_command_args/01-basic-argocd-install.yaml
@@ -0,0 +1,15 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: test-1-29-appsets-extra-command
+---
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+  namespace: test-1-29-appsets-extra-command
+  labels:
+    example: basic
+spec:
+  applicationSet: {}
\ No newline at end of file
diff --git a/tests/k8s/1-029_validate_applicationset_extra_command_args/02-add-extraCommandArgs.yaml b/tests/k8s/1-029_validate_applicationset_extra_command_args/02-add-extraCommandArgs.yaml
new file mode 100644
index 00000000..bc395ee1
--- /dev/null
+++ b/tests/k8s/1-029_validate_applicationset_extra_command_args/02-add-extraCommandArgs.yaml
@@ -0,0 +1,9 @@
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+  namespace: test-1-29-appsets-extra-command
+spec:
+  applicationSet:
+    extraCommandArgs:
+      - --enable-progressive-rollouts
\ No newline at end of file
diff --git a/tests/k8s/1-029_validate_applicationset_extra_command_args/02-assert.yaml b/tests/k8s/1-029_validate_applicationset_extra_command_args/02-assert.yaml
new file mode 100644
index 00000000..fccc16a8
--- /dev/null
+++ b/tests/k8s/1-029_validate_applicationset_extra_command_args/02-assert.yaml
@@ -0,0 +1,23 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: example-argocd-applicationset-controller
+  namespace: test-1-29-appsets-extra-command
+spec:
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: example-argocd-applicationset-controller
+  template:
+    spec:
+      containers:
+        - command:
+          - entrypoint.sh
+          - argocd-applicationset-controller
+          - --argocd-repo-server
+          - example-argocd-repo-server.test-1-29-appsets-extra-command.svc.cluster.local:8081
+          - --loglevel
+          - info
+          - --enable-progressive-rollouts
+          name: argocd-applicationset-controller
+
diff --git a/tests/k8s/1-029_validate_applicationset_extra_command_args/99-delete.yaml b/tests/k8s/1-029_validate_applicationset_extra_command_args/99-delete.yaml
new file mode 100644
index 00000000..8fbfbba8
--- /dev/null
+++ b/tests/k8s/1-029_validate_applicationset_extra_command_args/99-delete.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: kuttl.dev/v1beta1
+kind: TestStep
+delete:
+- apiVersion: v1
+  kind: Namespace
+  name: test-1-29-appsets-extra-command
\ No newline at end of file
diff --git a/tests/k8s/1-030_validate_applciationset_add_env_vars/01-assert.yaml b/tests/k8s/1-030_validate_applciationset_add_env_vars/01-assert.yaml
new file mode 100644
index 00000000..20b569cf
--- /dev/null
+++ b/tests/k8s/1-030_validate_applciationset_add_env_vars/01-assert.yaml
@@ -0,0 +1,14 @@
+---
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+status:
+  phase: Available
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: example-argocd-applicationset-controller
+status:
+  readyReplicas: 1
\ No newline at end of file
diff --git a/tests/k8s/1-030_validate_applciationset_add_env_vars/01-basic-argocd-install.yaml b/tests/k8s/1-030_validate_applciationset_add_env_vars/01-basic-argocd-install.yaml
new file mode 100644
index 00000000..c87f3631
--- /dev/null
+++ b/tests/k8s/1-030_validate_applciationset_add_env_vars/01-basic-argocd-install.yaml
@@ -0,0 +1,9 @@
+---
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+  labels:
+    example: basic
+spec:
+  applicationSet: {}
\ No newline at end of file
diff --git a/tests/k8s/1-030_validate_applciationset_add_env_vars/02-add-env-vars.yaml b/tests/k8s/1-030_validate_applciationset_add_env_vars/02-add-env-vars.yaml
new file mode 100644
index 00000000..4c8341d7
--- /dev/null
+++ b/tests/k8s/1-030_validate_applciationset_add_env_vars/02-add-env-vars.yaml
@@ -0,0 +1,9 @@
+apiVersion: argoproj.io/v1alpha1
+kind: ArgoCD
+metadata:
+  name: example-argocd
+spec:
+  applicationSet:
+    env:
+     - name: foo
+       value: bar
\ No newline at end of file
diff --git a/tests/k8s/1-030_validate_applciationset_add_env_vars/02-assert.yaml b/tests/k8s/1-030_validate_applciationset_add_env_vars/02-assert.yaml
new file mode 100644
index 00000000..fa16802a
--- /dev/null
+++ b/tests/k8s/1-030_validate_applciationset_add_env_vars/02-assert.yaml
@@ -0,0 +1,22 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: example-argocd-applicationset-controller
+spec:
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: example-argocd-applicationset-controller
+  template:
+    spec:
+      containers:
+        - name: argocd-applicationset-controller
+          env:
+            - name: NAMESPACE
+              valueFrom:
+                fieldRef:
+                  apiVersion: v1
+                  fieldPath: metadata.namespace
+            - name: foo
+              value: bar
+