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/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..73642acc 100644 --- a/charts/istio-certs/templates/configmap.yaml +++ b/charts/istio-certs/templates/configmap.yaml @@ -9,7 +9,6 @@ data: configure-dns.sh: | #!/usr/bin/env bash set -euo pipefail - echo "=================================================================" echo " Starting DNS + Cert Configuration for AKS LoadBalancer" echo "=================================================================" @@ -22,13 +21,13 @@ data: } wait_for_loadbalancer_ip() { - echo "Waiting for LoadBalancer IP on service istio-ingress-external in istio-system..." + 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 - fi + fi echo "…retry $((i+1))/60" sleep 5 done @@ -38,7 +37,7 @@ data: 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 } @@ -58,7 +57,6 @@ data: } main "$@" - istio-certificate.yaml: | apiVersion: cert-manager.io/v1 kind: Certificate @@ -71,10 +69,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-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/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..322a8ec7 100644 --- a/charts/istio-ingress/templates/gateways.yaml +++ b/charts/istio-ingress/templates/gateways.yaml @@ -1,60 +1,95 @@ {{- 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 }} + istio.io/gateway-name: external-gateway +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 }} + istio.io/gateway-name: internal-gateway +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..808cfd88 --- /dev/null +++ b/charts/istio-ingress/templates/httproutes.yaml @@ -0,0 +1,12 @@ +# 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 new file mode 100644 index 00000000..99816564 --- /dev/null +++ b/charts/istio-ingress/templates/referencegrants.yaml @@ -0,0 +1,9 @@ +# 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/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/charts/osdu-developer-auth/templates/http-route.yaml b/charts/osdu-developer-auth/templates/http-route.yaml new file mode 100644 index 00000000..b3b8445c --- /dev/null +++ b/charts/osdu-developer-auth/templates/http-route.yaml @@ -0,0 +1,43 @@ +{{- $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 }} + {{- $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 + - 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 deleted file mode 100644 index 88ba04e9..00000000 --- a/charts/osdu-developer-auth/templates/virtual-service.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- $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..e48361e1 --- /dev/null +++ b/charts/osdu-developer-service/templates/http-route.yaml @@ -0,0 +1,52 @@ +{{- $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 }} + {{- $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: + - 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 deleted file mode 100644 index cdc2bbc7..00000000 --- a/charts/osdu-developer-service/templates/virtual-service.yaml +++ /dev/null @@ -1,41 +0,0 @@ -{{- $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/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==================================================================" diff --git a/software/applications/web-site/httproute.yaml b/software/applications/web-site/httproute.yaml new file mode 100644 index 00000000..56a322cf --- /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: + # Default route for all web traffic + # cert-manager will handle ACME challenges through its own mechanisms + - 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 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 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/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 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