From bf409f2e2067602e58d8a3f6266a60d91e1432b8 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Thu, 29 May 2025 18:27:39 -0500 Subject: [PATCH 01/13] feat: implement Gateway API with HTTPRoute for ACME challenge and web traffic routing --- .../istio-certs/templates/access_control.yaml | 4 + charts/istio-certs/templates/configmap.yaml | 11 +- .../istio-ingress/templates/certificate.yaml | 7 + charts/istio-ingress/templates/gateways.yaml | 129 +++++++++++------- .../istio-ingress/templates/httproutes.yaml | 61 +++++++++ .../templates/referencegrants.yaml | 34 +++++ charts/istio-ingress/values.yaml | 6 +- .../applications/web-site/httproute-web.yaml | 22 +++ software/applications/web-site/httproute.yaml | 23 ++++ software/applications/web-site/ingress.yaml | 47 ++++--- 10 files changed, 269 insertions(+), 75 deletions(-) create mode 100644 charts/istio-ingress/templates/certificate.yaml create mode 100644 charts/istio-ingress/templates/httproutes.yaml create mode 100644 charts/istio-ingress/templates/referencegrants.yaml create mode 100644 software/applications/web-site/httproute-web.yaml create mode 100644 software/applications/web-site/httproute.yaml diff --git a/charts/istio-certs/templates/access_control.yaml b/charts/istio-certs/templates/access_control.yaml index 0a8b0d69..07e474c6 100644 --- a/charts/istio-certs/templates/access_control.yaml +++ b/charts/istio-certs/templates/access_control.yaml @@ -16,6 +16,10 @@ rules: - apiGroups: ["cert-manager.io"] resources: ["certificates"] verbs: ["get", "create", "update", "patch", "apply"] + # Gateway API permissions for Gateway and HTTPRoute management + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gateways", "httproutes"] + verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/charts/istio-certs/templates/configmap.yaml b/charts/istio-certs/templates/configmap.yaml index 20615f0d..b7739b9d 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -58,7 +58,6 @@ data: } main "$@" - istio-certificate.yaml: | apiVersion: cert-manager.io/v1 kind: Certificate @@ -71,10 +70,18 @@ data: renewBefore: 360h # 15 days subject: organizations: - - Example Organization + - OSDU Developer commonName: __FQDN__ dnsNames: - __FQDN__ issuerRef: name: letsencrypt-staging kind: ClusterIssuer + # Use HTTP-01 challenge which will work with Gateway API HTTPRoute + # The ACME challenge solver will create temporary pods that need routing + privateKey: + algorithm: RSA + size: 2048 + usages: + - digital signature + - key encipherment diff --git a/charts/istio-ingress/templates/certificate.yaml b/charts/istio-ingress/templates/certificate.yaml new file mode 100644 index 00000000..ee9f7c3e --- /dev/null +++ b/charts/istio-ingress/templates/certificate.yaml @@ -0,0 +1,7 @@ +# Certificate will be created by the istio-certs chart after DNS configuration +# This ensures proper FQDN is available for Let's Encrypt validation +# The istio-certs Job handles: +# 1. Waiting for LoadBalancer IP +# 2. Setting DNS label annotation +# 3. Creating Certificate with correct FQDN +# 4. HTTP-01 challenge routing via Gateway API diff --git a/charts/istio-ingress/templates/gateways.yaml b/charts/istio-ingress/templates/gateways.yaml index 7aa023e6..2dab2f32 100644 --- a/charts/istio-ingress/templates/gateways.yaml +++ b/charts/istio-ingress/templates/gateways.yaml @@ -1,60 +1,93 @@ {{- define "gateway" -}} -apiVersion: networking.istio.io/v1alpha3 +apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: {{ .name | default (printf "%s-gateway" .gatewayType) }} namespace: istio-system spec: - selector: - {{- .selector | default (dict "istio" (printf "ingress-%s" .gatewayType)) | toYaml | nindent 4 }} - servers: - - port: - name: http2 - number: 80 - protocol: HTTP2 - hosts: - {{- if .hosts }} - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - {{- else }} - - "*" - {{- end }} - - port: - name: https - number: 443 - protocol: HTTPS - hosts: - {{- if .hosts }} - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - {{- else }} - - "*" - {{- end }} + gatewayClassName: istio + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: https + protocol: HTTPS + port: 443 + hostname: {{ printf "%s.%s.cloudapp.azure.com" .azure.dnsName .azure.region | quote }} tls: - {{- if .requireSSL }} - httpsRedirect: true # sends 301 redirect for http requests - {{- end }} - {{- with .tls }} - {{- toYaml . | nindent 8 }} - {{- end }} + mode: Terminate + certificateRefs: + - kind: Secret + name: {{ .tls.credentialName | quote }} + namespace: istio-system + allowedRoutes: + namespaces: + from: All {{- end }} -{{- if .Values.ingress }} - {{- if hasKey .Values.ingress "internalGateway" }} - {{- if .Values.ingress.internalGateway.enabled }} +{{- if .Values.ingress.externalGateway.enabled }} --- -{{- $internalGateway := merge (dict "gatewayType" "internal" "requireSSL" .Values.ingress.internalGateway.requireSSL) .Values.ingress.internalGateway -}} -{{ include "gateway" $internalGateway }} - {{- end }} - {{- end }} +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: external-gateway + namespace: istio-system + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + gatewayClassName: istio + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + name: {{ .Values.ingress.externalGateway.tls.credentialName | quote }} + namespace: istio-system + allowedRoutes: + namespaces: + from: All +{{- end }} - {{- if hasKey .Values.ingress "externalGateway" }} - {{- if .Values.ingress.externalGateway.enabled }} +{{- if .Values.ingress.internalGateway.enabled }} --- -{{- $externalGateway := merge (dict "gatewayType" "external" "requireSSL" .Values.ingress.externalGateway.requireSSL) .Values.ingress.externalGateway -}} -{{ include "gateway" $externalGateway }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: internal-gateway + namespace: istio-system + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + gatewayClassName: istio + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + name: {{ .Values.ingress.internalGateway.tls.credentialName | quote }} + namespace: istio-system + allowedRoutes: + namespaces: + from: All +{{- end }} diff --git a/charts/istio-ingress/templates/httproutes.yaml b/charts/istio-ingress/templates/httproutes.yaml new file mode 100644 index 00000000..ca15efd5 --- /dev/null +++ b/charts/istio-ingress/templates/httproutes.yaml @@ -0,0 +1,61 @@ +# HTTPRoute for ACME challenge path routing and web traffic +{{- if .Values.ingress.externalGateway.enabled }} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: acme-challenge-route + namespace: istio-system + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + parentRefs: + - name: external-gateway + namespace: istio-system + sectionName: http + - name: external-gateway + namespace: istio-system + sectionName: https + hostnames: + - "*.cloudapp.azure.com" + rules: + # ACME challenge route - highest priority + - matches: + - path: + type: PathPrefix + value: "/.well-known/acme-challenge/" + backendRefs: + - name: cm-acme-http-solver + port: 8089 + namespace: cert-manager +{{- end }} + +{{- if .Values.ingress.internalGateway.enabled }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: internal-acme-challenge-route + namespace: istio-system + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + parentRefs: + - name: internal-gateway + namespace: istio-system + sectionName: http + - name: internal-gateway + namespace: istio-system + sectionName: https + hostnames: + - "*.cloudapp.azure.com" + rules: + # ACME challenge route - highest priority + - matches: + - path: + type: PathPrefix + value: "/.well-known/acme-challenge/" + backendRefs: + - name: cm-acme-http-solver + port: 8089 + namespace: cert-manager +{{- end }} diff --git a/charts/istio-ingress/templates/referencegrants.yaml b/charts/istio-ingress/templates/referencegrants.yaml new file mode 100644 index 00000000..c6d4d877 --- /dev/null +++ b/charts/istio-ingress/templates/referencegrants.yaml @@ -0,0 +1,34 @@ +# ReferenceGrant to allow cross-namespace routing +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: allow-cross-namespace-routing + namespace: web-site + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: web +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: allow-acme-challenge-routing + namespace: cert-manager + labels: + {{- include "istio-ingress.labels" . | nindent 4 }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: cm-acme-http-solver diff --git a/charts/istio-ingress/values.yaml b/charts/istio-ingress/values.yaml index 0aab9038..2058aa40 100644 --- a/charts/istio-ingress/values.yaml +++ b/charts/istio-ingress/values.yaml @@ -9,11 +9,9 @@ ingress: - "*" tls: mode: SIMPLE - credentialName: wild-card-tls + credentialName: istio-ingressgateway-certs # Match the secret created by istio-certs chart externalGateway: enabled: true - hosts: - - "*" tls: mode: SIMPLE - credentialName: wild-card-tls + credentialName: istio-ingressgateway-certs # Match the secret created by istio-certs chart diff --git a/software/applications/web-site/httproute-web.yaml b/software/applications/web-site/httproute-web.yaml new file mode 100644 index 00000000..b95cc5c1 --- /dev/null +++ b/software/applications/web-site/httproute-web.yaml @@ -0,0 +1,22 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: web-site-default + namespace: web-site + labels: + app: web-site +spec: + parentRefs: + - name: external-gateway + namespace: istio-system + - name: internal-gateway + namespace: istio-system + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: osdu-developer-web-service + port: 80 + weight: 100 diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml new file mode 100644 index 00000000..3feb147c --- /dev/null +++ b/software/applications/web-site/httproute.yaml @@ -0,0 +1,23 @@ +# HTTPRoute for web-site application +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: web-site-route + namespace: web-site +spec: + parentRefs: + - name: external-gateway + namespace: istio-system + - name: internal-gateway + namespace: istio-system + rules: + # Route all web traffic to the web service + # ACME challenge paths are handled by the higher-priority route in istio-system + - matches: + - path: + type: PathPrefix + value: "/" + backendRefs: + - name: osdu-developer-web-service + port: 80 + weight: 100 diff --git a/software/applications/web-site/ingress.yaml b/software/applications/web-site/ingress.yaml index 46eb632a..42af7a89 100644 --- a/software/applications/web-site/ingress.yaml +++ b/software/applications/web-site/ingress.yaml @@ -1,21 +1,26 @@ ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: web-site - namespace: web-site -spec: - hosts: - - "*" - gateways: - - istio-system/internal-gateway - - istio-system/external-gateway - http: - - match: - - uri: - prefix: "/" - route: - - destination: - host: "osdu-developer-web-service.web-site.svc.cluster.local" - port: - number: 80 +# MIGRATED TO GATEWAY API HTTPRoute +# The VirtualService below has been replaced by HTTPRoute in httproute.yaml +# This provides better integration with cert-manager HTTP-01 challenges +# and follows the new Gateway API standard + +# --- +# apiVersion: networking.istio.io/v1alpha3 +# kind: VirtualService +# metadata: +# name: web-site +# namespace: web-site +# spec: +# hosts: +# - "*" +# gateways: +# - istio-system/internal-gateway +# - istio-system/external-gateway +# http: +# - match: +# - uri: +# prefix: "/" +# route: +# - destination: +# host: "osdu-developer-web-service.web-site.svc.cluster.local" +# port: +# number: 80 From d95ce3aab0a16e5675a729349740a1f9a23668b4 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Thu, 29 May 2025 19:34:50 -0500 Subject: [PATCH 02/13] refactor: restructure HTTPRoutes and ReferenceGrants for improved namespace management --- .../istio-ingress/templates/httproutes.yaml | 73 +++---------------- .../templates/referencegrants.yaml | 43 +++-------- .../applications/web-site/httproute-web.yaml | 22 ------ software/applications/web-site/httproute.yaml | 7 +- .../applications/web-site/referencegrant.yaml | 16 ++++ 5 files changed, 40 insertions(+), 121 deletions(-) delete mode 100644 software/applications/web-site/httproute-web.yaml create mode 100644 software/applications/web-site/referencegrant.yaml diff --git a/charts/istio-ingress/templates/httproutes.yaml b/charts/istio-ingress/templates/httproutes.yaml index ca15efd5..808cfd88 100644 --- a/charts/istio-ingress/templates/httproutes.yaml +++ b/charts/istio-ingress/templates/httproutes.yaml @@ -1,61 +1,12 @@ -# HTTPRoute for ACME challenge path routing and web traffic -{{- if .Values.ingress.externalGateway.enabled }} -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: acme-challenge-route - namespace: istio-system - labels: - {{- include "istio-ingress.labels" . | nindent 4 }} -spec: - parentRefs: - - name: external-gateway - namespace: istio-system - sectionName: http - - name: external-gateway - namespace: istio-system - sectionName: https - hostnames: - - "*.cloudapp.azure.com" - rules: - # ACME challenge route - highest priority - - matches: - - path: - type: PathPrefix - value: "/.well-known/acme-challenge/" - backendRefs: - - name: cm-acme-http-solver - port: 8089 - namespace: cert-manager -{{- end }} - -{{- if .Values.ingress.internalGateway.enabled }} ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: internal-acme-challenge-route - namespace: istio-system - labels: - {{- include "istio-ingress.labels" . | nindent 4 }} -spec: - parentRefs: - - name: internal-gateway - namespace: istio-system - sectionName: http - - name: internal-gateway - namespace: istio-system - sectionName: https - hostnames: - - "*.cloudapp.azure.com" - rules: - # ACME challenge route - highest priority - - matches: - - path: - type: PathPrefix - value: "/.well-known/acme-challenge/" - backendRefs: - - name: cm-acme-http-solver - port: 8089 - namespace: cert-manager -{{- end }} +# HTTPRoutes for ACME challenge handling with Gateway API +# +# Note: For Gateway API, cert-manager typically uses one of these approaches: +# 1. Creates temporary Ingress resources that get converted to HTTPRoutes +# 2. Uses Gateway API native challenge solvers (experimental) +# 3. Relies on application HTTPRoutes to handle challenge paths +# +# Since this is infrastructure-level routing, we'll let individual applications +# handle ACME challenge routing in their own HTTPRoutes, or cert-manager +# will create temporary resources as needed. +# +# This avoids namespace dependency issues during deployment. diff --git a/charts/istio-ingress/templates/referencegrants.yaml b/charts/istio-ingress/templates/referencegrants.yaml index c6d4d877..99816564 100644 --- a/charts/istio-ingress/templates/referencegrants.yaml +++ b/charts/istio-ingress/templates/referencegrants.yaml @@ -1,34 +1,9 @@ -# ReferenceGrant to allow cross-namespace routing -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: ReferenceGrant -metadata: - name: allow-cross-namespace-routing - namespace: web-site - labels: - {{- include "istio-ingress.labels" . | nindent 4 }} -spec: - from: - - group: gateway.networking.k8s.io - kind: HTTPRoute - namespace: istio-system - to: - - group: "" - kind: Service - name: web ---- -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: ReferenceGrant -metadata: - name: allow-acme-challenge-routing - namespace: cert-manager - labels: - {{- include "istio-ingress.labels" . | nindent 4 }} -spec: - from: - - group: gateway.networking.k8s.io - kind: HTTPRoute - namespace: istio-system - to: - - group: "" - kind: Service - name: cm-acme-http-solver +# ReferenceGrants are now managed by individual application charts +# to avoid namespace dependency issues during deployment: +# - web-site ReferenceGrant is in software/applications/web-site/ +# - cert-manager ReferenceGrant is managed by cert-manager operator +# +# This approach ensures that: +# 1. istio-ingress can deploy without waiting for application namespaces +# 2. Each application manages its own cross-namespace access permissions +# 3. No circular dependencies between infrastructure and applications diff --git a/software/applications/web-site/httproute-web.yaml b/software/applications/web-site/httproute-web.yaml deleted file mode 100644 index b95cc5c1..00000000 --- a/software/applications/web-site/httproute-web.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: web-site-default - namespace: web-site - labels: - app: web-site -spec: - parentRefs: - - name: external-gateway - namespace: istio-system - - name: internal-gateway - namespace: istio-system - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - name: osdu-developer-web-service - port: 80 - weight: 100 diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml index 3feb147c..8d02e152 100644 --- a/software/applications/web-site/httproute.yaml +++ b/software/applications/web-site/httproute.yaml @@ -9,10 +9,9 @@ spec: - name: external-gateway namespace: istio-system - name: internal-gateway - namespace: istio-system - rules: - # Route all web traffic to the web service - # ACME challenge paths are handled by the higher-priority route in istio-system + namespace: istio-system rules: + # Default route for all web traffic + # cert-manager will handle ACME challenges through its own mechanisms - matches: - path: type: PathPrefix diff --git a/software/applications/web-site/referencegrant.yaml b/software/applications/web-site/referencegrant.yaml new file mode 100644 index 00000000..b0b0d987 --- /dev/null +++ b/software/applications/web-site/referencegrant.yaml @@ -0,0 +1,16 @@ +# ReferenceGrant to allow HTTPRoutes in istio-system to reference services in web-site namespace +# This is created alongside the web-site deployment to avoid namespace dependency issues +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: allow-cross-namespace-routing + namespace: web-site +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: osdu-developer-web-service From 78b3650c9e467025936025fa6b75156bfaab1082 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Thu, 29 May 2025 20:01:32 -0500 Subject: [PATCH 03/13] bug: yaml error --- software/applications/web-site/httproute.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml index 8d02e152..28801d58 100644 --- a/software/applications/web-site/httproute.yaml +++ b/software/applications/web-site/httproute.yaml @@ -7,9 +7,9 @@ metadata: spec: parentRefs: - name: external-gateway + namespace: istio-system - name: internal-gateway namespace: istio-system - - name: internal-gateway - namespace: istio-system rules: + rules: # Default route for all web traffic # cert-manager will handle ACME challenges through its own mechanisms - matches: From c0fb3a254d113fa2141b17eeaab58b29c6e1c483 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Thu, 29 May 2025 20:12:52 -0500 Subject: [PATCH 04/13] refactor: update HTTPRoute to use internal-gateway for improved routing --- software/applications/web-site/httproute.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml index 28801d58..94bce6b2 100644 --- a/software/applications/web-site/httproute.yaml +++ b/software/applications/web-site/httproute.yaml @@ -7,7 +7,6 @@ metadata: spec: parentRefs: - name: external-gateway - namespace: istio-system - name: internal-gateway namespace: istio-system rules: # Default route for all web traffic From 64865fcd0abaaf949c57d34dda5a002f338a0ad8 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 08:04:37 -0500 Subject: [PATCH 05/13] feat: migrate from Istio VirtualServices to Gateway API HTTPRoutes with dual gateway access --- charts/istio-certs/README.md | 6 +- charts/istio-certs/templates/configmap.yaml | 14 +- charts/istio-certs/values.yaml | 10 +- charts/istio-ingress/templates/gateways.yaml | 8 + .../templates/http-route.yaml | 34 +++++ .../templates/reference-grant.yaml | 33 +++++ .../templates/virtual-service.yaml | 51 +++---- .../templates/http-route.yaml | 43 ++++++ .../templates/reference-grant.yaml | 21 +++ .../templates/virtual-service.yaml | 83 +++++------ docs/gateway-migration-summary.md | 137 ++++++++++++++++++ software/applications/web-site/httproute.yaml | 2 + software/components/airflow/httproute.yaml | 21 +++ software/components/airflow/ingress.yaml | 43 +++--- .../components/airflow/referencegrant.yaml | 15 ++ software/components/osdu-system/mesh.yaml | 15 +- software/experimental/admin-ui/httproute.yaml | 27 ++++ software/experimental/admin-ui/ingress.yaml | 47 +++--- .../experimental/admin-ui/referencegrant.yaml | 15 ++ 19 files changed, 496 insertions(+), 129 deletions(-) create mode 100644 charts/osdu-developer-auth/templates/http-route.yaml create mode 100644 charts/osdu-developer-auth/templates/reference-grant.yaml create mode 100644 charts/osdu-developer-service/templates/http-route.yaml create mode 100644 charts/osdu-developer-service/templates/reference-grant.yaml create mode 100644 docs/gateway-migration-summary.md create mode 100644 software/components/airflow/httproute.yaml create mode 100644 software/components/airflow/referencegrant.yaml create mode 100644 software/experimental/admin-ui/httproute.yaml create mode 100644 software/experimental/admin-ui/referencegrant.yaml diff --git a/charts/istio-certs/README.md b/charts/istio-certs/README.md index 850a8f7d..2c646f96 100644 --- a/charts/istio-certs/README.md +++ b/charts/istio-certs/README.md @@ -1,6 +1,6 @@ # Istio Certs Helm Chart -This chart configures DNS labels for Azure Kubernetes Service (AKS) LoadBalancer IPs, enabling automatic FQDN assignment for OSDU services. +This chart configures DNS labels for Azure Kubernetes Service (AKS) LoadBalancer IPs associated with Gateway API gateways, enabling automatic FQDN assignment for OSDU services with Let's Encrypt certificate provisioning. -------------------------------------------------------------------------------- @@ -20,8 +20,8 @@ Modify the `values.yaml` for the chart or create a `custom_values.yaml` with the azure: region: # Azure region, e.g. eastus dnsName: # Unique DNS label for the cluster -istioServiceName: istio-ingressgateway # Name of the Istio service -istioNamespace: istio-system # Namespace of the Istio service +gatewayServiceName: external-gateway-istio # Name of the Gateway API service (LoadBalancer) +gatewayNamespace: istio-system # Namespace of the Gateway API service maxRetries: 30 # Max retries for waiting on LoadBalancer IP retryInterval: 10 # Seconds between retries ``` diff --git a/charts/istio-certs/templates/configmap.yaml b/charts/istio-certs/templates/configmap.yaml index b7739b9d..3d87d5d8 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -19,12 +19,10 @@ data: tdnf install -y ca-certificates curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl && mv kubectl /usr/local/bin/ - } - - wait_for_loadbalancer_ip() { - echo "Waiting for LoadBalancer IP on service istio-ingress-external in istio-system..." + } wait_for_loadbalancer_ip() { + echo "Waiting for LoadBalancer IP on service external-gateway-istio in istio-system..." for ((i=0; i<60; i++)); do - EXTERNAL_IP=$(kubectl get svc istio-ingress-external -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || :) + EXTERNAL_IP=$(kubectl get svc external-gateway-istio -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || :) if [[ -n "$EXTERNAL_IP" ]]; then echo "Found IP: $EXTERNAL_IP" return 0 @@ -34,11 +32,9 @@ data: done echo "ERROR: LoadBalancer IP not assigned after 60 attempts." return 1 - } - - annotate_service_with_dns() { + } annotate_service_with_dns() { echo "Annotating service with DNS label ${DNS_NAME}..." - kubectl annotate svc istio-ingress-external -n istio-system \ + kubectl annotate svc external-gateway-istio -n istio-system \ service.beta.kubernetes.io/azure-dns-label-name="${DNS_NAME}" --overwrite } diff --git a/charts/istio-certs/values.yaml b/charts/istio-certs/values.yaml index 199684be..cd73bcaa 100644 --- a/charts/istio-certs/values.yaml +++ b/charts/istio-certs/values.yaml @@ -16,9 +16,9 @@ azure: dnsName: "" # DNS name to be used for the LoadBalancer IP ################################################################################ -# Istio configuration values +# Gateway API configuration values # -istioServiceName: "istio-ingressgateway" # Name of the Istio service -istioNamespace: "istio-system" # Namespace of the Istio service -maxRetries: 30 # Max retries for waiting on LoadBalancer IP -retryInterval: 10 # Seconds between retries +gatewayServiceName: "external-gateway-istio" # Name of the Gateway API service (LoadBalancer) +gatewayNamespace: "istio-system" # Namespace of the Gateway API service +maxRetries: 30 # Max retries for waiting on LoadBalancer IP +retryInterval: 10 # Seconds between retries diff --git a/charts/istio-ingress/templates/gateways.yaml b/charts/istio-ingress/templates/gateways.yaml index 2dab2f32..c4064e5a 100644 --- a/charts/istio-ingress/templates/gateways.yaml +++ b/charts/istio-ingress/templates/gateways.yaml @@ -37,8 +37,12 @@ metadata: namespace: istio-system labels: {{- include "istio-ingress.labels" . | nindent 4 }} + istio.io/gateway-name: external-gateway spec: gatewayClassName: istio + addresses: + - type: NamedAddress + value: external-gateway-istio listeners: - name: http protocol: HTTP @@ -69,8 +73,12 @@ metadata: namespace: istio-system labels: {{- include "istio-ingress.labels" . | nindent 4 }} + istio.io/gateway-name: internal-gateway spec: gatewayClassName: istio + addresses: + - type: NamedAddress + value: internal-gateway-istio listeners: - name: http protocol: HTTP diff --git a/charts/osdu-developer-auth/templates/http-route.yaml b/charts/osdu-developer-auth/templates/http-route.yaml new file mode 100644 index 00000000..c4dc79ca --- /dev/null +++ b/charts/osdu-developer-auth/templates/http-route.yaml @@ -0,0 +1,34 @@ +{{- $namespace := .Release.Namespace }} +{{- if and .Values.hosts .Values.gateways }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: osdu-auth-route + namespace: {{ $namespace }} +spec: + parentRefs: + {{- range .Values.gateways }} + - name: {{ . | regexReplaceAll "istio-system/" "" }} + namespace: istio-system + {{- end }} + rules: + # Auth SPA route + - matches: + - path: + type: PathPrefix + value: {{ .Values.path }}spa/ + backendRefs: + - name: osdu-auth-spa + port: 80 + weight: 100 + # Main auth route + - matches: + - path: + type: PathPrefix + value: {{ .Values.path }} + backendRefs: + - name: osdu-auth + port: 80 + weight: 100 +{{- end }} diff --git a/charts/osdu-developer-auth/templates/reference-grant.yaml b/charts/osdu-developer-auth/templates/reference-grant.yaml new file mode 100644 index 00000000..16b699ce --- /dev/null +++ b/charts/osdu-developer-auth/templates/reference-grant.yaml @@ -0,0 +1,33 @@ +{{- $namespace := .Release.Namespace }} +{{- if and .Values.hosts .Values.gateways }} +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: osdu-auth-reference-grant + namespace: {{ $namespace }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: osdu-auth +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: osdu-auth-spa-reference-grant + namespace: {{ $namespace }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: osdu-auth-spa +{{- end }} diff --git a/charts/osdu-developer-auth/templates/virtual-service.yaml b/charts/osdu-developer-auth/templates/virtual-service.yaml index 88ba04e9..9335ca38 100644 --- a/charts/osdu-developer-auth/templates/virtual-service.yaml +++ b/charts/osdu-developer-auth/templates/virtual-service.yaml @@ -1,25 +1,26 @@ -{{- $namespace := .Release.Namespace }} -{{- if and .Values.hosts .Values.gateways }} ---- -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -metadata: - name: osdu-auth - namespace: {{ $namespace }} -spec: - hosts: {{ toYaml .Values.hosts | nindent 4 }} - gateways: {{ toYaml .Values.gateways | nindent 4 }} - http: - - match: - - uri: - prefix: {{ .Values.path }}spa/ - route: - - destination: - host: osdu-auth-spa.{{ $namespace }}.svc.cluster.local - - match: - - uri: - prefix: {{ .Values.path }} - route: - - destination: - host: osdu-auth.{{ $namespace }}.svc.cluster.local -{{- end }} +# DEPRECATED: Migrated to Gateway API HTTPRoute (see http-route.yaml) +# {{- $namespace := .Release.Namespace }} +# {{- if and .Values.hosts .Values.gateways }} +# --- +# apiVersion: networking.istio.io/v1beta1 +# kind: VirtualService +# metadata: +# name: osdu-auth +# namespace: {{ $namespace }} +# spec: +# hosts: {{ toYaml .Values.hosts | nindent 4 }} +# gateways: {{ toYaml .Values.gateways | nindent 4 }} +# http: +# - match: +# - uri: +# prefix: {{ .Values.path }}spa/ +# route: +# - destination: +# host: osdu-auth-spa.{{ $namespace }}.svc.cluster.local +# - match: +# - uri: +# prefix: {{ .Values.path }} +# route: +# - destination: +# host: osdu-auth.{{ $namespace }}.svc.cluster.local +# {{- end }} diff --git a/charts/osdu-developer-service/templates/http-route.yaml b/charts/osdu-developer-service/templates/http-route.yaml new file mode 100644 index 00000000..766ebc4c --- /dev/null +++ b/charts/osdu-developer-service/templates/http-route.yaml @@ -0,0 +1,43 @@ +{{- $enabled := eq (include "osdu-developer-service.isEnabled" .) "1" -}} +{{- $namespace := .Release.Namespace }} +{{- range .Values.configuration }} +{{- if and $enabled .service .hosts .gateways }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ .service }}-route + namespace: {{ $namespace }} +spec: + parentRefs: + {{- range .gateways }} + - name: {{ . | regexReplaceAll "istio-system/" "" }} + namespace: istio-system + {{- end }} + rules: + - matches: + - path: + type: PathPrefix + value: {{ .path }} + backendRefs: + - name: {{ .service }} + port: 80 + weight: 100 + {{- if .cors }} + filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + add: + - name: Access-Control-Allow-Origin + value: {{ join "," .cors }} + - name: Access-Control-Allow-Methods + value: "GET,PUT,POST,DELETE,OPTIONS" + - name: Access-Control-Allow-Headers + value: "Authorization,Content-Type" + - name: Access-Control-Allow-Credentials + value: "true" + - name: Access-Control-Max-Age + value: "86400" + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/osdu-developer-service/templates/reference-grant.yaml b/charts/osdu-developer-service/templates/reference-grant.yaml new file mode 100644 index 00000000..667a1b2c --- /dev/null +++ b/charts/osdu-developer-service/templates/reference-grant.yaml @@ -0,0 +1,21 @@ +{{- $enabled := eq (include "osdu-developer-service.isEnabled" .) "1" -}} +{{- $namespace := .Release.Namespace }} +{{- range .Values.configuration }} +{{- if and $enabled .service .hosts .gateways }} +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: {{ .service }}-reference-grant + namespace: {{ $namespace }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: {{ .service }} +{{- end }} +{{- end }} diff --git a/charts/osdu-developer-service/templates/virtual-service.yaml b/charts/osdu-developer-service/templates/virtual-service.yaml index cdc2bbc7..edba5d40 100644 --- a/charts/osdu-developer-service/templates/virtual-service.yaml +++ b/charts/osdu-developer-service/templates/virtual-service.yaml @@ -1,41 +1,42 @@ -{{- $enabled := eq (include "osdu-developer-service.isEnabled" .) "1" -}} -{{- $namespace := .Release.Namespace }} -{{- $subset := .Values.subset}} -{{- range .Values.configuration }} -{{- if and $enabled .service .hosts .gateways }} ---- -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -metadata: - name: {{ .service }} -spec: - hosts: {{ toYaml .hosts | nindent 4 }} - gateways: {{ toYaml .gateways | nindent 4 }} - http: - - match: - - uri: - prefix: {{ .path }} - route: - - destination: - host: {{ .service }}.{{ $namespace }}.svc.cluster.local - subset: {{ $subset }} - {{- if .cors }} - corsPolicy: - allowCredentials: true - allowHeaders: - - Authorization - - Content-Type - allowMethods: - - GET - - PUT - - POST - - DELETE - - OPTIONS - allowOrigins: - {{- range .cors }} - - exact: {{ . }} - {{- end }} - maxAge: 24h - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file +# DEPRECATED: Migrated to Gateway API HTTPRoute (see http-route.yaml) +# {{- $enabled := eq (include "osdu-developer-service.isEnabled" .) "1" -}} +# {{- $namespace := .Release.Namespace }} +# {{- $subset := .Values.subset}} +# {{- range .Values.configuration }} +# {{- if and $enabled .service .hosts .gateways }} +# --- +# apiVersion: networking.istio.io/v1beta1 +# kind: VirtualService +# metadata: +# name: {{ .service }} +# spec: +# hosts: {{ toYaml .hosts | nindent 4 }} +# gateways: {{ toYaml .gateways | nindent 4 }} +# http: +# - match: +# - uri: +# prefix: {{ .path }} +# route: +# - destination: +# host: {{ .service }}.{{ $namespace }}.svc.cluster.local +# subset: {{ $subset }} +# {{- if .cors }} +# corsPolicy: +# allowCredentials: true +# allowHeaders: +# - Authorization +# - Content-Type +# allowMethods: +# - GET +# - PUT +# - POST +# - DELETE +# - OPTIONS +# allowOrigins: +# {{- range .cors }} +# - exact: {{ . }} +# {{- end }} +# maxAge: 24h +# {{- end }} +# {{- end }} +# {{- end }} \ No newline at end of file diff --git a/docs/gateway-migration-summary.md b/docs/gateway-migration-summary.md new file mode 100644 index 00000000..76d39170 --- /dev/null +++ b/docs/gateway-migration-summary.md @@ -0,0 +1,137 @@ +# Gateway API Migration Summary + +## Overview +Successfully migrated from Istio VirtualServices to Gateway API HTTPRoutes while maintaining both internal and external gateway access. + +## Architecture + +### Istio Gateway Services (Physical Layer) +Deployed via `software/components/osdu-system/mesh.yaml`: + +1. **External Gateway Service**: `external-gateway-istio` + - Service Type: LoadBalancer (external IP) + - Annotation: `service.beta.kubernetes.io/azure-load-balancer-internal: 'false'` + - Accessible from internet + +2. **Internal Gateway Service**: `internal-gateway-istio` + - Service Type: LoadBalancer (internal IP: 10.224.0.13) + - Annotation: `service.beta.kubernetes.io/azure-load-balancer-internal: 'true'` + - Accessible only within VNet + +### Gateway API Gateways (Logical Layer) +Deployed via `charts/istio-ingress/templates/gateways.yaml`: + +1. **external-gateway**: Bound to `external-gateway-istio` service +2. **internal-gateway**: Bound to `internal-gateway-istio` service + +## Routing Configuration + +### HTTPRoutes with Dual Gateway Access +All services are configured to accept traffic from both gateways: + +1. **Web Site** (`software/applications/web-site/httproute.yaml`) + - Path: `/` (root) + - Accessible via both external and internal IPs + +2. **Airflow** (`software/components/airflow/httproute.yaml`) + - Path: `/airflow` + - Accessible via both external and internal IPs + +3. **Admin UI** (`software/experimental/admin-ui/httproute.yaml`) + - Path: `/adminui` (rewrites to `/`) + - Accessible via both external and internal IPs + +4. **OSDU Services** (Chart templates) + - osdu-developer-service: Multiple API services with configured paths + - osdu-developer-auth: Authentication services at `/auth` and `/auth/spa/` + +## Verification Commands + +### Check Gateway Services +```powershell +# Check external gateway service (should have external IP) +kubectl get svc external-gateway-istio -n istio-system + +# Check internal gateway service (should have internal IP: 10.224.0.13) +kubectl get svc internal-gateway-istio -n istio-system +``` + +### Check Gateway API Resources +```powershell +# Check Gateway API gateways +kubectl get gateways -n istio-system + +# Check HTTPRoutes across all namespaces +kubectl get httproutes -A + +# Check ReferenceGrants for cross-namespace permissions +kubectl get referencegrants -A +``` + +### Test External Access +```powershell +# Get external IP +$EXTERNAL_IP = kubectl get svc external-gateway-istio -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' + +# Test web site +curl "http://$EXTERNAL_IP/" + +# Test airflow +curl "http://$EXTERNAL_IP/airflow" + +# Test admin UI +curl "http://$EXTERNAL_IP/adminui" +``` + +### Test Internal Access +```powershell +# From within VNet (e.g., from a pod or VM in the VNet) +curl "http://10.224.0.13/" +curl "http://10.224.0.13/airflow" +curl "http://10.224.0.13/adminui" +``` + +## Migration Changes Made + +### 1. Updated Istio Gateway Services (`mesh.yaml`) +- Added unique names and labels for each gateway service +- `external-gateway-istio` and `internal-gateway-istio` +- Proper LoadBalancer annotations for internal vs external access + +### 2. Updated Gateway API Configuration (`gateways.yaml`) +- Added `addresses` field to bind gateways to specific services +- Added proper labels for identification + +### 3. Created HTTPRoute Files +- **Charts**: Template-based HTTPRoutes with ReferenceGrants +- **Applications**: Static HTTPRoute files with dual gateway access +- **Components**: HTTPRoute files replacing VirtualServices + +### 4. Commented Out VirtualServices +- All original VirtualService files marked as deprecated +- Pointed to new HTTPRoute equivalents + +## Key Benefits + +1. **Standard Compliance**: Using Gateway API instead of Istio-specific VirtualServices +2. **Dual Access**: Services available via both internal (VNet) and external (internet) IPs +3. **Cross-namespace Security**: ReferenceGrants provide secure cross-namespace routing +4. **CORS Support**: Migrated to response header modifiers +5. **Future Proof**: Gateway API is the standard for Kubernetes ingress + +## Troubleshooting + +### If Internal Gateway Not Working +1. Verify internal gateway service has internal IP: `kubectl get svc internal-gateway-istio -n istio-system` +2. Check VNet connectivity from client +3. Verify HTTPRoute references correct gateway: `kubectl describe httproute -n ` + +### If External Gateway Not Working +1. Verify external gateway service has public IP +2. Check DNS configuration (if using FQDN) +3. Verify certificate configuration for HTTPS + +### If HTTPRoutes Not Working +1. Check gateway status: `kubectl describe gateway external-gateway -n istio-system` +2. Check ReferenceGrant permissions: `kubectl get referencegrants -A` +3. Verify Istio proxy configuration: `istioctl proxy-config routes ` diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml index 94bce6b2..56a322cf 100644 --- a/software/applications/web-site/httproute.yaml +++ b/software/applications/web-site/httproute.yaml @@ -8,6 +8,8 @@ spec: parentRefs: - name: external-gateway namespace: istio-system + - name: internal-gateway + namespace: istio-system rules: # Default route for all web traffic # cert-manager will handle ACME challenges through its own mechanisms diff --git a/software/components/airflow/httproute.yaml b/software/components/airflow/httproute.yaml new file mode 100644 index 00000000..d1650721 --- /dev/null +++ b/software/components/airflow/httproute.yaml @@ -0,0 +1,21 @@ +# HTTPRoute for airflow component +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: airflow-route + namespace: airflow +spec: + parentRefs: + - name: internal-gateway + namespace: istio-system + - name: external-gateway + namespace: istio-system + rules: + - matches: + - path: + type: PathPrefix + value: "/airflow" + backendRefs: + - name: airflow-web + port: 8080 + weight: 100 diff --git a/software/components/airflow/ingress.yaml b/software/components/airflow/ingress.yaml index 99df1a1e..4ddfb984 100644 --- a/software/components/airflow/ingress.yaml +++ b/software/components/airflow/ingress.yaml @@ -1,21 +1,22 @@ ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: airflow - namespace: airflow -spec: - hosts: - - "*" - gateways: - - istio-system/internal-gateway - - istio-system/external-gateway - http: - - match: - - uri: - prefix: "/airflow" - route: - - destination: - host: "airflow-web.airflow.svc.cluster.local" - port: - number: 8080 \ No newline at end of file +# DEPRECATED: Migrated to Gateway API HTTPRoute (see httproute.yaml) +# --- +# apiVersion: networking.istio.io/v1alpha3 +# kind: VirtualService +# metadata: +# name: airflow +# namespace: airflow +# spec: +# hosts: +# - "*" +# gateways: +# - istio-system/internal-gateway +# - istio-system/external-gateway +# http: +# - match: +# - uri: +# prefix: "/airflow" +# route: +# - destination: +# host: "airflow-web.airflow.svc.cluster.local" +# port: +# number: 8080 \ No newline at end of file diff --git a/software/components/airflow/referencegrant.yaml b/software/components/airflow/referencegrant.yaml new file mode 100644 index 00000000..cd6b5426 --- /dev/null +++ b/software/components/airflow/referencegrant.yaml @@ -0,0 +1,15 @@ +# ReferenceGrant to allow HTTPRoutes in istio-system to reference services in airflow namespace +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: airflow-reference-grant + namespace: airflow +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: airflow-web diff --git a/software/components/osdu-system/mesh.yaml b/software/components/osdu-system/mesh.yaml index 0b9c3437..c373ac44 100644 --- a/software/components/osdu-system/mesh.yaml +++ b/software/components/osdu-system/mesh.yaml @@ -133,8 +133,9 @@ spec: minProtocolVersion: TLSV1_3 defaultConfig: proxyAdminPort: 15000 - ingressSelector: istio-ingress - ingressService: istio-ingressgateway + # Updated for Gateway API - using external gateway as primary + ingressSelector: istio-external-gateway + ingressService: external-gateway-istio pilot: env: K8S_INGRESS_NS: istio-ingress @@ -166,6 +167,11 @@ spec: remediation: retries: 3 values: + # Set unique name for internal gateway + name: internal-gateway-istio + labels: + istio: internal-gateway + istio.io/gateway-name: internal-gateway service: type: LoadBalancer ports: @@ -210,6 +216,11 @@ spec: remediation: retries: 3 values: + # Set unique name for external gateway + name: external-gateway-istio + labels: + istio: external-gateway + istio.io/gateway-name: external-gateway service: type: LoadBalancer annotations: diff --git a/software/experimental/admin-ui/httproute.yaml b/software/experimental/admin-ui/httproute.yaml new file mode 100644 index 00000000..391dcae5 --- /dev/null +++ b/software/experimental/admin-ui/httproute.yaml @@ -0,0 +1,27 @@ +# HTTPRoute for admin-ui component +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: admin-ui-route + namespace: osdu-experimental +spec: + parentRefs: + - name: internal-gateway + namespace: istio-system + - name: external-gateway + namespace: istio-system + rules: + - matches: + - path: + type: PathPrefix + value: "/adminui" + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: "/" + backendRefs: + - name: osdu-experimental-admin-ui + port: 80 + weight: 100 diff --git a/software/experimental/admin-ui/ingress.yaml b/software/experimental/admin-ui/ingress.yaml index b1540fd4..4161e05a 100644 --- a/software/experimental/admin-ui/ingress.yaml +++ b/software/experimental/admin-ui/ingress.yaml @@ -1,23 +1,24 @@ ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: admin-ui - namespace: osdu-experimental -spec: - hosts: - - "*" - gateways: - - istio-system/internal-gateway - - istio-system/external-gateway - http: - - match: - - uri: - prefix: "/adminui" - rewrite: - uri: "/" - route: - - destination: - host: "osdu-experimental-admin-ui.osdu-experimental.svc.cluster.local" - port: - number: 80 +# DEPRECATED: Migrated to Gateway API HTTPRoute (see httproute.yaml) +# --- +# apiVersion: networking.istio.io/v1alpha3 +# kind: VirtualService +# metadata: +# name: admin-ui +# namespace: osdu-experimental +# spec: +# hosts: +# - "*" +# gateways: +# - istio-system/internal-gateway +# - istio-system/external-gateway +# http: +# - match: +# - uri: +# prefix: "/adminui" +# rewrite: +# uri: "/" +# route: +# - destination: +# host: "osdu-experimental-admin-ui.osdu-experimental.svc.cluster.local" +# port: +# number: 80 diff --git a/software/experimental/admin-ui/referencegrant.yaml b/software/experimental/admin-ui/referencegrant.yaml new file mode 100644 index 00000000..f5c2c1cd --- /dev/null +++ b/software/experimental/admin-ui/referencegrant.yaml @@ -0,0 +1,15 @@ +# ReferenceGrant to allow HTTPRoutes in istio-system to reference services in osdu-experimental namespace +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: admin-ui-reference-grant + namespace: osdu-experimental +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: istio-system + to: + - group: "" + kind: Service + name: osdu-experimental-admin-ui From 6b9641c834ed1ca744b8e2b4ddab977c96fd1488 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 09:11:43 -0500 Subject: [PATCH 06/13] bug: configmap script syntax --- charts/istio-certs/templates/configmap.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/charts/istio-certs/templates/configmap.yaml b/charts/istio-certs/templates/configmap.yaml index 3d87d5d8..c776af55 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -12,14 +12,14 @@ data: echo "=================================================================" echo " Starting DNS + Cert Configuration for AKS LoadBalancer" - echo "=================================================================" - - install_kubectl() { + echo "=================================================================" install_kubectl() { echo "Installing kubectl…" tdnf install -y ca-certificates curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl && mv kubectl /usr/local/bin/ - } wait_for_loadbalancer_ip() { + } + + wait_for_loadbalancer_ip() { echo "Waiting for LoadBalancer IP on service external-gateway-istio in istio-system..." for ((i=0; i<60; i++)); do EXTERNAL_IP=$(kubectl get svc external-gateway-istio -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || :) @@ -29,10 +29,11 @@ data: fi echo "…retry $((i+1))/60" sleep 5 - done - echo "ERROR: LoadBalancer IP not assigned after 60 attempts." + done echo "ERROR: LoadBalancer IP not assigned after 60 attempts." return 1 - } annotate_service_with_dns() { + } + + annotate_service_with_dns() { echo "Annotating service with DNS label ${DNS_NAME}..." kubectl annotate svc external-gateway-istio -n istio-system \ service.beta.kubernetes.io/azure-dns-label-name="${DNS_NAME}" --overwrite From 42e6f95fff67080365dc661356ab28d611eda947 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 09:20:16 -0500 Subject: [PATCH 07/13] bug: configmap script syntax --- charts/istio-certs/templates/configmap.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/charts/istio-certs/templates/configmap.yaml b/charts/istio-certs/templates/configmap.yaml index c776af55..7dd79202 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -9,10 +9,11 @@ data: configure-dns.sh: | #!/usr/bin/env bash set -euo pipefail - echo "=================================================================" echo " Starting DNS + Cert Configuration for AKS LoadBalancer" - echo "=================================================================" install_kubectl() { + echo "=================================================================" + + install_kubectl() { echo "Installing kubectl…" tdnf install -y ca-certificates curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" @@ -26,10 +27,10 @@ data: if [[ -n "$EXTERNAL_IP" ]]; then echo "Found IP: $EXTERNAL_IP" return 0 - fi - echo "…retry $((i+1))/60" + fi echo "…retry $((i+1))/60" sleep 5 - done echo "ERROR: LoadBalancer IP not assigned after 60 attempts." + done + echo "ERROR: LoadBalancer IP not assigned after 60 attempts." return 1 } From 9cdedb63587ceb1dd5ecebc806806642cf264671 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 09:27:46 -0500 Subject: [PATCH 08/13] bug: configmap script syntax --- charts/istio-certs/templates/configmap.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/charts/istio-certs/templates/configmap.yaml b/charts/istio-certs/templates/configmap.yaml index 7dd79202..73642acc 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -27,7 +27,8 @@ data: if [[ -n "$EXTERNAL_IP" ]]; then echo "Found IP: $EXTERNAL_IP" return 0 - fi echo "…retry $((i+1))/60" + fi + echo "…retry $((i+1))/60" sleep 5 done echo "ERROR: LoadBalancer IP not assigned after 60 attempts." From 35c1363a2b1c8b0e26267070a432a7deadd6684e Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 09:55:44 -0500 Subject: [PATCH 09/13] bug: virtual service --- .../templates/virtual-service.yaml | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 charts/osdu-developer-service/templates/virtual-service.yaml diff --git a/charts/osdu-developer-service/templates/virtual-service.yaml b/charts/osdu-developer-service/templates/virtual-service.yaml deleted file mode 100644 index edba5d40..00000000 --- a/charts/osdu-developer-service/templates/virtual-service.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# DEPRECATED: Migrated to Gateway API HTTPRoute (see http-route.yaml) -# {{- $enabled := eq (include "osdu-developer-service.isEnabled" .) "1" -}} -# {{- $namespace := .Release.Namespace }} -# {{- $subset := .Values.subset}} -# {{- range .Values.configuration }} -# {{- if and $enabled .service .hosts .gateways }} -# --- -# apiVersion: networking.istio.io/v1beta1 -# kind: VirtualService -# metadata: -# name: {{ .service }} -# spec: -# hosts: {{ toYaml .hosts | nindent 4 }} -# gateways: {{ toYaml .gateways | nindent 4 }} -# http: -# - match: -# - uri: -# prefix: {{ .path }} -# route: -# - destination: -# host: {{ .service }}.{{ $namespace }}.svc.cluster.local -# subset: {{ $subset }} -# {{- if .cors }} -# corsPolicy: -# allowCredentials: true -# allowHeaders: -# - Authorization -# - Content-Type -# allowMethods: -# - GET -# - PUT -# - POST -# - DELETE -# - OPTIONS -# allowOrigins: -# {{- range .cors }} -# - exact: {{ . }} -# {{- end }} -# maxAge: 24h -# {{- end }} -# {{- end }} -# {{- end }} \ No newline at end of file From 64d45599f71f31aae71622e8c1ab7bd0a541c718 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 10:17:19 -0500 Subject: [PATCH 10/13] bug: virtual service --- .../templates/http-route.yaml | 2 +- .../templates/virtual-service.yaml | 26 ------------------- .../templates/http-route.yaml | 2 +- 3 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 charts/osdu-developer-auth/templates/virtual-service.yaml diff --git a/charts/osdu-developer-auth/templates/http-route.yaml b/charts/osdu-developer-auth/templates/http-route.yaml index c4dc79ca..5bc13e02 100644 --- a/charts/osdu-developer-auth/templates/http-route.yaml +++ b/charts/osdu-developer-auth/templates/http-route.yaml @@ -9,7 +9,7 @@ metadata: spec: parentRefs: {{- range .Values.gateways }} - - name: {{ . | regexReplaceAll "istio-system/" "" }} + - name: {{ . }} namespace: istio-system {{- end }} rules: diff --git a/charts/osdu-developer-auth/templates/virtual-service.yaml b/charts/osdu-developer-auth/templates/virtual-service.yaml deleted file mode 100644 index 9335ca38..00000000 --- a/charts/osdu-developer-auth/templates/virtual-service.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# DEPRECATED: Migrated to Gateway API HTTPRoute (see http-route.yaml) -# {{- $namespace := .Release.Namespace }} -# {{- if and .Values.hosts .Values.gateways }} -# --- -# apiVersion: networking.istio.io/v1beta1 -# kind: VirtualService -# metadata: -# name: osdu-auth -# namespace: {{ $namespace }} -# spec: -# hosts: {{ toYaml .Values.hosts | nindent 4 }} -# gateways: {{ toYaml .Values.gateways | nindent 4 }} -# http: -# - match: -# - uri: -# prefix: {{ .Values.path }}spa/ -# route: -# - destination: -# host: osdu-auth-spa.{{ $namespace }}.svc.cluster.local -# - match: -# - uri: -# prefix: {{ .Values.path }} -# route: -# - destination: -# host: osdu-auth.{{ $namespace }}.svc.cluster.local -# {{- end }} diff --git a/charts/osdu-developer-service/templates/http-route.yaml b/charts/osdu-developer-service/templates/http-route.yaml index 766ebc4c..765e1c9b 100644 --- a/charts/osdu-developer-service/templates/http-route.yaml +++ b/charts/osdu-developer-service/templates/http-route.yaml @@ -11,7 +11,7 @@ metadata: spec: parentRefs: {{- range .gateways }} - - name: {{ . | regexReplaceAll "istio-system/" "" }} + - name: {{ . }} namespace: istio-system {{- end }} rules: From 167a685416b8e13458792664c4e7309c4a6d194b Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 13:54:13 -0500 Subject: [PATCH 11/13] add: ingressclass --- charts/istio-ingress/templates/gateways.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/charts/istio-ingress/templates/gateways.yaml b/charts/istio-ingress/templates/gateways.yaml index c4064e5a..322a8ec7 100644 --- a/charts/istio-ingress/templates/gateways.yaml +++ b/charts/istio-ingress/templates/gateways.yaml @@ -40,9 +40,6 @@ metadata: istio.io/gateway-name: external-gateway spec: gatewayClassName: istio - addresses: - - type: NamedAddress - value: external-gateway-istio listeners: - name: http protocol: HTTP @@ -76,9 +73,6 @@ metadata: istio.io/gateway-name: internal-gateway spec: gatewayClassName: istio - addresses: - - type: NamedAddress - value: internal-gateway-istio listeners: - name: http protocol: HTTP From 8cbd3e5396c844c7501cea56a4ec54562ae765cb Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Fri, 30 May 2025 17:51:08 -0500 Subject: [PATCH 12/13] add: ingressclass --- software/components/certs-issuer/lets-encrypt.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/software/components/certs-issuer/lets-encrypt.yaml b/software/components/certs-issuer/lets-encrypt.yaml index 66862d99..482e5d36 100644 --- a/software/components/certs-issuer/lets-encrypt.yaml +++ b/software/components/certs-issuer/lets-encrypt.yaml @@ -11,8 +11,10 @@ spec: name: letsencrypt-staging solvers: - http01: - ingress: - class: istio + gatewayHTTPRoute: + parentRefs: + - name: external-gateway + namespace: istio-system --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer @@ -26,5 +28,7 @@ spec: name: letsencrypt-production solvers: - http01: - ingress: - class: istio \ No newline at end of file + gatewayHTTPRoute: + parentRefs: + - name: external-gateway + namespace: istio-system \ No newline at end of file From a8be5c55324f5a4fb8517a027d119558a0ad6581 Mon Sep 17 00:00:00 2001 From: Daniel Scholl Date: Sat, 31 May 2025 09:06:42 -0500 Subject: [PATCH 13/13] fix: update public IP retrieval in post-provision script to prefer DNS name --- .../templates/http-route.yaml | 13 +++++-- .../templates/http-route.yaml | 13 +++++-- scripts/post-provision.ps1 | 35 +++++++++++++++---- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/charts/osdu-developer-auth/templates/http-route.yaml b/charts/osdu-developer-auth/templates/http-route.yaml index 5bc13e02..b3b8445c 100644 --- a/charts/osdu-developer-auth/templates/http-route.yaml +++ b/charts/osdu-developer-auth/templates/http-route.yaml @@ -6,11 +6,20 @@ kind: HTTPRoute metadata: name: osdu-auth-route namespace: {{ $namespace }} -spec: - parentRefs: +spec: parentRefs: {{- range .Values.gateways }} + {{- $parts := split "/" . }} + {{- if eq (len $parts) 2 }} + - name: {{ index $parts 1 }} + namespace: {{ index $parts 0 }} + group: gateway.networking.k8s.io + kind: Gateway + {{- else }} - name: {{ . }} namespace: istio-system + group: gateway.networking.k8s.io + kind: Gateway + {{- end }} {{- end }} rules: # Auth SPA route diff --git a/charts/osdu-developer-service/templates/http-route.yaml b/charts/osdu-developer-service/templates/http-route.yaml index 765e1c9b..e48361e1 100644 --- a/charts/osdu-developer-service/templates/http-route.yaml +++ b/charts/osdu-developer-service/templates/http-route.yaml @@ -8,11 +8,20 @@ kind: HTTPRoute metadata: name: {{ .service }}-route namespace: {{ $namespace }} -spec: - parentRefs: +spec: parentRefs: {{- range .gateways }} + {{- $parts := split "/" . }} + {{- if eq (len $parts) 2 }} + - name: {{ index $parts 1 }} + namespace: {{ index $parts 0 }} + group: gateway.networking.k8s.io + kind: Gateway + {{- else }} - name: {{ . }} namespace: istio-system + group: gateway.networking.k8s.io + kind: Gateway + {{- end }} {{- end }} rules: - matches: diff --git a/scripts/post-provision.ps1 b/scripts/post-provision.ps1 index d007b588..f3192dbc 100644 --- a/scripts/post-provision.ps1 +++ b/scripts/post-provision.ps1 @@ -175,14 +175,35 @@ function Update-Application { try { $redirectUris = @() $nodeResourceGroup = az aks show -g $ResourceGroup -n $AKS_NAME --query nodeResourceGroup -o tsv - $publicIp = az network public-ip list -g "$nodeResourceGroup" --query "[?contains(name, 'kubernetes')].ipAddress" -o tsv - if ($publicIp) { - Write-Host "`n==================================================================" - Write-Host "Adding Public Web Endpoint: $publicIp" - Write-Host "==================================================================" - $redirectUris += "https://$publicIp/auth/" + + # Get the public IP resource that contains 'kubernetes' in the name + $publicIpResource = az network public-ip list -g "$nodeResourceGroup" --query "[?contains(name, 'kubernetes')]" -o json | ConvertFrom-Json + + $externalEndpoint = $null + if ($publicIpResource -and $publicIpResource.Count -gt 0) { + $publicIpData = $publicIpResource[0] + + # Prefer DNS name if available, otherwise fall back to IP address + if ($publicIpData.dnsSettings -and $publicIpData.dnsSettings.fqdn) { + $externalEndpoint = $publicIpData.dnsSettings.fqdn + Write-Host "`n==================================================================" + Write-Host "Adding Public Web Endpoint (DNS): $externalEndpoint" + Write-Host "==================================================================" + } elseif ($publicIpData.ipAddress) { + $externalEndpoint = $publicIpData.ipAddress + Write-Host "`n==================================================================" + Write-Host "Adding Public Web Endpoint (IP): $externalEndpoint" + Write-Host "==================================================================" + } + + if ($externalEndpoint) { + $redirectUris += "https://$externalEndpoint/auth/" + } + } + + if ($externalEndpoint) { + azd env set INGRESS_EXTERNAL "https://$externalEndpoint/auth/" } - azd env set INGRESS_EXTERNAL "https://$publicIp/auth/" $privateIp = az network lb frontend-ip list --lb-name kubernetes-internal -g "$nodeResourceGroup" --query [].privateIPAddress -o tsv if ($privateIp) { Write-Host "`n=================================================================="