Skip to content

Commit 0a5dfcf

Browse files
committed
fix(common): model externalRefs services as Service kind
Signed-off-by: Patrik Deke <patrik.deke@bedag.ch>
1 parent 7b6c29e commit 0a5dfcf

11 files changed

Lines changed: 99 additions & 75 deletions

‎charts/common/Chart.yaml‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ annotations:
2828
artifacthub.io/license: Apache-2.0
2929
artifacthub.io/changes: |
3030
- kind: added
31-
description: "externalRefs: unified registry for ConfigMaps, Secrets, PVCs, and ExternalName services (list format with id field)"
31+
description: "externalRefs: unified registry for ConfigMaps, Secrets, PVCs, and Services (list format with id field)"
3232
- kind: added
33-
description: "externalRefs: ExternalName kind support with mode create (chart-managed) and reference (pre-existing)"
33+
description: "externalRefs: Service kind support with mode create (ExternalName service) and reference (pre-existing service)"
3434
- kind: added
35-
description: "externalRefs: new externalServiceRef env field resolves ExternalName service names in container env vars"
35+
description: "externalRefs: new externalServiceRef env field resolves referenced service names in container env vars"
3636
- kind: added
37-
description: "externalRefs: mode field (create/reference) for ExternalName entries"
37+
description: "externalRefs: mode field (create/reference) for Service entries"
3838
- kind: added
3939
description: "externalRef support for envFrom, volumes, env valueFrom secretKeyRef/configMapKeyRef"
4040
- kind: added
@@ -56,4 +56,4 @@ annotations:
5656
- kind: changed
5757
description: "DX: title properties on oneOf schema branches for clearer validation error messages"
5858
- kind: removed
59-
description: "Removed standalone externalNameServices section (merged into externalRefs with kind: ExternalName)"
59+
description: "Removed standalone externalNameServices section (merged into externalRefs with kind: Service)"

‎charts/common/README.md‎

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Major Changes to functions are documented with the version affected. **Before up
2525
|networkpolicy template changes|10.0.0|add possibility to create multiple networkpolicies|https://github.com/bedag/helm-charts/pull/77|
2626
|ingress template changes|11.0.0|add possibility to create multiple ingress objects|https://github.com/bedag/helm-charts/pull/134
2727
|ingress template changes|12.0.0|support defining multiple hosts and secrets for one ingress|https://github.com/bedag/helm-charts/pull/138
28-
|unified externalRefs|12.7.0|List-based externalRefs registry for ConfigMaps, Secrets, PVCs, and ExternalName services. Supports `mode: create` (chart-managed) and `mode: reference` (pre-existing). New `externalServiceRef` env field resolves ExternalName service names.|
28+
|unified externalRefs|12.7.0|List-based externalRefs registry for ConfigMaps, Secrets, PVCs, and Services. Supports `mode: create` (chart-managed ExternalName Service) and `mode: reference` (pre-existing Service). New `externalServiceRef` env field resolves Service names.|
2929

3030
# Values by Component
3131

@@ -74,7 +74,7 @@ Major Changes to functions are documented with the version affected. **Before up
7474
The `externalRefs` feature provides a unified registry for declaring external dependencies at the top level of your values. It supports four resource kinds:
7575

7676
- **ConfigMap** / **Secret** / **PersistentVolumeClaim** — reference pre-existing resources by alias in `envFrom`, `volumes`, `env valueFrom`, Ingress TLS, ServiceMonitor basicAuth, and imagePullSecrets
77-
- **ExternalName** — create or reference Kubernetes `ExternalName` services for external dependencies (databases, caches, APIs), resolvable in env vars via `externalServiceRef`
77+
- **Service** — create a Kubernetes `Service` with `spec.type: ExternalName`, or reference an existing Service for external dependencies (databases, caches, APIs), resolvable in env vars via `externalServiceRef`
7878

7979
Enable the feature by setting `includes.externalRefs: true`.
8080

