Gateway api support (#890)
* Gateway api support Signed-off-by: Kevin Fox <[email protected]> * Update readme Signed-off-by: Kevin Fox <[email protected]> * Fix gateway name. a gateway doesnt need to be named gateway Signed-off-by: Kevin Fox <[email protected]> * Fix naming issue Signed-off-by: Kevin Fox <[email protected]> * Incorperate feedback Signed-off-by: Kevin Fox <[email protected]> * Incorperate feedback Signed-off-by: Kevin Fox <[email protected]> --------- Signed-off-by: Kevin Fox <[email protected]>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Test-owned shared Gateway. Created outside the chart so its Envoy Gateway
|
||||
# data-plane Service (and ClusterIP) exists before the chart is installed,
|
||||
# letting the harness resolve the test hostnames to it in a single install pass.
|
||||
# name/namespace match the chart's global reference defaults
|
||||
# (global.spire.gatewayAPI.gateway.name=spire-gateway, namespace=release ns) so
|
||||
# the chart's ListenerSets and routes attach to it.
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: spire
|
||||
namespace: spire-server
|
||||
spec:
|
||||
gatewayClassName: eg
|
||||
allowedListeners:
|
||||
namespaces:
|
||||
from: All
|
||||
listeners:
|
||||
- name: base
|
||||
protocol: TLS
|
||||
port: 443
|
||||
tls:
|
||||
mode: Passthrough
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
@@ -0,0 +1,27 @@
|
||||
# EnvoyProxy forces the per-Gateway data-plane Service to type ClusterIP so the
|
||||
# integration harness can capture a stable ClusterIP and map the test hostnames
|
||||
# to it via hostAliases (kind has no LoadBalancer). The GatewayClass wires this
|
||||
# proxy config in via parametersRef.
|
||||
apiVersion: gateway.envoyproxy.io/v1alpha1
|
||||
kind: EnvoyProxy
|
||||
metadata:
|
||||
name: clusterip-proxy
|
||||
namespace: envoy-gateway-system
|
||||
spec:
|
||||
provider:
|
||||
type: Kubernetes
|
||||
kubernetes:
|
||||
envoyService:
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: eg
|
||||
spec:
|
||||
controllerName: gateway.envoyproxy.io/gatewayclass-controller
|
||||
parametersRef:
|
||||
group: gateway.envoyproxy.io
|
||||
kind: EnvoyProxy
|
||||
name: clusterip-proxy
|
||||
namespace: envoy-gateway-system
|
||||
@@ -12,6 +12,6 @@
|
||||
{
|
||||
"name": "envoy-gateway",
|
||||
"registry": "docker.io/envoyproxy/gateway-helm",
|
||||
"version": "v1.7.2"
|
||||
"version": "v1.8.2"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.fetchCA.gatewayAPI.enabled -}}
|
||||
{{- $fullName := printf "%s-fetchca" (include "spiffe-step-ssh.fullname" .) -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.fetchCA.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" .Release.Namespace
|
||||
"svcName" $fullName
|
||||
"port" .Values.fetchCA.service.port
|
||||
"labels" (include "spiffe-step-ssh.labels" .)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $fullName := include "spiffe-step-ssh.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" .Release.Namespace
|
||||
"svcName" $fullName
|
||||
"port" .Values.step.service.port
|
||||
"labels" (include "spiffe-step-ssh.labels" .)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
@@ -72,6 +72,21 @@ stepIngress:
|
||||
# - hosts:
|
||||
# - spiffe-step-ssh.example.org
|
||||
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose the step endpoint via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spiffe-step-ssh"
|
||||
## @param gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
## @skip step
|
||||
step:
|
||||
service:
|
||||
@@ -233,6 +248,21 @@ fetchCA:
|
||||
# - hosts:
|
||||
# - spiffe-step-ssh-fetchca.example.org
|
||||
|
||||
gatewayAPI:
|
||||
## @param fetchCA.gatewayAPI.enabled Flag to expose the fetchCA endpoint via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param fetchCA.gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spiffe-step-ssh-fetchca"
|
||||
## @param fetchCA.gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param fetchCA.gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param fetchCA.gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param fetchCA.gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
## @param fetchCA.autoscaling.enabled Enable autoscaling
|
||||
## @param fetchCA.autoscaling.minReplicas Minimum number of replicas to deploy
|
||||
## @param fetchCA.autoscaling.maxReplicas Maximum number of replicas to deploy
|
||||
|
||||
@@ -102,6 +102,14 @@ A Helm chart to install the SPIRE Identity Exchange.
|
||||
| `rest.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `rest.ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` |
|
||||
| `rest.ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `rest.gatewayAPI.enabled` | Flag to expose the REST endpoint via Gateway API | `false` |
|
||||
| `rest.gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `spire-identity-exchange-rest` |
|
||||
| `rest.gatewayAPI.tlsSecret` | Secret with the TLS cert for edge termination. Blank keeps passthrough. | `""` |
|
||||
| `rest.gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `rest.gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `rest.gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `rest.gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `rest.gatewayAPI.backendTLS.caCertificateRefs` | ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap. | `[]` |
|
||||
| `grpc.enabled` | Enable the grpc service | `false` |
|
||||
| `grpc.service.type` | Service type | `ClusterIP` |
|
||||
| `grpc.service.port` | port for the service | `443` |
|
||||
@@ -115,6 +123,14 @@ A Helm chart to install the SPIRE Identity Exchange.
|
||||
| `grpc.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `grpc.ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` |
|
||||
| `grpc.ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `grpc.gatewayAPI.enabled` | Flag to expose the gRPC endpoint via Gateway API | `false` |
|
||||
| `grpc.gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `spire-identity-exchange-grpc` |
|
||||
| `grpc.gatewayAPI.tlsSecret` | Secret with the TLS cert for edge termination. Blank keeps passthrough. | `""` |
|
||||
| `grpc.gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `grpc.gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `grpc.gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `grpc.gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `grpc.gatewayAPI.backendTLS.caCertificateRefs` | ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap. | `[]` |
|
||||
| `tools.kubectl.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` |
|
||||
| `tools.kubectl.image.repository` | The repository within the registry | `kubectl` |
|
||||
| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` |
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.grpc.gatewayAPI.enabled -}}
|
||||
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.grpc.gatewayAPI) -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.grpc.gatewayAPI
|
||||
"name" (printf "%s-grpc" (include "spire-identity-exchange.fullname" .))
|
||||
"namespace" (include "spire-identity-exchange.namespace" .)
|
||||
"svcName" (printf "%s-grpc" (include "spire-identity-exchange.fullname" .))
|
||||
"port" .Values.grpc.service.port
|
||||
"labels" (include "spire-identity-exchange.labels" .)
|
||||
"routeKind" $routeKind
|
||||
"backendTLS" (eq $routeKind "HTTPRoute")) }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.rest.gatewayAPI.enabled -}}
|
||||
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.rest.gatewayAPI) -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.rest.gatewayAPI
|
||||
"name" (printf "%s-rest" (include "spire-identity-exchange.fullname" .))
|
||||
"namespace" (include "spire-identity-exchange.namespace" .)
|
||||
"svcName" (printf "%s-rest" (include "spire-identity-exchange.fullname" .))
|
||||
"port" .Values.rest.service.port
|
||||
"labels" (include "spire-identity-exchange.labels" .)
|
||||
"routeKind" $routeKind
|
||||
"backendTLS" (eq $routeKind "HTTPRoute")) }}
|
||||
{{- end }}
|
||||
@@ -284,6 +284,31 @@ rest:
|
||||
# hosts:
|
||||
# - spire-identity-exchange-rest.example.org
|
||||
|
||||
## Gateway API exposure for the REST endpoint. Independent of rest.ingress. The
|
||||
## backend serves HTTPS, so a set tlsSecret => HTTPRoute + BackendTLSPolicy
|
||||
## (reencrypt); blank tlsSecret => TLSRoute (SNI passthrough).
|
||||
gatewayAPI:
|
||||
## @param rest.gatewayAPI.enabled Flag to expose the REST endpoint via Gateway API
|
||||
enabled: false
|
||||
## @param rest.gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spire-identity-exchange-rest"
|
||||
## @param rest.gatewayAPI.tlsSecret Secret with the TLS cert for edge termination. Blank keeps passthrough.
|
||||
tlsSecret: ""
|
||||
## @param rest.gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param rest.gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param rest.gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param rest.gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
# BackendTLSPolicy (reencrypt) is emitted automatically for the terminated
|
||||
# HTTPS backend when gatewayAPI.tlsSecret is set.
|
||||
backendTLS:
|
||||
## @param rest.gatewayAPI.backendTLS.caCertificateRefs [array] ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap.
|
||||
caCertificateRefs: []
|
||||
|
||||
grpc:
|
||||
## @param grpc.enabled Enable the grpc service
|
||||
enabled: false
|
||||
@@ -331,6 +356,31 @@ grpc:
|
||||
# hosts:
|
||||
# - spire-identiy-exchange-grpc.example.org
|
||||
|
||||
## Gateway API exposure for the gRPC endpoint. Independent of grpc.ingress. The
|
||||
## backend serves HTTPS, so a set tlsSecret => HTTPRoute + BackendTLSPolicy
|
||||
## (reencrypt); blank tlsSecret => TLSRoute (SNI passthrough).
|
||||
gatewayAPI:
|
||||
## @param grpc.gatewayAPI.enabled Flag to expose the gRPC endpoint via Gateway API
|
||||
enabled: false
|
||||
## @param grpc.gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spire-identity-exchange-grpc"
|
||||
## @param grpc.gatewayAPI.tlsSecret Secret with the TLS cert for edge termination. Blank keeps passthrough.
|
||||
tlsSecret: ""
|
||||
## @param grpc.gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param grpc.gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param grpc.gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param grpc.gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
# BackendTLSPolicy (reencrypt) is emitted automatically for the terminated
|
||||
# HTTPS backend when gatewayAPI.tlsSecret is set.
|
||||
backendTLS:
|
||||
## @param grpc.gatewayAPI.backendTLS.caCertificateRefs [array] ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap.
|
||||
caCertificateRefs: []
|
||||
|
||||
tools:
|
||||
kubectl:
|
||||
## @param tools.kubectl.image.registry The OCI registry to pull the image from
|
||||
|
||||
@@ -366,3 +366,242 @@ Anything lower has an incompatible API.
|
||||
{{- print "crt" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/* ---------------------------------------------------------------------------
|
||||
* Gateway API helpers
|
||||
*
|
||||
* Gateway API support is entirely independent of Ingress. It is driven by a
|
||||
* per-service `gatewayAPI:` values block (sibling of `ingress:`) with its own
|
||||
* `enabled` flag, so a service can expose both an Ingress and Gateway API
|
||||
* resources at the same time. The existing ingress helpers above are untouched.
|
||||
*
|
||||
* Only Standard-channel, v1 Gateway API resources are used
|
||||
* (gateway.networking.k8s.io/v1): Gateway, HTTPRoute, TLSRoute, ListenerSet,
|
||||
* BackendTLSPolicy. Requires Gateway API v1.5+ CRDs pre-installed.
|
||||
* --------------------------------------------------------------------------- */}}
|
||||
|
||||
{{/* Shared Gateway object name (global reference). Input: dict {global} */}}
|
||||
{{- define "spire-lib.gateway-name" -}}
|
||||
{{- dig "spire" "gatewayAPI" "gateway" "name" "spire" .global -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* Shared Gateway namespace. Input: dict {global, root}. Defaults to the release namespace. */}}
|
||||
{{- define "spire-lib.gateway-namespace" -}}
|
||||
{{- $ns := dig "spire" "gatewayAPI" "gateway" "namespace" "" .global -}}
|
||||
{{- if $ns -}}{{ $ns }}{{- else -}}{{ .root.Release.Namespace }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* Shared Gateway listener port (global reference, ListenerSets must match). Input: dict {global} */}}
|
||||
{{- define "spire-lib.gateway-port" -}}
|
||||
{{- dig "spire" "gatewayAPI" "gateway" "port" 443 .global -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* Resolve whether ListenerSet management is on for a service.
|
||||
* Input: dict {gatewayAPI, global}. Per-service listenerSet.enabled (null=inherit)
|
||||
* falls back to global.spire.gatewayAPI.manageListenerSets (default true).
|
||||
* Returns the string "true" or "false".
|
||||
*/}}
|
||||
{{- define "spire-lib.gateway-manage-listenersets" -}}
|
||||
{{- $ls := dig "listenerSet" "enabled" nil .gatewayAPI -}}
|
||||
{{- if ne $ls nil -}}
|
||||
{{- $ls -}}
|
||||
{{- else -}}
|
||||
{{- dig "spire" "gatewayAPI" "manageListenerSets" true .global -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* Default route kind from tlsSecret. Input: dict {gatewayAPI}. Empty tlsSecret => TLSRoute (passthrough). */}}
|
||||
{{- define "spire-lib.gateway-route-kind" -}}
|
||||
{{- if .gatewayAPI.tlsSecret -}}HTTPRoute{{- else -}}TLSRoute{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/* parentRefs list items for a route.
|
||||
* Input: dict {manageLS(bool), name, gatewayAPI, gwName, gwNS}
|
||||
* - manageLS on: attach to the service's ListenerSet (kind ListenerSet, sectionName=name)
|
||||
* - off + gatewayAPI.parentRefs set: use those verbatim
|
||||
* - off + no override: attach directly to the shared Gateway
|
||||
*/}}
|
||||
{{- define "spire-lib.gateway-parentref" -}}
|
||||
{{- if .manageLS }}
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: ListenerSet
|
||||
name: {{ .name | quote }}
|
||||
sectionName: {{ .name | quote }}
|
||||
{{- else if .gatewayAPI.parentRefs }}
|
||||
{{ toYaml .gatewayAPI.parentRefs }}
|
||||
{{- else }}
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: {{ .gwName | quote }}
|
||||
namespace: {{ .gwNS | quote }}
|
||||
{{- with .gatewayAPI.sectionName }}
|
||||
sectionName: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Emit Gateway API resources for one service: a Route, plus (optionally) a
|
||||
* ListenerSet and a BackendTLSPolicy. Direct analogue of spire-lib.ingress-spec.
|
||||
* Input dict:
|
||||
* root - chart root context (.)
|
||||
* gatewayAPI - the per-service gatewayAPI values block
|
||||
* name - base name for the emitted resources
|
||||
* namespace - namespace for the emitted resources
|
||||
* svcName - backend Service name
|
||||
* port - backend Service port (number)
|
||||
* labels - pre-rendered labels YAML (string)
|
||||
* routeKind - "TLSRoute" or "HTTPRoute"
|
||||
* backendTLS - bool; when true and HTTPRoute, emit a BackendTLSPolicy (reencrypt)
|
||||
* path - HTTPRoute path prefix (default "/")
|
||||
*/}}
|
||||
{{- define "spire-lib.gateway-routes" -}}
|
||||
{{- $g := .gatewayAPI -}}
|
||||
{{- $global := .root.Values.global -}}
|
||||
{{- $host := include "spire-lib.ingress-calculated-name" (dict "ingress" (dict "host" $g.host) "Values" .root.Values) | trim -}}
|
||||
{{- $gwName := include "spire-lib.gateway-name" (dict "global" $global) -}}
|
||||
{{- $gwNS := include "spire-lib.gateway-namespace" (dict "global" $global "root" .root) -}}
|
||||
{{- $port := include "spire-lib.gateway-port" (dict "global" $global) -}}
|
||||
{{- $manageLS := eq (include "spire-lib.gateway-manage-listenersets" (dict "gatewayAPI" $g "global" $global)) "true" -}}
|
||||
{{- $terminate := eq .routeKind "HTTPRoute" -}}
|
||||
{{- $path := default "/" .path -}}
|
||||
{{- $parentRefs := include "spire-lib.gateway-parentref" (dict "manageLS" $manageLS "name" .name "gatewayAPI" $g "gwName" $gwName "gwNS" $gwNS) -}}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: {{ .routeKind }}
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ .namespace }}
|
||||
labels:
|
||||
{{- .labels | nindent 4 }}
|
||||
{{- with $g.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
parentRefs:
|
||||
{{- $parentRefs | trim | nindent 4 }}
|
||||
hostnames:
|
||||
- {{ $host | quote }}
|
||||
rules:
|
||||
{{- if $terminate }}
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: {{ $path | quote }}
|
||||
backendRefs:
|
||||
- name: {{ .svcName | quote }}
|
||||
port: {{ .port }}
|
||||
{{- else }}
|
||||
- backendRefs:
|
||||
- name: {{ .svcName | quote }}
|
||||
port: {{ .port }}
|
||||
{{- end }}
|
||||
{{- if $manageLS }}
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: ListenerSet
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ .namespace }}
|
||||
labels:
|
||||
{{- .labels | nindent 4 }}
|
||||
spec:
|
||||
parentRef:
|
||||
group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: {{ $gwName | quote }}
|
||||
namespace: {{ $gwNS | quote }}
|
||||
listeners:
|
||||
- name: {{ .name }}
|
||||
hostname: {{ $host | quote }}
|
||||
port: {{ $port }}
|
||||
{{- if $terminate }}
|
||||
protocol: HTTPS
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- kind: Secret
|
||||
group: ""
|
||||
name: {{ $g.tlsSecret | quote }}
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
kinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
{{- else }}
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
kinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and $terminate .backendTLS }}
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ .namespace }}
|
||||
labels:
|
||||
{{- .labels | nindent 4 }}
|
||||
spec:
|
||||
targetRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: {{ .svcName | quote }}
|
||||
validation:
|
||||
hostname: {{ $host | quote }}
|
||||
caCertificateRefs:
|
||||
{{- if dig "backendTLS" "caCertificateRefs" (list) $g }}
|
||||
{{- toYaml $g.backendTLS.caCertificateRefs | nindent 6 }}
|
||||
{{- else }}
|
||||
- group: ""
|
||||
kind: ConfigMap
|
||||
name: {{ include "spire-lib.bundle-configmap" .root | trim | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/* The shared Gateway object. Rendered only by the umbrella chart.
|
||||
* Input: dict {root, gatewayObject} where gatewayObject is the umbrella-local
|
||||
* `gatewayAPI.gateway` values block. name/namespace/port come from the global
|
||||
* reference; className and listener policy are local.
|
||||
*/}}
|
||||
{{- define "spire-lib.gateway-resource" -}}
|
||||
{{- $global := .root.Values.global -}}
|
||||
{{- $obj := .gatewayObject -}}
|
||||
{{- $gwName := include "spire-lib.gateway-name" (dict "global" $global) -}}
|
||||
{{- $gwNS := include "spire-lib.gateway-namespace" (dict "global" $global "root" .root) -}}
|
||||
{{- $port := include "spire-lib.gateway-port" (dict "global" $global) -}}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: {{ $gwName }}
|
||||
namespace: {{ $gwNS }}
|
||||
{{- with $obj.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
gatewayClassName: {{ required "gatewayAPI.gateway.className is required to render the shared Gateway" $obj.className | quote }}
|
||||
allowedListeners:
|
||||
namespaces:
|
||||
from: {{ default "All" $obj.allowedListenersNamespaces }}
|
||||
listeners:
|
||||
- name: base
|
||||
protocol: TLS
|
||||
port: {{ $port }}
|
||||
tls:
|
||||
mode: Passthrough
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: {{ default "All" $obj.allowedRoutesNamespaces }}
|
||||
{{- with $obj.extraListeners }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -311,12 +311,27 @@ Now you can interact with the Spire agent socket from your own application. The
|
||||
| `global.spire.namespaces.server.labels` | Labels to apply to the Spire server Namespace. | `{}` |
|
||||
| `global.spire.strictMode` | Check values, such as trustDomain, are overridden with a suitable value for production. | `false` |
|
||||
| `global.spire.ingressControllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` |
|
||||
| `global.spire.gatewayAPI.manageListenerSets` | Default policy for whether services render a ListenerSet for their SNI listener. Each service may override via its gatewayAPI.listenerSet.enabled. | `true` |
|
||||
| `global.spire.gatewayAPI.gateway.name` | Name of the shared Gateway object that routes and ListenerSets attach to | `spire` |
|
||||
| `global.spire.gatewayAPI.gateway.namespace` | Namespace of the shared Gateway object. Defaults to the release namespace if blank. | `""` |
|
||||
| `global.spire.gatewayAPI.gateway.port` | Port the shared Gateway listens on. ListenerSet listeners must match this. | `443` |
|
||||
| `global.spire.tools.kubectl.tag` | Set to force the tag to use for all kubectl instances | `""` |
|
||||
| `global.installAndUpgradeHooks.enabled` | Enable Helm hooks to autofix common install/upgrade issues (should be disabled when using `helm template`) | `true` |
|
||||
| `global.installAndUpgradeHooks.resources` | Resource requests and limits for installAndUpgradeHooks | `{}` |
|
||||
| `global.deleteHooks.enabled` | Enable Helm hooks to autofix common delete issues (should be disabled when using `helm template`) | `true` |
|
||||
| `global.deleteHooks.resources` | Resource requests and limits for deleteHooks | `{}` |
|
||||
|
||||
### Gateway API parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `gatewayAPI.gateway.enabled` | Render the shared Gateway object | `false` |
|
||||
| `gatewayAPI.gateway.className` | gatewayClassName for the shared Gateway (e.g. "eg"). Required when enabled. | `""` |
|
||||
| `gatewayAPI.gateway.annotations` | Annotations for the Gateway object | `{}` |
|
||||
| `gatewayAPI.gateway.allowedListenersNamespaces` | From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector. | `All` |
|
||||
| `gatewayAPI.gateway.allowedRoutesNamespaces` | From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector. | `All` |
|
||||
| `gatewayAPI.gateway.extraListeners` | Additional listeners to add to the Gateway | `[]` |
|
||||
|
||||
### Spire server parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|
||||
@@ -122,6 +122,14 @@ A Helm chart to install the SPIFFE OIDC discovery provider.
|
||||
| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` |
|
||||
| `ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `gatewayAPI.enabled` | Flag to expose the OIDC discovery provider via Gateway API | `false` |
|
||||
| `gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `oidc-discovery` |
|
||||
| `gatewayAPI.tlsSecret` | Secret with the TLS cert for edge termination. Blank keeps passthrough when TLS is enabled. | `""` |
|
||||
| `gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `gatewayAPI.backendTLS.caCertificateRefs` | ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap. | `[]` |
|
||||
| `tests.hostAliases` | List of host aliases for testing | `[]` |
|
||||
| `tests.tls.enabled` | Flag for enabling tls for tests | `false` |
|
||||
| `tests.tls.customCA` | Custom CA value for tests | `""` |
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $tlsEnabled := eq (include "spiffe-oidc-discovery-provider.tls-enabled" .) "true" -}}
|
||||
{{- $hasSecret := ne (default "" .Values.gatewayAPI.tlsSecret) "" -}}
|
||||
{{- $port := $tlsEnabled | ternary .Values.service.ports.https .Values.service.ports.http -}}
|
||||
{{- $routeKind := (or (not $tlsEnabled) $hasSecret) | ternary "HTTPRoute" "TLSRoute" -}}
|
||||
{{- $backendTLS := and $tlsEnabled $hasSecret -}}
|
||||
{{- $fullName := include "spiffe-oidc-discovery-provider.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" (include "spiffe-oidc-discovery-provider.namespace" .)
|
||||
"svcName" $fullName
|
||||
"port" $port
|
||||
"labels" (include "spiffe-oidc-discovery-provider.labels" .)
|
||||
"routeKind" $routeKind
|
||||
"backendTLS" $backendTLS) }}
|
||||
{{- end }}
|
||||
+4
-1
@@ -9,6 +9,9 @@
|
||||
{{- if gt (len .Values.ingress.hosts) 0 }}
|
||||
{{- $host = (index .Values.ingress.hosts 0).host }}
|
||||
{{- end }}
|
||||
{{- if .Values.gatewayAPI.enabled }}
|
||||
{{- $host = include "spire-lib.ingress-calculated-name" (dict "Values" .Values "ingress" (dict "host" .Values.gatewayAPI.host)) | trim }}
|
||||
{{- end }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -40,7 +43,7 @@ spec:
|
||||
args: ['-s', '-f', '-k', '{{ $protocol }}://{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}.svc.{{ include "spire-lib.cluster-domain" . }}:{{ $port }}/.well-known/openid-configuration']
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 8 }}
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- if or .Values.ingress.enabled .Values.gatewayAPI.enabled }}
|
||||
- name: curl-ingress
|
||||
image: {{ template "spire-lib.image" (dict "image" .Values.tests.bash.image "global" .Values.global) }}
|
||||
command: ['curl']
|
||||
|
||||
@@ -345,6 +345,33 @@ ingress:
|
||||
# hosts:
|
||||
# - oidc-discovery.example.org
|
||||
|
||||
## Gateway API exposure for the OIDC discovery provider. Independent of `ingress`.
|
||||
## Route kind follows the provider's TLS setting: TLS disabled => HTTPRoute (edge,
|
||||
## plaintext backend); TLS enabled + tlsSecret => HTTPRoute + BackendTLSPolicy
|
||||
## (reencrypt to the HTTPS backend); TLS enabled + no tlsSecret => TLSRoute
|
||||
## (SNI passthrough).
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose the OIDC discovery provider via Gateway API
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "oidc-discovery"
|
||||
## @param gatewayAPI.tlsSecret Secret with the TLS cert for edge termination. Blank keeps passthrough when TLS is enabled.
|
||||
tlsSecret: ""
|
||||
## @param gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
# BackendTLSPolicy (reencrypt) is emitted automatically when this service
|
||||
# terminates TLS at the gateway while the backend serves HTTPS.
|
||||
backendTLS:
|
||||
## @param gatewayAPI.backendTLS.caCertificateRefs [array] ConfigMap refs holding the backend CA used to validate the re-encrypted connection. Defaults to the SPIRE bundle configmap.
|
||||
caCertificateRefs: []
|
||||
|
||||
tests:
|
||||
## @param tests.hostAliases [array] List of host aliases for testing
|
||||
hostAliases: []
|
||||
|
||||
@@ -72,3 +72,9 @@ A Helm chart to deploy spike keepers
|
||||
| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `ingress.tls` | Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `gatewayAPI.enabled` | Flag to expose spike-keeper via Gateway API (TLS passthrough) | `false` |
|
||||
| `gatewayAPI.host` | Host name for the routes. A `-<index>` suffix is added per replica. If no '.' in host, trustDomain is automatically appended. | `keeper` |
|
||||
| `gatewayAPI.annotations` | Annotations for the routes (and their ListenerSets) | `{}` |
|
||||
| `gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for each replica's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $root := . -}}
|
||||
{{- $g := .Values.gatewayAPI -}}
|
||||
{{- $fullName := include "spike-keeper.fullname" . -}}
|
||||
{{- $last := sub (.Values.replicas | int) 1 | int -}}
|
||||
{{- range (seq 0 $last | toString | split " ") }}
|
||||
{{- $i := . }}
|
||||
{{- $host := $g.host }}
|
||||
{{- if contains "." $host }}
|
||||
{{- $hostParts := regexSplit "[.]" $host 2 }}
|
||||
{{- $host = printf "%s-%s.%s" (index $hostParts 0) $i (index $hostParts 1) }}
|
||||
{{- else }}
|
||||
{{- $host = printf "%s-%s" $host $i }}
|
||||
{{- end }}
|
||||
{{- $gi := deepCopy $g }}
|
||||
{{- $_ := set $gi "host" $host }}
|
||||
---
|
||||
{{ include "spire-lib.gateway-routes" (dict
|
||||
"root" $root
|
||||
"gatewayAPI" $gi
|
||||
"name" (printf "%s-%s" $fullName $i)
|
||||
"namespace" (include "spike-keeper.namespace" $root)
|
||||
"svcName" (printf "%s-%s" $fullName $i)
|
||||
"port" $root.Values.service.port
|
||||
"labels" (include "spike-keeper.labels" $root)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -141,3 +141,21 @@ ingress:
|
||||
|
||||
## @param ingress.tls [array] Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars.
|
||||
tls: []
|
||||
|
||||
## Gateway API exposure for spike-keeper. One route + ListenerSet per replica
|
||||
## (host suffixed with the replica index, like the ingress). Independent of
|
||||
## `ingress`. Empty tlsSecret => TLSRoute (SNI passthrough).
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose spike-keeper via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the routes. A `-<index>` suffix is added per replica. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "keeper"
|
||||
## @param gatewayAPI.annotations [object] Annotations for the routes (and their ListenerSets)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for each replica's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
@@ -84,6 +84,12 @@ A Helm chart to deploy spike nexus
|
||||
| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `ingress.tls` | Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `gatewayAPI.enabled` | Flag to expose spike-nexus via Gateway API (TLS passthrough) | `false` |
|
||||
| `gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `nexus` |
|
||||
| `gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `persistence.type` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `pvc` |
|
||||
| `persistence.size` | What size volume to use for persistence | `1Gi` |
|
||||
| `persistence.accessMode` | What access mode to use for persistence. Valid options are ReadWriteOnce (recommended), ReadWriteOncePod, ReadWriteMany (not recommended) | `ReadWriteOnce` |
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $fullName := include "spike-nexus.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" (include "spike-nexus.namespace" .)
|
||||
"svcName" $fullName
|
||||
"port" .Values.service.port
|
||||
"labels" (include "spike-nexus.labels" .)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
@@ -182,6 +182,23 @@ ingress:
|
||||
# hosts:
|
||||
# - nexus.example.org
|
||||
|
||||
## Gateway API exposure for spike-nexus. Independent of `ingress`. Empty tlsSecret
|
||||
## => TLSRoute (SNI passthrough); set tlsSecret => HTTPRoute (edge terminate).
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose spike-nexus via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "nexus"
|
||||
## @param gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
## @param persistence.type What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only)
|
||||
## @param persistence.size What size volume to use for persistence
|
||||
## @param persistence.accessMode What access mode to use for persistence. Valid options are ReadWriteOnce (recommended), ReadWriteOncePod, ReadWriteMany (not recommended)
|
||||
|
||||
@@ -191,6 +191,12 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
|
||||
| `federation.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `federation.ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `federation.ingress.tls` | Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `federation.gatewayAPI.enabled` | Flag to expose the federation endpoint via Gateway API (TLS passthrough) | `false` |
|
||||
| `federation.gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `spire-server-federation` |
|
||||
| `federation.gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `federation.gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `federation.gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `federation.gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `caSubject.country` | Country for Spire server CA | `ARPA` |
|
||||
| `caSubject.organization` | Organization for Spire server CA | `Example` |
|
||||
| `caSubject.commonName` | Common Name for Spire server CA | `example.org` |
|
||||
@@ -426,6 +432,12 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
|
||||
| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `ingress.tls` | Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `gatewayAPI.enabled` | Flag to expose spire-server via Gateway API (TLS passthrough) | `false` |
|
||||
| `gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `spire-server` |
|
||||
| `gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `extraEnv` | Extra environment variables to add to the spire server | `[]` |
|
||||
| `extraVolumes` | Extra volumes to be mounted | `[]` |
|
||||
| `extraVolumeMounts` | Extra volume mounts | `[]` |
|
||||
@@ -548,6 +560,13 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
|
||||
| `tornjak.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `tornjak.ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `tornjak.ingress.tls` | Secrets containing TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `tornjak.gatewayAPI.enabled` | Flag to expose the Tornjak backend via Gateway API | `false` |
|
||||
| `tornjak.gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `tornjak-backend` |
|
||||
| `tornjak.gatewayAPI.tlsSecret` | Secret with the TLS cert for edge termination (used when connectionType is http). Blank keeps passthrough. | `""` |
|
||||
| `tornjak.gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `tornjak.gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `tornjak.gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `tornjak.gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `tornjak.startupProbe.failureThreshold` | Failure threshold count | `3` |
|
||||
| `tornjak.startupProbe.initialDelaySeconds` | Initial delay seconds | `5` |
|
||||
| `tornjak.startupProbe.periodSeconds` | Period seconds | `10` |
|
||||
|
||||
@@ -364,9 +364,14 @@ The code below determines what connection type should be used.
|
||||
|
||||
{{- define "spire-server.test.federation-ingress-args" }}
|
||||
{{- $args := list }}
|
||||
{{- $host := include "spire-lib.ingress-calculated-name" (dict "Values" .Values "ingress" .Values.federation.ingress) }}
|
||||
{{- if gt (len .Values.federation.ingress.tls) 0 }}
|
||||
{{- $host = index (index (index .Values.federation.ingress.tls 0) "hosts") 0 }}
|
||||
{{- $host := "" }}
|
||||
{{- if .host }}
|
||||
{{- $host = .host }}
|
||||
{{- else }}
|
||||
{{- $host = include "spire-lib.ingress-calculated-name" (dict "Values" .Values "ingress" .Values.federation.ingress) }}
|
||||
{{- if gt (len .Values.federation.ingress.tls) 0 }}
|
||||
{{- $host = index (index (index .Values.federation.ingress.tls 0) "hosts") 0 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if dig "tests" "tls" "enabled" false .Values }}
|
||||
{{- if ne (len (dig "tests" "tls" "customCA" "" .Values)) 0 }}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.federation.enabled -}}
|
||||
{{- if .Values.federation.gatewayAPI.enabled -}}
|
||||
{{- $fullName := include "spire-server.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.federation.gatewayAPI
|
||||
"name" (printf "%s-federation" $fullName)
|
||||
"namespace" (include "spire-server.namespace" .)
|
||||
"svcName" $fullName
|
||||
"port" .Values.federation.bundleEndpoint.port
|
||||
"labels" (include "spire-server.labels" .)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $fullName := include "spire-server.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" (include "spire-server.namespace" .)
|
||||
"svcName" $fullName
|
||||
"port" .Values.service.port
|
||||
"labels" (include "spire-server.labels" .)
|
||||
"routeKind" "TLSRoute") }}
|
||||
{{- end }}
|
||||
@@ -56,6 +56,21 @@ spec:
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.federation.gatewayAPI.enabled }}
|
||||
{{- $gwHost := include "spire-lib.ingress-calculated-name" (dict "Values" .Values "ingress" (dict "host" .Values.federation.gatewayAPI.host)) | trim }}
|
||||
- name: federation-gateway
|
||||
image: {{ template "spire-lib.image" (dict "image" .Values.tests.bash.image "global" .Values.global) }}
|
||||
command: ['curl']
|
||||
args:
|
||||
{{ include "spire-server.test.federation-ingress-args" (dict "Values" $values "host" $gwHost) | nindent 8 }}
|
||||
{{- if ne (len (dig "tests" "tls" "customCA" "" $values)) 0 }}
|
||||
volumeMounts:
|
||||
- name: custom-ca
|
||||
mountPath: /ca
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "spire-lib.securitycontext" . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if ne (len (dig "tests" "hostAliases" "" $values)) 0 }}
|
||||
hostAliases:
|
||||
{{- toYaml .Values.tests.hostAliases | nindent 4 }}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if .Values.tornjak.gatewayAPI.enabled -}}
|
||||
{{- $isHttp := eq (include "spire-tornjak.connectionType" .) "http" -}}
|
||||
{{- $routeKind := $isHttp | ternary "HTTPRoute" "TLSRoute" -}}
|
||||
{{- $port := $isHttp | ternary .Values.tornjak.service.ports.http .Values.tornjak.service.ports.https -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.tornjak.gatewayAPI
|
||||
"name" (include "spire-tornjak.fullname" .)
|
||||
"namespace" (include "spire-server.namespace" .)
|
||||
"svcName" (include "spire-tornjak.servicename" .)
|
||||
"port" $port
|
||||
"labels" (include "spire-server.labels" .)
|
||||
"routeKind" $routeKind
|
||||
"backendTLS" false) }}
|
||||
{{- end }}
|
||||
@@ -343,6 +343,21 @@ federation:
|
||||
# If Profile Type == https_web:
|
||||
# secretName: spire-server-federation-tls
|
||||
|
||||
gatewayAPI:
|
||||
## @param federation.gatewayAPI.enabled Flag to expose the federation endpoint via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param federation.gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spire-server-federation"
|
||||
## @param federation.gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param federation.gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param federation.gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param federation.gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
caSubject:
|
||||
## @param caSubject.country Country for Spire server CA
|
||||
country: ARPA
|
||||
@@ -1056,6 +1071,21 @@ ingress:
|
||||
# hosts:
|
||||
# - spire-server.example.org
|
||||
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose spire-server via Gateway API (TLS passthrough)
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "spire-server"
|
||||
## @param gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
## @param extraEnv [array] Extra environment variables to add to the spire server
|
||||
extraEnv: []
|
||||
|
||||
@@ -1358,6 +1388,25 @@ tornjak:
|
||||
# hosts:
|
||||
# - tornjak-backend.example.org
|
||||
|
||||
## Gateway API exposure for the Tornjak backend. Route kind follows the tornjak
|
||||
## connectionType: non-http => TLSRoute (passthrough), http => HTTPRoute (edge).
|
||||
gatewayAPI:
|
||||
## @param tornjak.gatewayAPI.enabled Flag to expose the Tornjak backend via Gateway API
|
||||
enabled: false
|
||||
## @param tornjak.gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "tornjak-backend"
|
||||
## @param tornjak.gatewayAPI.tlsSecret Secret with the TLS cert for edge termination (used when connectionType is http). Blank keeps passthrough.
|
||||
tlsSecret: ""
|
||||
## @param tornjak.gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param tornjak.gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param tornjak.gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param tornjak.gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
## @param tornjak.startupProbe.failureThreshold Failure threshold count
|
||||
## @param tornjak.startupProbe.initialDelaySeconds Initial delay seconds
|
||||
## @param tornjak.startupProbe.periodSeconds Period seconds
|
||||
|
||||
@@ -98,6 +98,13 @@ port forwarding. See the chart NOTES output for more details.
|
||||
| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` |
|
||||
| `ingress.hosts` | Host paths for ingress object. If empty, rules will be built based on the host var. | `[]` |
|
||||
| `ingress.tls` | Secrets containing TLS certs to enable https on ingress. If empty, rules will be built based on the host and tlsSecret vars. | `[]` |
|
||||
| `gatewayAPI.enabled` | Flag to expose the Tornjak frontend via Gateway API | `false` |
|
||||
| `gatewayAPI.host` | Host name for the route. If no '.' in host, trustDomain is automatically appended. | `tornjak-frontend` |
|
||||
| `gatewayAPI.tlsSecret` | Secret with the TLS cert for edge termination | `""` |
|
||||
| `gatewayAPI.annotations` | Annotations for the route (and its ListenerSet) | `{}` |
|
||||
| `gatewayAPI.listenerSet.enabled` | Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets. | `nil` |
|
||||
| `gatewayAPI.parentRefs` | parentRefs used when ListenerSet management is disabled (direct attach) | `[]` |
|
||||
| `gatewayAPI.sectionName` | Listener sectionName override when attaching directly to a Gateway | `""` |
|
||||
| `tests.bash.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
|
||||
| `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` |
|
||||
| `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` |
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.gatewayAPI.enabled -}}
|
||||
{{- $fullName := include "tornjak-frontend.fullname" . -}}
|
||||
{{- include "spire-lib.gateway-routes" (dict
|
||||
"root" .
|
||||
"gatewayAPI" .Values.gatewayAPI
|
||||
"name" $fullName
|
||||
"namespace" (include "tornjak-frontend.namespace" .)
|
||||
"svcName" $fullName
|
||||
"port" .Values.service.port
|
||||
"labels" (include "tornjak-frontend.labels" .)
|
||||
"routeKind" "HTTPRoute"
|
||||
"backendTLS" false) }}
|
||||
{{- end }}
|
||||
@@ -151,6 +151,26 @@ ingress:
|
||||
# hosts:
|
||||
# - tornjak-frontend.example.org
|
||||
|
||||
## Gateway API exposure for the Tornjak frontend UI. Independent of `ingress`.
|
||||
## The frontend serves plaintext HTTP, so this is always an HTTPRoute with edge
|
||||
## TLS termination at the Gateway; set tlsSecret to supply the listener cert.
|
||||
gatewayAPI:
|
||||
## @param gatewayAPI.enabled Flag to expose the Tornjak frontend via Gateway API
|
||||
enabled: false
|
||||
## @param gatewayAPI.host Host name for the route. If no '.' in host, trustDomain is automatically appended.
|
||||
host: "tornjak-frontend"
|
||||
## @param gatewayAPI.tlsSecret Secret with the TLS cert for edge termination
|
||||
tlsSecret: ""
|
||||
## @param gatewayAPI.annotations [object] Annotations for the route (and its ListenerSet)
|
||||
annotations: {}
|
||||
listenerSet:
|
||||
## @param gatewayAPI.listenerSet.enabled Manage a ListenerSet for this service's SNI listener. Null inherits global.spire.gatewayAPI.manageListenerSets.
|
||||
enabled: null
|
||||
## @param gatewayAPI.parentRefs [array] parentRefs used when ListenerSet management is disabled (direct attach)
|
||||
parentRefs: []
|
||||
## @param gatewayAPI.sectionName Listener sectionName override when attaching directly to a Gateway
|
||||
sectionName: ""
|
||||
|
||||
tests:
|
||||
bash:
|
||||
## @param tests.bash.image.registry The OCI registry to pull the image from
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{{- if .Values.gatewayAPI.gateway.enabled }}
|
||||
{{- include "spire-lib.gateway-resource" (dict "root" . "gatewayObject" .Values.gatewayAPI.gateway) }}
|
||||
{{- end }}
|
||||
@@ -84,6 +84,22 @@ global:
|
||||
## @param global.spire.ingressControllerType Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""].
|
||||
ingressControllerType: ""
|
||||
|
||||
## Gateway API reference settings shared across charts. Only the values needed
|
||||
## by other charts to attach their routes/ListenerSets to the shared Gateway
|
||||
## live here; the Gateway object itself is configured under the top-level
|
||||
## `gatewayAPI.gateway` block of this (umbrella) chart. Gateway API support is
|
||||
## independent of ingress and can be enabled alongside it.
|
||||
gatewayAPI:
|
||||
## @param global.spire.gatewayAPI.manageListenerSets Default policy for whether services render a ListenerSet for their SNI listener. Each service may override via its gatewayAPI.listenerSet.enabled.
|
||||
manageListenerSets: true
|
||||
gateway:
|
||||
## @param global.spire.gatewayAPI.gateway.name Name of the shared Gateway object that routes and ListenerSets attach to
|
||||
name: spire
|
||||
## @param global.spire.gatewayAPI.gateway.namespace Namespace of the shared Gateway object. Defaults to the release namespace if blank.
|
||||
namespace: ""
|
||||
## @param global.spire.gatewayAPI.gateway.port Port the shared Gateway listens on. ListenerSet listeners must match this.
|
||||
port: 443
|
||||
|
||||
tools:
|
||||
kubectl:
|
||||
## @param global.spire.tools.kubectl.tag Set to force the tag to use for all kubectl instances
|
||||
@@ -129,6 +145,27 @@ global:
|
||||
# namespace: "kube-prometheus-system"
|
||||
# labels: {}
|
||||
|
||||
## @section Gateway API parameters
|
||||
## Configuration for the optional shared Gateway object managed by this umbrella
|
||||
## chart. The Gateway is rendered here (rather than in a subchart) so it exists
|
||||
## even when spire-server is disabled. name/namespace/port come from
|
||||
## global.spire.gatewayAPI.gateway; className and listener policy are local.
|
||||
##
|
||||
gatewayAPI:
|
||||
gateway:
|
||||
## @param gatewayAPI.gateway.enabled Render the shared Gateway object
|
||||
enabled: false
|
||||
## @param gatewayAPI.gateway.className gatewayClassName for the shared Gateway (e.g. "eg"). Required when enabled.
|
||||
className: ""
|
||||
## @param gatewayAPI.gateway.annotations [object] Annotations for the Gateway object
|
||||
annotations: {}
|
||||
## @param gatewayAPI.gateway.allowedListenersNamespaces From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector.
|
||||
allowedListenersNamespaces: All
|
||||
## @param gatewayAPI.gateway.allowedRoutesNamespaces From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector.
|
||||
allowedRoutesNamespaces: All
|
||||
## @param gatewayAPI.gateway.extraListeners [array] Additional listeners to add to the Gateway
|
||||
extraListeners: []
|
||||
|
||||
## subcharts
|
||||
|
||||
## @section Spire server parameters
|
||||
|
||||
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -xe
|
||||
|
||||
# Gateway API integration test. Mirrors tests/integration/production but exposes
|
||||
# services through the Kubernetes Gateway API (Envoy Gateway) instead of
|
||||
# ingress-nginx:
|
||||
# - spire-server and the federation endpoint use TLS passthrough (TLSRoute)
|
||||
# - the OIDC discovery provider uses HTTPS termination at the edge (HTTPRoute)
|
||||
# Both share port 443 and are disambiguated by SNI via per-service ListenerSets.
|
||||
#
|
||||
# The shared Gateway object is created by this harness (see gateway-eg.yaml)
|
||||
# rather than by the chart, so its data-plane Service ClusterIP is known before
|
||||
# the chart is installed and the whole thing installs in a single pass.
|
||||
#
|
||||
# The released chart has no Gateway API support, so the production `-u`
|
||||
# upgrade-from-release path is intentionally omitted here.
|
||||
|
||||
SCRIPT="$(readlink -f "$0")"
|
||||
SCRIPTPATH="$(dirname "${SCRIPT}")"
|
||||
TESTDIR="${SCRIPTPATH}/../../../.github/tests"
|
||||
DEPS="${TESTDIR}/dependencies"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "${SCRIPTPATH}/../../../.github/scripts/parse-versions.sh"
|
||||
# shellcheck source=/dev/null
|
||||
source "${TESTDIR}/common.sh"
|
||||
|
||||
"${SCRIPTPATH}/../../../.github/scripts/prepare-local-chart-deps.sh"
|
||||
|
||||
CLEANUP=1
|
||||
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
-c)
|
||||
CLEANUP=0
|
||||
shift # past argument=value
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
teardown() {
|
||||
print_helm_releases
|
||||
print_spire_workload_status spire-server spire-system
|
||||
|
||||
if [[ "$1" -ne 0 ]]; then
|
||||
get_namespace_details spire-server spire-system
|
||||
fi
|
||||
|
||||
if [ "${CLEANUP}" -eq 1 ]; then
|
||||
helm uninstall --namespace spire-server spire 2>/dev/null || true
|
||||
kubectl delete ns spire-server 2>/dev/null || true
|
||||
kubectl delete ns spire-system 2>/dev/null || true
|
||||
helm uninstall --namespace cert-manager cert-manager 2>/dev/null || true
|
||||
kubectl delete ns cert-manager 2>/dev/null || true
|
||||
kubectl delete -f "${DEPS}/gateway-eg.yaml" 2>/dev/null || true
|
||||
kubectl delete -f "${DEPS}/gatewayclass-eg.yaml" 2>/dev/null || true
|
||||
helm uninstall --namespace envoy-gateway-system eg 2>/dev/null || true
|
||||
kubectl delete ns envoy-gateway-system 2>/dev/null || true
|
||||
# Leave the Gateway API CRDs installed; removing them is unnecessary and
|
||||
# would disrupt anything else on a shared cluster.
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'EC=$? && trap - SIGTERM && teardown $EC' SIGINT SIGTERM EXIT
|
||||
|
||||
kubectl create namespace spire-system 2>/dev/null || true
|
||||
kubectl label namespace spire-system pod-security.kubernetes.io/enforce=privileged || true
|
||||
kubectl create namespace spire-server 2>/dev/null || true
|
||||
kubectl label namespace spire-server pod-security.kubernetes.io/enforce=restricted || true
|
||||
|
||||
helm upgrade --install --create-namespace cert-manager cert-manager \
|
||||
--version "$VERSION_CERT_MANAGER" --repo "$HELM_REPO_CERT_MANAGER" \
|
||||
--namespace cert-manager \
|
||||
--set installCRDs=true \
|
||||
--wait
|
||||
|
||||
kubectl apply -f "${DEPS}/testcert.yaml" -n spire-server
|
||||
|
||||
# Install the Envoy Gateway control plane. Its gateway-crds-helm dependency also
|
||||
# installs the Gateway API CRDs (bundled v1.5.1), including the standard v1
|
||||
# ListenerSet, TLSRoute and BackendTLSPolicy we rely on — so no separate CRD
|
||||
# apply is needed. Pin the standard channel explicitly.
|
||||
helm upgrade --install --create-namespace eg "$HELM_REGISTRY_ENVOY_GATEWAY" \
|
||||
--version "$VERSION_ENVOY_GATEWAY" \
|
||||
--namespace envoy-gateway-system \
|
||||
--set gateway-crds-helm.crds.gatewayAPI.channel=standard \
|
||||
--wait
|
||||
|
||||
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
|
||||
|
||||
# GatewayClass (eg) + an EnvoyProxy that forces the data-plane Service to
|
||||
# ClusterIP so the hostAliases DNS trick works on kind, then the shared Gateway
|
||||
# object itself. Creating the Gateway here (not in the chart) makes Envoy Gateway
|
||||
# provision the data-plane Service up front so we can capture its ClusterIP.
|
||||
kubectl apply -f "${DEPS}/gatewayclass-eg.yaml"
|
||||
kubectl apply -f "${DEPS}/gateway-eg.yaml"
|
||||
|
||||
# Capture the Envoy Gateway data-plane Service ClusterIP. Envoy Gateway labels
|
||||
# the Service with the owning Gateway (spire in spire-server).
|
||||
echo "Waiting for the Envoy Gateway data-plane Service to be provisioned..."
|
||||
ip=""
|
||||
for _ in $(seq 1 60); do
|
||||
ip=$(kubectl -n envoy-gateway-system get svc \
|
||||
-l "gateway.envoyproxy.io/owning-gateway-namespace=spire-server,gateway.envoyproxy.io/owning-gateway-name=spire" \
|
||||
-o jsonpath='{.items[0].spec.clusterIP}' 2>/dev/null || true)
|
||||
if [[ -n "$ip" && "$ip" != "None" ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
if [[ -z "$ip" || "$ip" == "None" ]]; then
|
||||
echo "Failed to obtain Envoy Gateway data-plane Service ClusterIP"
|
||||
exit 1
|
||||
fi
|
||||
echo "$ip" spire-server.production.other oidc-discovery.production.other spire-server-federation.production.other
|
||||
|
||||
cat > /tmp/dummydns <<EOF
|
||||
spiffe-oidc-discovery-provider:
|
||||
tests:
|
||||
hostAliases:
|
||||
- ip: "$ip"
|
||||
hostnames:
|
||||
- "oidc-discovery.production.other"
|
||||
spire-agent:
|
||||
hostAliases:
|
||||
- ip: "$ip"
|
||||
hostnames:
|
||||
- "spire-server.production.other"
|
||||
spire-server:
|
||||
tests:
|
||||
hostAliases:
|
||||
- ip: "$ip"
|
||||
hostnames:
|
||||
- "spire-server-federation.production.other"
|
||||
EOF
|
||||
|
||||
# The Gateway (and its data-plane Service) already exist, so the hostnames
|
||||
# resolve immediately and the chart installs in a single pass.
|
||||
helm upgrade --install --create-namespace spire charts/spire \
|
||||
--namespace spire-server \
|
||||
--values "${COMMON_TEST_YOUR_VALUES}" \
|
||||
--values "${SCRIPTPATH}/values-expose-spire-server-gateway-api.yaml" \
|
||||
--values "${SCRIPTPATH}/values-expose-spiffe-oidc-discovery-provider-gateway-api.yaml" \
|
||||
--values "${SCRIPTPATH}/values-expose-federation-https-web-gateway-api.yaml" \
|
||||
--values /tmp/dummydns \
|
||||
--set spiffe-oidc-discovery-provider.tests.tls.customCA=tls-cert,spire-server.tests.tls.customCA=tls-cert \
|
||||
--set spire-agent.server.address=spire-server.production.other,spire-agent.server.port=443 \
|
||||
--set spire-server.federation.tls.externalSecret.secretName=tls-cert \
|
||||
--wait
|
||||
|
||||
helm test --namespace spire-server spire
|
||||
|
||||
if helm get manifest -n spire-server spire | grep -i example; then
|
||||
echo Global settings did not work. Please fix.
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,9 @@
|
||||
# Alternate federation profile (https_spiffe): the federation endpoint is
|
||||
# exposed via Gateway API with TLS passthrough of the pod's SPIFFE-authenticated
|
||||
# endpoint. Provided for a targeted passthrough-federation test; NOT referenced
|
||||
# by run-tests.sh by default (mirrors the production https_spiffe variant).
|
||||
spire-server:
|
||||
federation:
|
||||
enabled: true
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
@@ -0,0 +1,18 @@
|
||||
# Expose the federation bundle endpoint via Gateway API. The federation pod
|
||||
# serves a web-PKI cert (externalSecret), so the Gateway uses TLS passthrough
|
||||
# (empty gatewayAPI.tlsSecret => TLSRoute + a passthrough SNI listener) and the
|
||||
# client validates the pod's cert directly. This is the https_web profile.
|
||||
spire-server:
|
||||
tests:
|
||||
tls:
|
||||
enabled: true
|
||||
federation:
|
||||
enabled: true
|
||||
tls:
|
||||
spire:
|
||||
enabled: false
|
||||
externalSecret:
|
||||
enabled: true
|
||||
secretName: spire-server-federation-tls
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
# Expose the OIDC discovery provider via Gateway API with HTTPS termination at
|
||||
# the edge. The provider's SPIRE TLS is disabled so it serves plaintext behind
|
||||
# the Gateway; the Gateway terminates TLS with tls-cert (set gatewayAPI.tlsSecret)
|
||||
# => HTTPRoute + a terminating SNI listener. The helm test curls the discovery
|
||||
# document over HTTPS and validates the gateway cert against the tls-cert CA.
|
||||
spiffe-oidc-discovery-provider:
|
||||
tls:
|
||||
spire:
|
||||
enabled: false
|
||||
tests:
|
||||
tls:
|
||||
enabled: true
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
tlsSecret: tls-cert
|
||||
@@ -0,0 +1,7 @@
|
||||
# Expose spire-server via Gateway API using TLS passthrough (mTLS terminated at
|
||||
# the pod). Empty gatewayAPI.tlsSecret => TLSRoute + a passthrough SNI listener.
|
||||
# The shared Gateway object is created by the test harness (not the chart), so
|
||||
# gatewayAPI.gateway.enabled is left at its default (false).
|
||||
spire-server:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
Reference in New Issue
Block a user