Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions api/v1beta1/argocd_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,12 @@ type ArgoCDSpec struct {
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD","urn:alm:descriptor:com.tectonic.ui:text"}
Version string `json:"version,omitempty"`

// ClusterDomain is the cluster domain suffix used for constructing service FQDNs. Defaults to "cluster.local".
// The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
// This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local", "edge.local").
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Cluster Domain'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"}
ClusterDomain string `json:"clusterDomain,omitempty"`

// Banner defines an additional banner to be displayed in Argo CD UI
Banner *Banner `json:"banner,omitempty"`

Expand Down
11 changes: 10 additions & 1 deletion bundle/manifests/argocd-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ metadata:
capabilities: Deep Insights
categories: Integration & Delivery
certified: "false"
createdAt: "2025-08-28T14:32:44Z"
createdAt: "2025-09-15T13:17:46Z"
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 @@ -1070,6 +1070,15 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: 'ClusterDomain is the cluster domain suffix used for constructing
service FQDNs. Defaults to "cluster.local". The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local",
"edge.local").'
displayName: Cluster Domain'
path: clusterDomain
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: 'Deprecated: ConfigManagementPlugins field is no longer supported.
Argo CD now requires plugins to be defined as sidecar containers of repo
server component. See ''.spec.repo.sidecarContainers''. ConfigManagementPlugins
Expand Down
6 changes: 6 additions & 0 deletions bundle/manifests/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10248,6 +10248,12 @@ spec:
required:
- content
type: object
clusterDomain:
description: |-
ClusterDomain is the cluster domain suffix used for constructing service FQDNs. Defaults to "cluster.local".
The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local", "edge.local").
type: string
cmdParams:
additionalProperties:
type: string
Expand Down
3 changes: 3 additions & 0 deletions common/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOf

// ArgoCDAgentPrincipalDefaultImageName is the default image name for the ArgoCD agent principal.
ArgoCDAgentPrincipalDefaultImageName = "quay.io/argoprojlabs/argocd-agent:v0.3.2"

// ArgoCDDefaultClusterDomain is the default cluster domain suffix for service FQDNs.
ArgoCDDefaultClusterDomain = "cluster.local"
)