@@ -85,23 +85,21 @@ Each entry in the `externalRefs` list supports:
8585
| Field | Required | Default | Description |
8686
|-------|----------|---------|-------------|
8787
| `id` | Yes | — | Unique alias for referencing this entry |
88-
| `kind` | Yes | — | Resource kind: `ConfigMap`, `Secret`, `PersistentVolumeClaim`, or `ExternalName` |
89-
| `mode` | No | `reference` | `reference` (pre-existing resource) or `create` (chart creates the resource). Only `ExternalName` supports `create`. |
88+
| `kind` | Yes | — | Resource kind: `ConfigMap`, `Secret`, `PersistentVolumeClaim`, or `Service` |
89+
| `mode` | No | `reference` | `reference` (pre-existing resource) or `create` (chart creates the resource). Only `Service` supports `create`. |
9090
| `name` | When mode=reference | — | Actual Kubernetes resource name |
91-
| `externalName` | When kind=ExternalName, mode=create | — | DNS hostname for the ExternalName service |
92-
| `fullnameOverride` | No | — | Override the generated ExternalName service name entirely (ExternalName + create only) |
93-
| `annotations` | No | — | Additional annotations for ExternalName services |
94-
| `group` | No | `""` | API group (empty string for core resources) |
95-
| `version` | No | `"v1"` | API version |
91+
| `externalName` | When kind=Service, mode=create | — | DNS hostname for the rendered `Service.spec.externalName` |
92+
| `fullnameOverride` | No | — | Override the generated Service name entirely (`kind: Service` + `mode: create` only) |
93+
| `annotations` | No | — | Additional annotations for created Services |
9694
| `optional` | No | — | Mark the reference as optional |
9795

9896
### Mode behavior
9997

10098
| Kind | Allowed modes | What happens |
10199
|------|--------------|--------------|
102100
| ConfigMap / Secret / PVC | `reference` only | No resource created. `name` is used for lookups. |
103-
| ExternalName | `create` | Chart creates a `Service/ExternalName`. Name = `fullnameOverride` or `<library.name>-<id>`. |
104-
| ExternalName | `reference` | No resource created. `name` used for `externalServiceRef` resolution. |
101+
| Service | `create` | Chart creates a `Service` with `spec.type: ExternalName`. Name = `fullnameOverride` or `<library.name>-<id>`. |
102+
| Service | `reference` | No resource created. `name` used for `externalServiceRef` resolution. |
105103

106104
### Registry definition
107105

@@ -126,24 +124,24 @@ externalRefs:
126124
kind: PersistentVolumeClaim
127125
name: shared-data-pvc
128126

129-
# ExternalName — chart creates the Service
127+
# Service — chart creates a Service with spec.type=ExternalName
130128
- id: database
131-
kind: ExternalName
129+
kind: Service
132130
mode: create
133131
externalName: db.prod.example.com
134132

135-
# ExternalName — exact name override
133+
# Service — exact name override
136134
- id: cache
137-
kind: ExternalName
135+
kind: Service
138136
mode: create
139137
externalName: cache.prod.example.com
140138
fullnameOverride: "redis-cache"
141139
annotations:
142140
service.beta.kubernetes.io/description: "External Redis cache"
143141

