Skip to content
Merged
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
22 changes: 22 additions & 0 deletions templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{/*
Determines if the current cluster is a hub cluster.
First checks if clusterGroup.isHubCluster is explicitly set and uses that value.
If not set, falls back to comparing global.localClusterDomain and global.hubClusterDomain.
If domains are equal or localClusterDomain is not set (defaults to hubClusterDomain), this is a hub cluster.
Usage: {{ include "ocp_eso.ishubcluster" . }}
Returns: "true" or "false" as a string
*/}}
{{- define "ocp_eso.ishubcluster" -}}
{{- if and (hasKey .Values.clusterGroup "isHubCluster") (not (kindIs "invalid" .Values.clusterGroup.isHubCluster)) -}}
{{- .Values.clusterGroup.isHubCluster | toString -}}
{{- else if $.Values.global.hubClusterDomain -}}
{{- $localDomain := coalesce $.Values.global.localClusterDomain $.Values.global.hubClusterDomain -}}
{{- if eq $localDomain $.Values.global.hubClusterDomain -}}
true
{{- else -}}
false
{{- end -}}
{{- else -}}
false
{{- end -}}
{{- end }}
2 changes: 1 addition & 1 deletion templates/kubernetes/external-secrets-hub-secretstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spec:
server:
url: {{ .Values.ocpExternalSecrets.kubernetes.server.url }}
{{- if .Values.ocpExternalSecrets.caProvider.enabled }}
{{- if .Values.clusterGroup.isHubCluster }}
{{- if (eq (include "ocp_eso.ishubcluster" .) "true") }}
caProvider:
type: {{ .Values.ocpExternalSecrets.caProvider.hostCluster.type }}
name: {{ .Values.ocpExternalSecrets.caProvider.hostCluster.name }}
Expand Down
4 changes: 2 additions & 2 deletions templates/vault/external-secrets-hub-secretstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
# Version of KV backend
version: v2
{{- if .Values.ocpExternalSecrets.caProvider.enabled }}
{{ if or .Values.clusterGroup.isHubCluster $hashicorp_vault_found }}
{{- if or (eq (include "ocp_eso.ishubcluster" .) "true") $hashicorp_vault_found }}
caProvider:
type: {{ .Values.ocpExternalSecrets.caProvider.hostCluster.type }}
name: {{ .Values.ocpExternalSecrets.caProvider.hostCluster.name }}
Expand All @@ -37,7 +37,7 @@ spec:
{{- end }}
auth:
kubernetes:
{{ if or .Values.clusterGroup.isHubCluster $hashicorp_vault_found }}
{{- if or (eq (include "ocp_eso.ishubcluster" .) "true") $hashicorp_vault_found }}
mountPath: {{ .Values.ocpExternalSecrets.vault.mountPath }}
role: {{ .Values.ocpExternalSecrets.rbac.rolename }}
{{ else }}
Expand Down
7 changes: 5 additions & 2 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

## Testing documentation

The syntax for writing tests can be found [here](https://github.com/helm-unittest/helm-unittest/blob/main/DOCUMENT.md)
The syntax for writing tests can be found [at this place here](https://github.com/helm-unittest/helm-unittest/blob/main/DOCUMENT.md)

## Run tests

The following will use a containerized version:

```bash
make helm-unittest
```
Expand All @@ -18,11 +19,13 @@ helm plugin install https://github.com/helm-unittest/helm-unittest.git
```

### Run unittest with locally installed helm and helm plugin

```bash
helm unittest .
```

## Run unittests with docker
## Run unittests with Docker

```bash
docker run -ti --rm -v $(pwd):/apps:z helmunittest/helm-unittest .
```
266 changes: 266 additions & 0 deletions tests/ishubcluster_helper_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
suite: Test ocp_eso.ishubcluster helper function
templates:
- templates/vault/external-secrets-hub-secretstore.yaml
release:
name: release-test
tests:
# ============================================================================
# Tests when clusterGroup.isHubCluster is EXPLICITLY SET
# These should take precedence over domain logic
# ============================================================================

- it: should use isHubCluster=true when explicitly set, ignoring domain logic
set:
clusterGroup:
isHubCluster: true
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "spoke.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: hub-role

- it: should use isHubCluster=false when explicitly set, ignoring matching domains
set:
clusterGroup:
isHubCluster: false
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "hub.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.example.com
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: spoke.example.com-role

# ============================================================================
# Tests when clusterGroup.isHubCluster is UNSET
# These should fall back to domain comparison logic
# ============================================================================

- it: should detect hub cluster when localClusterDomain equals hubClusterDomain
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "hub.example.com"
clusterDomain: "hub.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: hub-role

- it: should detect spoke cluster when localClusterDomain differs from hubClusterDomain
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "spoke.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.example.com
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: spoke.example.com-role

- it: should detect hub cluster when localClusterDomain is not set (defaults to hubClusterDomain)
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
clusterDomain: "hub.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: hub-role

- it: should detect spoke cluster when only hubClusterDomain set and clusterDomain differs
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: hub-role

- it: should default to false (spoke) when hubClusterDomain is not set
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: null
localClusterDomain: "spoke.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.example.com
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: spoke.example.com-role

- it: should default to false (spoke) when no domain configuration is provided
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: null
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.example.com
- equal:
path: spec.provider.vault.auth.kubernetes.role
value: spoke.example.com-role

# ============================================================================
# Tests for caProvider selection based on ishubcluster result
# ============================================================================

- it: should use hostCluster caProvider when detected as hub via domain match
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "hub.example.com"
clusterDomain: "hub.example.com"
secretStore:
backend: "vault"
ocpExternalSecrets:
caProvider:
enabled: true
asserts:
- equal:
path: spec.provider.vault.caProvider.type
value: ConfigMap
- equal:
path: spec.provider.vault.caProvider.name
value: kube-root-ca.crt

- it: should use clientCluster caProvider when detected as spoke via domain mismatch
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: "spoke.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
ocpExternalSecrets:
caProvider:
enabled: true
asserts:
- equal:
path: spec.provider.vault.caProvider.type
value: Secret
- equal:
path: spec.provider.vault.caProvider.name
value: hub-ca

# ============================================================================
# Edge cases for domain comparison
# ============================================================================

- it: should handle domains with subdomains correctly - matching
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.apps.cluster.example.com"
localClusterDomain: "hub.apps.cluster.example.com"
clusterDomain: "hub.apps.cluster.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub

- it: should handle domains with subdomains correctly - not matching
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.apps.cluster.example.com"
localClusterDomain: "spoke.apps.cluster.example.com"
clusterDomain: "spoke.apps.cluster.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.apps.cluster.example.com

- it: should treat empty localClusterDomain as unset (default to hubClusterDomain)
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: "hub.example.com"
localClusterDomain: ""
clusterDomain: "hub.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: hub

- it: should handle empty hubClusterDomain as unset (default to false)
set:
clusterGroup:
isHubCluster: null
global:
hubClusterDomain: ""
localClusterDomain: "spoke.example.com"
clusterDomain: "spoke.example.com"
secretStore:
backend: "vault"
asserts:
- equal:
path: spec.provider.vault.auth.kubernetes.mountPath
value: spoke.example.com
3 changes: 2 additions & 1 deletion values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ global:
backend: "vault"

clusterGroup:
applications: {}
# -- The variable that defines when a cluster is the HUB
isHubCluster: true
# (Deprecated) isHubCluster: true