// DefaultLabels returns the default set of labels for controllers.
Expand Down
4 changes: 2 additions & 2 deletions config/certmanager/certificate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ metadata:
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
namespace: system
spec:
# $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
# $(SERVICE_NAME), $(SERVICE_NAMESPACE) and $(CLUSTER_DOMAIN) will be substituted by kustomize
dnsNames:
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.$(CLUSTER_DOMAIN)
issuerRef:
kind: Issuer
name: selfsigned-issuer
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10237,6 +10237,12 @@ spec:
required:
- content
type: object
clusterDomain:
description: |-
ClusterDomain is the cluster domain suffix used for constructing service FQDNs. Defaults to "cluster.local".
The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local", "edge.local").
type: string
cmdParams:
additionalProperties:
type: string
Expand Down
2 changes: 2 additions & 0 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ vars:
# kind: Service
# version: v1
# name: webhook-service
#- name: CLUSTER_DOMAIN
# value: cluster.local
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,15 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: 'ClusterDomain is the cluster domain suffix used for constructing
service FQDNs. Defaults to "cluster.local". The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local",
"edge.local").'
displayName: Cluster Domain'
path: clusterDomain
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: 'Deprecated: ConfigManagementPlugins field is no longer supported.
Argo CD now requires plugins to be defined as sidecar containers of repo
server component. See ''.spec.repo.sidecarContainers''. ConfigManagementPlugins
Expand Down
2 changes: 1 addition & 1 deletion controllers/argocd/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func newCertificateSecret(suffix string, caCert *x509.Certificate, caKey *rsa.Pr
dnsNames := []string{
cr.Name,
nameWithSuffix("grpc", cr),
fmt.Sprintf("%s.%s.svc.cluster.local", cr.Name, cr.Namespace),
fmt.Sprintf("%s.%s.svc.%s", cr.Name, cr.Namespace, getClusterDomain(cr)),
}

//lint:ignore SA1019 known to be deprecated
Expand Down
13 changes: 11 additions & 2 deletions controllers/argocd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ func getRedisServerAddress(cr *argoproj.ArgoCD) string {

// If principal is enabled, then Argo CD server/repo server should be configured to use redis proxy from principal (argo cd agent)
if cr.Spec.ArgoCDAgent != nil && cr.Spec.ArgoCDAgent.Principal != nil && cr.Spec.ArgoCDAgent.Principal.IsEnabled() {
return argoutil.GenerateAgentPrincipalRedisProxyServiceName(cr.Name) + "." + cr.Namespace + ".svc.cluster.local:6379"
return fmt.Sprintf("%s.%s.svc.%s:6379", argoutil.GenerateAgentPrincipalRedisProxyServiceName(cr.Name), cr.Namespace, getClusterDomain(cr))
}

if cr.Spec.HA.Enabled {
Expand Down Expand Up @@ -592,10 +592,19 @@ func nameWithSuffix(suffix string, cr *argoproj.ArgoCD) string {
return fmt.Sprintf("%s-%s", cr.Name, suffix)
}

// getClusterDomain returns the cluster domain suffix for the given ArgoCD instance.
// If not specified in the CR, defaults to the standard cluster domain.
func getClusterDomain(cr *argoproj.ArgoCD) string {
if cr.Spec.ClusterDomain != "" {
return cr.Spec.ClusterDomain
}
return common.ArgoCDDefaultClusterDomain
}

// fqdnServiceRef will return the FQDN referencing a specific service name, as set up by the operator, with the
// given port.
func fqdnServiceRef(service string, port int, cr *argoproj.ArgoCD) string {
return fmt.Sprintf("%s.%s.svc.cluster.local:%d", nameWithSuffix(service, cr), cr.Namespace, port)
return fmt.Sprintf("%s.%s.svc.%s:%d", nameWithSuffix(service, cr), cr.Namespace, getClusterDomain(cr), port)
}

// InspectCluster will verify the availability of extra features available to the cluster, such as Prometheus and
Expand Down
192 changes: 192 additions & 0 deletions controllers/argocd/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1697,3 +1697,195 @@ func TestGetNamespacesToDelete(t *testing.T) {
})
}
}

func TestGetClusterDomain(t *testing.T) {
tests := []struct {
name string
clusterDomain string
expectedDomain string
}{
{
name: "default cluster domain when not specified",
clusterDomain: "",
expectedDomain: "cluster.local",
},
{
name: "custom cluster domain",
clusterDomain: "CLUSTER_ID.cluster.local",
expectedDomain: "CLUSTER_ID.cluster.local",
},
{
name: "custom domain for different cloud provider",
clusterDomain: "eks.amazonaws.com",
expectedDomain: "eks.amazonaws.com",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := makeTestArgoCD()
a.Spec.ClusterDomain = tt.clusterDomain

result := getClusterDomain(a)
assert.Equal(t, tt.expectedDomain, result)
})
}
}

func TestFqdnServiceRefWithCustomDomain(t *testing.T) {
tests := []struct {
name string
service string
port int
clusterDomain string
expectedFQDN string
}{
{
name: "default cluster domain",
service: "redis",
port: 6379,
clusterDomain: "",
expectedFQDN: "argocd-redis.argocd.svc.cluster.local:6379",
},
{
name: "custom cluster domain",
service: "redis",
port: 6379,
clusterDomain: "CLUSTER_ID.cluster.local",
expectedFQDN: "argocd-redis.argocd.svc.CLUSTER_ID.cluster.local:6379",
},
{
name: "repo server with custom domain",
service: "repo-server",
port: 8081,
clusterDomain: "eks.amazonaws.com",
expectedFQDN: "argocd-repo-server.argocd.svc.eks.amazonaws.com:8081",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := makeTestArgoCD()
a.Spec.ClusterDomain = tt.clusterDomain

result := fqdnServiceRef(tt.service, tt.port, a)
assert.Equal(t, tt.expectedFQDN, result)
})
}
}