144-
# ExternalName — reference a pre-existing service
142+
# Service — reference a pre-existing service
145143
- id: partner-api
146-
kind: ExternalName
144+
kind: Service
147145
mode: reference
148146
name: partner-api-gateway
149147
```
@@ -192,7 +190,7 @@ controller:
192190

193191
### externalServiceRef
194192

195-
For `ExternalName` entries, use `externalServiceRef` in env vars to resolve the Kubernetes service name:
193+
For `Service` entries, use `externalServiceRef` in env vars to resolve the Kubernetes service name:
196194

197195
- **mode: create** — resolves to `fullnameOverride` or `<library.name>-<id>`
198196
- **mode: reference** — resolves to `name`

‎charts/common/README.md.gotmpl‎

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Major Changes to functions are documented with the version affected. **Before up
3434
|networkpolicy template changes|10.0.0|add possibility to create multiple networkpolicies|https://github.com/bedag/helm-charts/pull/77|
3535
|ingress template changes|11.0.0|add possibility to create multiple ingress objects|https://github.com/bedag/helm-charts/pull/134
3636
|ingress template changes|12.0.0|support defining multiple hosts and secrets for one ingress|https://github.com/bedag/helm-charts/pull/138
37-
|unified externalRefs|12.7.0|List-based externalRefs registry for ConfigMaps, Secrets, PVCs, and ExternalName services. Supports `mode: create` (chart-managed) and `mode: reference` (pre-existing). New `externalServiceRef` env field resolves ExternalName service names.|
37+
|unified externalRefs|12.7.0|List-based externalRefs registry for ConfigMaps, Secrets, PVCs, and Services. Supports `mode: create` (chart-managed ExternalName Service) and `mode: reference` (pre-existing Service). New `externalServiceRef` env field resolves Service names.|
3838
{{/*
3939
Chart Values
4040
*/}}
@@ -71,7 +71,7 @@ Major Changes to functions are documented with the version affected. **Before up
7171
The `externalRefs` feature provides a unified registry for declaring external dependencies at the top level of your values. It supports four resource kinds:
7272

7373
- **ConfigMap** / **Secret** / **PersistentVolumeClaim** — reference pre-existing resources by alias in `envFrom`, `volumes`, `env valueFrom`, Ingress TLS, ServiceMonitor basicAuth, and imagePullSecrets
74-
- **ExternalName** — create or reference Kubernetes `ExternalName` services for external dependencies (databases, caches, APIs), resolvable in env vars via `externalServiceRef`
74+
- **Service** — create a Kubernetes `Service` with `spec.type: ExternalName`, or reference an existing Service for external dependencies (databases, caches, APIs), resolvable in env vars via `externalServiceRef`
7575

7676
Enable the feature by setting `includes.externalRefs: true`.
7777

@@ -82,23 +82,21 @@ Each entry in the `externalRefs` list supports:
8282
| Field | Required | Default | Description |
8383
|-------|----------|---------|-------------|
8484
| `id` | Yes | — | Unique alias for referencing this entry |
85-
| `kind` | Yes | — | Resource kind: `ConfigMap`, `Secret`, `PersistentVolumeClaim`, or `ExternalName` |
86-
| `mode` | No | `reference` | `reference` (pre-existing resource) or `create` (chart creates the resource). Only `ExternalName` supports `create`. |
85+
| `kind` | Yes | — | Resource kind: `ConfigMap`, `Secret`, `PersistentVolumeClaim`, or `Service` |
86+
| `mode` | No | `reference` | `reference` (pre-existing resource) or `create` (chart creates the resource). Only `Service` supports `create`. |
8787
| `name` | When mode=reference | — | Actual Kubernetes resource name |
88-
| `externalName` | When kind=ExternalName, mode=create | — | DNS hostname for the ExternalName service |
89-
| `fullnameOverride` | No | — | Override the generated ExternalName service name entirely (ExternalName + create only) |
90-
| `annotations` | No | — | Additional annotations for ExternalName services |
91-
| `group` | No | `""` | API group (empty string for core resources) |
92-
| `version` | No | `"v1"` | API version |
88+
| `externalName` | When kind=Service, mode=create | — | DNS hostname for the rendered `Service.spec.externalName` |
89+
| `fullnameOverride` | No | — | Override the generated Service name entirely (`kind: Service` + `mode: create` only) |
90+
| `annotations` | No | — | Additional annotations for created Services |
9391
| `optional` | No | — | Mark the reference as optional |
9492

9593
### Mode behavior
9694

9795
| Kind | Allowed modes | What happens |
9896
|------|--------------|--------------|
9997
| ConfigMap / Secret / PVC | `reference` only | No resource created. `name` is used for lookups. |
100-
| ExternalName | `create` | Chart creates a `Service/ExternalName`. Name = `fullnameOverride` or `<library.name>-<id>`. |
101-
| ExternalName | `reference` | No resource created. `name` used for `externalServiceRef` resolution. |
98+
| Service | `create` | Chart creates a `Service` with `spec.type: ExternalName`. Name = `fullnameOverride` or `<library.name>-<id>`. |
99+
| Service | `reference` | No resource created. `name` used for `externalServiceRef` resolution. |
102100

103101
### Registry definition
104102

@@ -123,24 +121,24 @@ externalRefs:
123121
kind: PersistentVolumeClaim
124122
name: shared-data-pvc
125123
126-
# ExternalName — chart creates the Service
124+
# Service — chart creates a Service with spec.type=ExternalName
127125
- id: database
128-
kind: ExternalName
126+
kind: Service
129127
mode: create
130128
externalName: db.prod.example.com
131129
132-
# ExternalName — exact name override
130+
# Service — exact name override
133131
- id: cache
134-
kind: ExternalName
132+
kind: Service
135133
mode: create
136134
externalName: cache.prod.example.com
137135
fullnameOverride: "redis-cache"
138136
annotations:
139137
service.beta.kubernetes.io/description: "External Redis cache"
140138
141-
# ExternalName — reference a pre-existing service
139+
# Service — reference a pre-existing service
142140
- id: partner-api
143-
kind: ExternalName
141+
kind: Service
144142
mode: reference
145143
name: partner-api-gateway
146144
```
@@ -189,7 +187,7 @@ controller:
189187

190188
### externalServiceRef
191189

192-
For `ExternalName` entries, use `externalServiceRef` in env vars to resolve the Kubernetes service name:
190+
For `Service` entries, use `externalServiceRef` in env vars to resolve the Kubernetes service name:
193191

194192
- **mode: create** — resolves to `fullnameOverride` or `<library.name>-<id>`
195193
- **mode: reference** — resolves to `name`
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
includes:
2+
externalRefs: true
3+
4+
# Negative regression fixture:
5+
# Duplicate ids must fail validation even when only the includes.externalRefs render path is enabled.
6+
externalRefs:
7+
- id: duplicate-service
8+
kind: Service
9+
mode: create
10+
externalName: db-one.prod.example.com
11+
12+
- id: duplicate-service
13+
kind: Service
14+
mode: create
15+
externalName: db-two.prod.example.com
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
includes:
2+
externalRefs: true
3+
4+
# Negative regression fixture:
5+
# Unknown kinds must be rejected by schema validation.
6+
externalRefs:
7+
- id: invalid-service
8+
kind: InvalidKind
9+
mode: create
10+
externalName: db.prod.example.com

‎charts/common/ci/values.test.yaml‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ pvcs:
7878
- name: name-of-pvc
7979
# end common.pvcs
8080

81-
# externalRefs is a unified registry of external dependencies
81+
# externalRefs is the happy-path coverage for the unified registry.
82+
# This fixture should render successfully and exercise both reference-based lookups
83+
# and chart-managed Services with `spec.type: ExternalName`.
8284
externalRefs:
8385
- id: app-config
8486
kind: ConfigMap
@@ -90,22 +92,22 @@ externalRefs:
9092
- id: shared-data
9193
kind: PersistentVolumeClaim
9294
name: shared-data-pvc
93-
# ExternalName service — mode: create renders a Service/ExternalName resource
95+
# mode=create should render a Service with `spec.type: ExternalName`
9496
- id: ext-database
95-
kind: ExternalName
97+
kind: Service
9698
mode: create
9799
externalName: db.prod.example.com
98-
# ExternalName with fullnameOverride and annotations
100+
# fullnameOverride and annotations should be applied to the rendered Service
99101
- id: ext-cache
100-
kind: ExternalName
102+
kind: Service
101103
mode: create
102104
externalName: cache.prod.example.com
103105
fullnameOverride: "redis-cache"
104106
annotations:
105107
service.beta.kubernetes.io/description: "External Redis cache"
106-
# ExternalName reference — points to an existing service, no resource created
108+
# mode=reference should not render a resource and should resolve to this existing Service name
107109
- id: partner-api
108-
kind: ExternalName
110+
kind: Service
109111
mode: reference
110112
name: partner-api-gateway
111113

‎charts/common/templates/_externalname-service.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{{- define "common.externalNameService" -}}
22
{{- $root := . }}
33
{{- range $ref := .Values.externalRefs }}
4-
{{- if and (eq $ref.kind "ExternalName") (eq ($ref.mode | default "reference") "create") }}
4+
{{- if and (eq $ref.kind "Service") (eq ($ref.mode | default "reference") "create") }}
55
---
66
apiVersion: v1
77
kind: Service