func TestGetRedisServerAddressWithCustomDomain(t *testing.T) {
tests := []struct {
name string
clusterDomain string
haEnabled bool
remoteRedis *string
expectedAddr string
}{
{
name: "default cluster domain - standalone redis",
clusterDomain: "",
haEnabled: false,
expectedAddr: "argocd-redis.argocd.svc.cluster.local:6379",
},
{
name: "custom cluster domain - standalone redis",
clusterDomain: "CLUSTER_ID.cluster.local",
haEnabled: false,
expectedAddr: "argocd-redis.argocd.svc.CLUSTER_ID.cluster.local:6379",
},
{
name: "custom cluster domain - HA redis",
clusterDomain: "eks.amazonaws.com",
haEnabled: true,
expectedAddr: "argocd-redis-ha-haproxy.argocd.svc.eks.amazonaws.com:6379",
},
{
name: "remote redis - custom domain ignored",
remoteRedis: stringPtr("remote-redis:6379"),
expectedAddr: "remote-redis:6379",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := makeTestArgoCD()
a.Spec.ClusterDomain = tt.clusterDomain
a.Spec.HA.Enabled = tt.haEnabled
a.Spec.Redis.Remote = tt.remoteRedis

result := getRedisServerAddress(a)
assert.Equal(t, tt.expectedAddr, result)
})
}
}

// stringPtr is a helper function to get a pointer to a string
func stringPtr(s string) *string {
return &s
}

func TestGetDexServerAddressWithCustomDomain(t *testing.T) {
tests := []struct {
name string
clusterDomain string
expectedAddr string
}{
{
name: "default cluster domain",
clusterDomain: "",
expectedAddr: "https://argocd-dex-server.argocd.svc.cluster.local:5556",
},
{
name: "custom cluster domain",
clusterDomain: "CLUSTER_ID.cluster.local",
expectedAddr: "https://argocd-dex-server.argocd.svc.CLUSTER_ID.cluster.local:5556",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := makeTestArgoCD()
a.Spec.ClusterDomain = tt.clusterDomain

result := getDexServerAddress(a)
assert.Equal(t, tt.expectedAddr, result)
})
}
}

func TestGetRepoServerAddressWithCustomDomain(t *testing.T) {
tests := []struct {
name string
clusterDomain string
remoteRepo *string
expectedAddr string
}{
{
name: "default cluster domain",
clusterDomain: "",
expectedAddr: "argocd-repo-server.argocd.svc.cluster.local:8081",
},
{
name: "custom cluster domain",
clusterDomain: "CLUSTER_ID.cluster.local",
expectedAddr: "argocd-repo-server.argocd.svc.CLUSTER_ID.cluster.local:8081",
},
{
name: "remote repo server - custom domain ignored",
remoteRepo: stringPtr("remote-repo:8081"),
expectedAddr: "remote-repo:8081",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := makeTestArgoCD()
a.Spec.ClusterDomain = tt.clusterDomain
a.Spec.Repo.Remote = tt.remoteRepo

result := getRepoServerAddress(a)
assert.Equal(t, tt.expectedAddr, result)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ metadata:
capabilities: Deep Insights
categories: Integration & Delivery
certified: "false"
createdAt: "2025-08-28T14:32:44Z"
createdAt: "2025-09-15T13:17:46Z"
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 @@ -1070,6 +1070,15 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus
- urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: 'ClusterDomain is the cluster domain suffix used for constructing
service FQDNs. Defaults to "cluster.local". The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local",
"edge.local").'
displayName: Cluster Domain'
path: clusterDomain
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: 'Deprecated: ConfigManagementPlugins field is no longer supported.
Argo CD now requires plugins to be defined as sidecar containers of repo
server component. See ''.spec.repo.sidecarContainers''. ConfigManagementPlugins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10248,6 +10248,12 @@ spec:
required:
- content
type: object
clusterDomain:
description: |-
ClusterDomain is the cluster domain suffix used for constructing service FQDNs. Defaults to "cluster.local".
The full FQDN will be: <service>.<namespace>.svc.<clusterDomain>
This is useful for clusters that use a different DNS suffix (e.g., "CLUSTER_ID.cluster.local", "edge.local").
type: string
cmdParams:
additionalProperties:
type: string
Expand Down
7 changes: 7 additions & 0 deletions examples/argocd-custom-cluster-domain.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: argoproj.io/v1beta1
kind: ArgoCD
metadata:
name: example-argocd
namespace: argocd
spec:
clusterDomain: "abc123.cluster.local"
Loading