‎charts/common/templates/helpers/_externalrefs.tpl‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
library.externalRefs.validate validates the top-level externalRefs list.
33
Context: dict with keys:
44
- externalRefs: list of externalRef entries (each a dict with id, kind, name/externalName, mode, optional).
5-
- root: the root context (needed for ExternalName service name computation).
5+
- root: the root context (needed for Service kind name computation).
66
Fails if:
77
- Any entry is missing id or kind
88
- id is not unique
9-
- kind is not one of: ConfigMap, Secret, PersistentVolumeClaim, ExternalName
9+
- kind is not one of: ConfigMap, Secret, PersistentVolumeClaim, Service
1010
- mode is invalid for the given kind
1111
- Required fields for the mode are missing
1212
*/ -}}
@@ -34,7 +34,7 @@ Fails if:
3434
{{- if not (hasKey $ref "kind") -}}
3535
{{- fail (printf "externalRefs[%d] (id=%s): missing required field 'kind'" $idx $ref.id) -}}
3636
{{- end -}}
37-
{{- $allowedKinds := list "ConfigMap" "Secret" "PersistentVolumeClaim" "ExternalName" -}}
37+
{{- $allowedKinds := list "ConfigMap" "Secret" "PersistentVolumeClaim" "Service" -}}
3838
{{- if not (has $ref.kind $allowedKinds) -}}
3939
{{- fail (printf "externalRefs[%d] (id=%s): kind '%s' is not valid (allowed: %s)" $idx $ref.id $ref.kind (join ", " $allowedKinds)) -}}
4040
{{- end -}}
@@ -45,8 +45,8 @@ Fails if:
4545
{{- fail (printf "externalRefs[%d] (id=%s): mode '%s' is not valid (allowed: create, reference)" $idx $ref.id $mode) -}}
4646
{{- end -}}
4747
{{- /* ConfigMap/Secret/PVC only support reference mode */ -}}
48-
{{- if and (ne $ref.kind "ExternalName") (eq $mode "create") -}}
49-
{{- fail (printf "externalRefs[%d] (id=%s): mode 'create' is only valid for kind 'ExternalName' (got kind '%s')" $idx $ref.id $ref.kind) -}}
48+
{{- if and (ne $ref.kind "Service") (eq $mode "create") -}}
49+
{{- fail (printf "externalRefs[%d] (id=%s): mode 'create' is only valid for kind 'Service' (got kind '%s')" $idx $ref.id $ref.kind) -}}
5050
{{- end -}}
5151
{{- /* Validate required fields based on mode */ -}}
5252
{{- if eq $mode "reference" -}}
@@ -65,8 +65,8 @@ Fails if:
6565
{{- fail (printf "externalRefs[%d] (id=%s): 'externalName' must not be empty for mode 'create'" $idx $ref.id) -}}
6666
{{- end -}}
6767
{{- end -}}
68-
{{- /* Default group and version for non-ExternalName kinds */ -}}
69-
{{- if ne $ref.kind "ExternalName" -}}
68+
{{- /* Default group and version for non-Service kinds */ -}}
69+
{{- if ne $ref.kind "Service" -}}
7070
{{- if not (hasKey $ref "group") -}}
7171
{{- $_ := set $ref "group" "" -}}
7272
{{- end -}}
@@ -164,24 +164,24 @@ Fails if value is empty, wrong type, or externalRef is invalid.
164164
{{- end -}}
165165

166166
{{- /*
167-
library.externalRef.resolveServiceName resolves the Kubernetes service name for an ExternalName ref.
167+
library.externalRef.resolveServiceName resolves the Kubernetes service name for a Service ref.
168168
Context: dict with keys:
169169
- id: string (the externalRefs entry id)
170170
- externalRefs: list (the externalRefs registry)
171171
- root: the root context (for library.name)
172172
- context: string (optional, error context)
173173
For mode=create: returns fullnameOverride or <library.name>-<id>
174174
For mode=reference: returns name field
175-
Fails if ref is not kind ExternalName.
175+
Fails if ref is not kind Service.
176176
*/ -}}
177177
{{- define "library.externalRef.resolveServiceName" -}}
178178
{{- $id := .id -}}
179179
{{- $refs := .externalRefs | default list -}}
180180
{{- $root := .root -}}
181181
{{- $context := .context | default "" -}}
182182
{{- $resolved := include "library.externalRef" (dict "id" $id "externalRefs" $refs "context" $context) | fromJson -}}
183-
{{- if ne $resolved.kind "ExternalName" -}}
184-
{{- fail (printf "%sexternalServiceRef '%s' has kind '%s' — only 'ExternalName' refs can be resolved as service names" (ternary (printf "%s: " $context) "" (ne $context "")) $id $resolved.kind) -}}
183+
{{- if ne $resolved.kind "Service" -}}
184+
{{- fail (printf "%sexternalServiceRef '%s' has kind '%s' — only 'Service' refs can be resolved as service names" (ternary (printf "%s: " $context) "" (ne $context "")) $id $resolved.kind) -}}
185185
{{- end -}}
186186
{{- $mode := $resolved.mode | default "reference" -}}
187187
{{- if eq $mode "create" -}}

‎charts/common/templates/includes.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{{- end -}}
99

1010
{{- if .Values.includes.externalRefs }}
11+
{{- include "library.externalRefs.validate" (dict "externalRefs" (.Values.externalRefs | default list) "root" .) -}}
1112
{{- template "common.externalNameService" . }}
1213
{{- end -}}
1314

0 commit comments

Comments
 (0)