diff --git a/charts/controlplane/values.aws.selfhosted-intracluster.yaml b/charts/controlplane/values.aws.selfhosted-intracluster.yaml index 10e90fb9..c490b5fd 100644 --- a/charts/controlplane/values.aws.selfhosted-intracluster.yaml +++ b/charts/controlplane/values.aws.selfhosted-intracluster.yaml @@ -478,10 +478,22 @@ ingress: - "{{ .Values.global.CONTROLPLANE_INTRA_CLUSTER_HOST }}" secretName: "{{ .Values.global.TLS_SECRET_NAME }}" + # --- Ingress Annotations (shared across all ingress objects) --- + annotations: + # Allow the nginx controller's internal DNS to match ingress rules so that + # intra-cluster traffic (DP → CP via nginx service DNS) is routed through + # the same auth subrequest as external traffic. Without this, the :authority + # header won't match the ingress host and auth is bypassed. + nginx.ingress.kubernetes.io/server-alias: "{{ .Values.global.CONTROLPLANE_INTRA_CLUSTER_HOST }}" + # --- Protected Ingress Auth Annotations --- # These configure nginx to validate requests via flyteadmin's /me endpoint # and redirect unauthenticated users to /login for the OIDC flow. # Active when OIDC authentication is enabled (server.security.useAuth: true). + # + # All protected endpoints use "https://$host/me" so the auth subrequest goes + # through nginx itself. This ensures verifyClaims runs on the access token, + # which resolves identitytype for all callers (browser, CLI, service-to-service). protectedIngressAnnotations: nginx.ingress.kubernetes.io/auth-url: "https://$host/me" nginx.ingress.kubernetes.io/auth-signin: "https://$host/login?redirect_url=$escaped_request_uri" diff --git a/charts/controlplane/values.gcp.selfhosted-intracluster.yaml b/charts/controlplane/values.gcp.selfhosted-intracluster.yaml index f0060a6e..2e7274f9 100644 --- a/charts/controlplane/values.gcp.selfhosted-intracluster.yaml +++ b/charts/controlplane/values.gcp.selfhosted-intracluster.yaml @@ -508,7 +508,14 @@ ingress: - "{{ .Values.global.CONTROLPLANE_INTRA_CLUSTER_HOST }}" secretName: "{{ .Values.global.TLS_SECRET_NAME }}" - # Protected ingress auth annotations are now defined in the base values.yaml. + # --- Ingress Annotations (shared across all ingress objects) --- + annotations: + # Allow the nginx controller's internal DNS to match ingress rules so that + # intra-cluster traffic (DP → CP via nginx service DNS) is routed through + # the same auth subrequest as external traffic. + nginx.ingress.kubernetes.io/server-alias: "{{ .Values.global.CONTROLPLANE_INTRA_CLUSTER_HOST }}" + + # Protected ingress auth annotations are defined in the base values.yaml. # Override here only if you need to customize auth behavior for this deployment mode. # ---------------------------------------------------------------------------- diff --git a/charts/controlplane/values.yaml b/charts/controlplane/values.yaml index 65e818ae..b0c14264 100644 --- a/charts/controlplane/values.yaml +++ b/charts/controlplane/values.yaml @@ -253,6 +253,31 @@ ingress: nginx.ingress.kubernetes.io/auth-url: "http://flyteadmin.{{ template \"flyte.namespace\" . }}.svc.cluster.local/me" nginx.ingress.kubernetes.io/auth-response-headers: "Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token" nginx.ingress.kubernetes.io/auth-cache-key: "$http_authorization$http_flyte_authorization$http_cookie" + # For gRPC backends (backend-protocol: GRPC), nginx uses grpc_pass instead + # of proxy_pass. The auth-response-headers annotation only sets proxy headers, + # not gRPC headers. This configuration-snippet bridges identity headers from + # the auth subrequest response into the upstream gRPC request so backend + # services receive the caller's identity. + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; envoyGateway: # GatewayClass name for Envoy Gateway. Used when INGRESS_PROVIDER is "envoy" or "both". @@ -541,6 +566,38 @@ services: secureTunnelTenantURLPattern: http://ingress-nginx-internal.ingress-nginx.svc.cluster.local:80 # http://ingress-nginx-internal.ingress-nginx.svc.cluster.local clusterSelector: type: local + organizations: + fullnameOverride: "organizations" + sharedService: + connectPort: 8081 + initContainers: + - name: migrate + args: + - cloudorganizations + - migrate + - --config + - "/etc/config/*.yaml" + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + configMap: + sharedService: + connectPort: 8081 + metrics: + scope: "organizations:" + db: + dbname: '{{ .Values.global.DB_NAME }}' + host: '{{ .Values.global.DB_HOST }}' + username: '{{ .Values.global.DB_USER }}' + passwordPath: /etc/db/pass.txt + port: 5432 + connectionPool: + maxIdleConnections: 20 + maxOpenConnections: 20 + maxConnectionLifetime: 1m + executions: fullnameOverride: "executions" initContainers: diff --git a/tests/generated/controlplane.aws.billing-enable.yaml b/tests/generated/controlplane.aws.billing-enable.yaml index d2f2cd8e..1a106b07 100644 --- a/tests/generated/controlplane.aws.billing-enable.yaml +++ b/tests/generated/controlplane.aws.billing-enable.yaml @@ -137,6 +137,18 @@ spec: # Source: controlplane/templates/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget +metadata: + name: organizations +spec: + minAvailable: "33%" + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/pdb.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget metadata: name: queue spec: @@ -293,6 +305,18 @@ metadata: # Source: controlplane/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +--- +# Source: controlplane/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount metadata: name: queue labels: @@ -970,6 +994,76 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +data: + config.yaml: | + authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + - x-user-token + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer + useExternalIdentity: 'false' + cache: + identity: + enabled: false + connection: + environment: staging + region: us-east-2 + rootTenantURLPattern: dns:///fake-host.domain + db: + connectionPool: + maxConnectionLifetime: 1m + maxIdleConnections: 20 + maxOpenConnections: 20 + dbname: '' + host: '' + passwordPath: /etc/db/pass.txt + port: 5432 + username: '' + logger: + formatter: + type: json + level: 6 + show-source: true + otel: + type: noop + sharedService: + connectPort: 8081 + metrics: + scope: 'organizations:' + selfServeConfig: + legacyHosts: + - '' + union: + auth: + authorizationMetadataKey: flyte-authorization + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + enable: true + scopes: + - all + tokenUrl: 'https://test.example.com/oauth2/v1/token' + type: ClientSecret + internalConnectionConfig: + enabled: true + urlPattern: _SERVICE_.union.svc.cluster.local:80 +--- +# Source: controlplane/templates/configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap metadata: name: queue labels: @@ -6244,6 +6338,45 @@ spec: # Source: controlplane/templates/service.yaml apiVersion: v1 kind: Service +metadata: + name: organizations + labels: + platform.union.ai/prometheus-group: "union-services" + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: grpc + port: 80 + protocol: TCP + targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc + - name: connect + port: 83 + protocol: TCP + targetPort: connect + - name: http + port: 81 + protocol: TCP + targetPort: http + - name: debug + port: 82 + protocol: TCP + targetPort: debug + selector: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/service.yaml +apiVersion: v1 +kind: Service metadata: name: queue labels: @@ -7498,6 +7631,135 @@ spec: # Source: controlplane/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: organizations + linkerd.io/inject: disabled + prometheus.io/path: /metrics + prometheus.io/port: "10254" + labels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + spec: + serviceAccountName: organizations + volumes: + - name: secrets + secret: + secretName: + - name: db-pass + secret: + secretName: + - name: config + configMap: + name: organizations + initContainers: + - name: organizations-migrate + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - migrate + - --config + - /etc/config/*.yaml + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + containers: + - name: organizations + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + ports: + - name: grpc + containerPort: 8080 + protocol: TCP + - name: http + containerPort: 8089 + protocol: TCP + - name: debug + containerPort: 10254 + protocol: TCP + - name: connect + containerPort: 8081 + protocol: TCP + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + env: + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 250Mi + livenessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + topologyKey: "kubernetes.io/hostname" +--- +# Source: controlplane/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment metadata: name: queue labels: @@ -8033,6 +8295,32 @@ spec: averageUtilization: 80 --- # Source: controlplane/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: organizations +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: organizations + minReplicas: 1 + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +# Source: controlplane/templates/hpa.yaml --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler @@ -8174,6 +8462,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" rules: @@ -8697,6 +9005,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" rules: @@ -9431,6 +9759,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" rules: diff --git a/tests/generated/controlplane.aws.yaml b/tests/generated/controlplane.aws.yaml index 98396771..10e11fa9 100644 --- a/tests/generated/controlplane.aws.yaml +++ b/tests/generated/controlplane.aws.yaml @@ -137,6 +137,18 @@ spec: # Source: controlplane/templates/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget +metadata: + name: organizations +spec: + minAvailable: "33%" + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/pdb.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget metadata: name: queue spec: @@ -293,6 +305,18 @@ metadata: # Source: controlplane/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +--- +# Source: controlplane/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount metadata: name: queue labels: @@ -970,6 +994,76 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +data: + config.yaml: | + authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + - x-user-token + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer + useExternalIdentity: 'false' + cache: + identity: + enabled: false + connection: + environment: staging + region: us-east-2 + rootTenantURLPattern: dns:///fake-host.domain + db: + connectionPool: + maxConnectionLifetime: 1m + maxIdleConnections: 20 + maxOpenConnections: 20 + dbname: '' + host: '' + passwordPath: /etc/db/pass.txt + port: 5432 + username: '' + logger: + formatter: + type: json + level: 6 + show-source: true + otel: + type: noop + sharedService: + connectPort: 8081 + metrics: + scope: 'organizations:' + selfServeConfig: + legacyHosts: + - '' + union: + auth: + authorizationMetadataKey: flyte-authorization + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + enable: true + scopes: + - all + tokenUrl: 'https://test.example.com/oauth2/v1/token' + type: ClientSecret + internalConnectionConfig: + enabled: true + urlPattern: _SERVICE_.union.svc.cluster.local:80 +--- +# Source: controlplane/templates/configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap metadata: name: queue labels: @@ -6244,6 +6338,45 @@ spec: # Source: controlplane/templates/service.yaml apiVersion: v1 kind: Service +metadata: + name: organizations + labels: + platform.union.ai/prometheus-group: "union-services" + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: grpc + port: 80 + protocol: TCP + targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc + - name: connect + port: 83 + protocol: TCP + targetPort: connect + - name: http + port: 81 + protocol: TCP + targetPort: http + - name: debug + port: 82 + protocol: TCP + targetPort: debug + selector: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/service.yaml +apiVersion: v1 +kind: Service metadata: name: queue labels: @@ -7504,6 +7637,136 @@ spec: # Source: controlplane/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: organizations + linkerd.io/inject: disabled + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + spec: + serviceAccountName: organizations + volumes: + - name: secrets + secret: + secretName: + - name: db-pass + secret: + secretName: + - name: config + configMap: + name: organizations + initContainers: + - name: organizations-migrate + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - migrate + - --config + - /etc/config/*.yaml + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + containers: + - name: organizations + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + ports: + - name: grpc + containerPort: 8080 + protocol: TCP + - name: http + containerPort: 8089 + protocol: TCP + - name: debug + containerPort: 10254 + protocol: TCP + - name: connect + containerPort: 8081 + protocol: TCP + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + env: + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 250Mi + livenessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + topologyKey: "kubernetes.io/hostname" +--- +# Source: controlplane/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment metadata: name: queue labels: @@ -8036,6 +8299,32 @@ spec: averageUtilization: 80 --- # Source: controlplane/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: organizations +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: organizations + minReplicas: 1 + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +# Source: controlplane/templates/hpa.yaml --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler @@ -8182,6 +8471,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; nginx.ingress.kubernetes.io/use-regex: "true" spec: ingressClassName: "controlplane" @@ -8706,6 +9015,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: @@ -9445,6 +9774,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: diff --git a/tests/generated/controlplane.custom-oidc.yaml b/tests/generated/controlplane.custom-oidc.yaml index 0ef0c61f..a5efd48f 100644 --- a/tests/generated/controlplane.custom-oidc.yaml +++ b/tests/generated/controlplane.custom-oidc.yaml @@ -137,6 +137,18 @@ spec: # Source: controlplane/templates/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget +metadata: + name: organizations +spec: + minAvailable: "33%" + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/pdb.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget metadata: name: queue spec: @@ -302,6 +314,18 @@ metadata: # Source: controlplane/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +--- +# Source: controlplane/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount metadata: name: queue labels: @@ -1031,6 +1055,86 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +data: + config.yaml: | + admin: + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + endpoint: '' + insecure: true + authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + - x-user-token + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer + useExternalIdentity: 'false' + cache: + identity: + enabled: false + connection: + environment: staging + region: us-east-2 + rootTenantURLPattern: dns:///fake-host.domain + db: + connectionPool: + maxConnectionLifetime: 1m + maxIdleConnections: 20 + maxOpenConnections: 20 + dbname: '' + host: '' + passwordPath: /etc/db/pass.txt + port: 5432 + username: '' + logger: + formatter: + type: json + level: 6 + show-source: true + otel: + type: noop + sharedService: + connectPort: 8081 + metrics: + scope: 'organizations:' + security: + singleTenantOrgID: '' + selfServeConfig: + legacyHosts: + - '' + union: + auth: + authorizationMetadataKey: flyte-authorization + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + enable: true + scopes: + - all + tokenUrl: 'https://idp.example.com/oauth2/v2.0/token' + type: ClientSecret + connection: + insecure: false + insecureSkipVerify: true + internalConnectionConfig: + enabled: true + urlPattern: _SERVICE_.union.svc.cluster.local:80 +--- +# Source: controlplane/templates/configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap metadata: name: queue labels: @@ -6291,6 +6395,45 @@ spec: # Source: controlplane/templates/service.yaml apiVersion: v1 kind: Service +metadata: + name: organizations + labels: + platform.union.ai/prometheus-group: "union-services" + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: grpc + port: 80 + protocol: TCP + targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc + - name: connect + port: 83 + protocol: TCP + targetPort: connect + - name: http + port: 81 + protocol: TCP + targetPort: http + - name: debug + port: 82 + protocol: TCP + targetPort: debug + selector: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/service.yaml +apiVersion: v1 +kind: Service metadata: name: queue labels: @@ -7572,6 +7715,137 @@ spec: # Source: controlplane/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: organizations + linkerd.io/inject: disabled + prometheus.io/path: /metrics + prometheus.io/port: "10254" + labels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + spec: + imagePullSecrets: + - name: union-registry-secret + serviceAccountName: organizations + volumes: + - name: secrets + secret: + secretName: + - name: db-pass + secret: + secretName: + - name: config + configMap: + name: organizations + initContainers: + - name: organizations-migrate + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - migrate + - --config + - /etc/config/*.yaml + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + containers: + - name: organizations + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + ports: + - name: grpc + containerPort: 8080 + protocol: TCP + - name: http + containerPort: 8089 + protocol: TCP + - name: debug + containerPort: 10254 + protocol: TCP + - name: connect + containerPort: 8081 + protocol: TCP + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + env: + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 250Mi + livenessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + topologyKey: "kubernetes.io/hostname" +--- +# Source: controlplane/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment metadata: name: queue labels: @@ -8113,6 +8387,32 @@ spec: averageUtilization: 80 --- # Source: controlplane/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: organizations +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: organizations + minReplicas: 1 + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +# Source: controlplane/templates/hpa.yaml --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler @@ -8195,6 +8495,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -8255,6 +8556,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -8275,6 +8577,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; nginx.ingress.kubernetes.io/use-regex: "true" spec: ingressClassName: "controlplane" @@ -8308,6 +8630,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -8362,6 +8685,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -8779,6 +9103,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -8799,6 +9124,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: @@ -9518,6 +9863,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -9538,6 +9884,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: @@ -9874,6 +10240,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -10080,6 +10447,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -10165,6 +10533,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; @@ -10214,6 +10583,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-buffer-size: 32k nginx.ingress.kubernetes.io/proxy-buffers: 4 32k nginx.ingress.kubernetes.io/proxy-cookie-domain: ~^ .$host + nginx.ingress.kubernetes.io/server-alias: '' nginx.ingress.kubernetes.io/server-snippet: | client_header_timeout 604800; client_body_timeout 604800; diff --git a/tests/generated/controlplane.external-authz.yaml b/tests/generated/controlplane.external-authz.yaml index ac76450b..816ba22d 100644 --- a/tests/generated/controlplane.external-authz.yaml +++ b/tests/generated/controlplane.external-authz.yaml @@ -137,6 +137,18 @@ spec: # Source: controlplane/templates/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget +metadata: + name: organizations +spec: + minAvailable: "33%" + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/pdb.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget metadata: name: queue spec: @@ -291,6 +303,18 @@ metadata: # Source: controlplane/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +--- +# Source: controlplane/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount metadata: name: queue labels: @@ -975,6 +999,76 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +data: + config.yaml: | + authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + - x-user-token + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer + useExternalIdentity: 'true' + cache: + identity: + enabled: false + connection: + environment: staging + region: us-east-2 + rootTenantURLPattern: dns:///fake-host.domain + db: + connectionPool: + maxConnectionLifetime: 1m + maxIdleConnections: 20 + maxOpenConnections: 20 + dbname: '' + host: '' + passwordPath: /etc/db/pass.txt + port: 5432 + username: '' + logger: + formatter: + type: json + level: 6 + show-source: true + otel: + type: noop + sharedService: + connectPort: 8081 + metrics: + scope: 'organizations:' + selfServeConfig: + legacyHosts: + - '' + union: + auth: + authorizationMetadataKey: flyte-authorization + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + enable: true + scopes: + - all + tokenUrl: 'https://test.example.com/oauth2/v1/token' + type: ClientSecret + internalConnectionConfig: + enabled: true + urlPattern: _SERVICE_.union.svc.cluster.local:80 +--- +# Source: controlplane/templates/configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap metadata: name: queue labels: @@ -6249,6 +6343,45 @@ spec: # Source: controlplane/templates/service.yaml apiVersion: v1 kind: Service +metadata: + name: organizations + labels: + platform.union.ai/prometheus-group: "union-services" + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: grpc + port: 80 + protocol: TCP + targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc + - name: connect + port: 83 + protocol: TCP + targetPort: connect + - name: http + port: 81 + protocol: TCP + targetPort: http + - name: debug + port: 82 + protocol: TCP + targetPort: debug + selector: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/service.yaml +apiVersion: v1 +kind: Service metadata: name: queue labels: @@ -7503,6 +7636,135 @@ spec: # Source: controlplane/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: organizations + linkerd.io/inject: disabled + prometheus.io/path: /metrics + prometheus.io/port: "10254" + labels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + spec: + serviceAccountName: organizations + volumes: + - name: secrets + secret: + secretName: + - name: db-pass + secret: + secretName: + - name: config + configMap: + name: organizations + initContainers: + - name: organizations-migrate + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - migrate + - --config + - /etc/config/*.yaml + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + containers: + - name: organizations + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + ports: + - name: grpc + containerPort: 8080 + protocol: TCP + - name: http + containerPort: 8089 + protocol: TCP + - name: debug + containerPort: 10254 + protocol: TCP + - name: connect + containerPort: 8081 + protocol: TCP + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + env: + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 250Mi + livenessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + topologyKey: "kubernetes.io/hostname" +--- +# Source: controlplane/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment metadata: name: queue labels: @@ -8038,6 +8300,32 @@ spec: averageUtilization: 80 --- # Source: controlplane/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: organizations +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: organizations + minReplicas: 1 + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +# Source: controlplane/templates/hpa.yaml --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler @@ -8184,6 +8472,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; nginx.ingress.kubernetes.io/use-regex: "true" spec: ingressClassName: "controlplane" @@ -8708,6 +9016,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: @@ -9447,6 +9775,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: diff --git a/tests/generated/controlplane.userclouds.yaml b/tests/generated/controlplane.userclouds.yaml index 473cbef1..2b1d6e1f 100644 --- a/tests/generated/controlplane.userclouds.yaml +++ b/tests/generated/controlplane.userclouds.yaml @@ -155,6 +155,18 @@ spec: # Source: controlplane/templates/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget +metadata: + name: organizations +spec: + minAvailable: "33%" + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/pdb.yaml +apiVersion: policy/v1 +kind: PodDisruptionBudget metadata: name: queue spec: @@ -323,6 +335,18 @@ metadata: # Source: controlplane/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +--- +# Source: controlplane/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount metadata: name: queue labels: @@ -1046,6 +1070,76 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +data: + config.yaml: | + authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + - x-user-token + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer + useExternalIdentity: 'false' + cache: + identity: + enabled: false + connection: + environment: staging + region: us-east-2 + rootTenantURLPattern: dns:///fake-host.domain + db: + connectionPool: + maxConnectionLifetime: 1m + maxIdleConnections: 20 + maxOpenConnections: 20 + dbname: '' + host: '' + passwordPath: /etc/db/pass.txt + port: 5432 + username: '' + logger: + formatter: + type: json + level: 6 + show-source: true + otel: + type: noop + sharedService: + connectPort: 8081 + metrics: + scope: 'organizations:' + selfServeConfig: + legacyHosts: + - '' + union: + auth: + authorizationMetadataKey: flyte-authorization + clientId: 'test-internal-client-id' + clientSecretLocation: /etc/secrets/union/client_secret + enable: true + scopes: + - all + tokenUrl: 'https://test.example.com/oauth2/v1/token' + type: ClientSecret + internalConnectionConfig: + enabled: true + urlPattern: _SERVICE_.union.svc.cluster.local:80 +--- +# Source: controlplane/templates/configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap metadata: name: queue labels: @@ -6378,6 +6472,45 @@ spec: # Source: controlplane/templates/service.yaml apiVersion: v1 kind: Service +metadata: + name: organizations + labels: + platform.union.ai/prometheus-group: "union-services" + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: grpc + port: 80 + protocol: TCP + targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc + - name: connect + port: 83 + protocol: TCP + targetPort: connect + - name: http + port: 81 + protocol: TCP + targetPort: http + - name: debug + port: 82 + protocol: TCP + targetPort: debug + selector: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name +--- +# Source: controlplane/templates/service.yaml +apiVersion: v1 +kind: Service metadata: name: queue labels: @@ -7746,6 +7879,135 @@ spec: # Source: controlplane/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment +metadata: + name: organizations + labels: + helm.sh/chart: controlplane-2026.4.7 + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "2026.4.7" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: organizations + linkerd.io/inject: disabled + prometheus.io/path: /metrics + prometheus.io/port: "10254" + labels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + spec: + serviceAccountName: organizations + volumes: + - name: secrets + secret: + secretName: + - name: db-pass + secret: + secretName: + - name: config + configMap: + name: organizations + initContainers: + - name: organizations-migrate + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - migrate + - --config + - /etc/config/*.yaml + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + containers: + - name: organizations + image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.4.7 + imagePullPolicy: IfNotPresent + args: + - cloudorganizations + - serve + - --config + - /etc/config/*.yaml + ports: + - name: grpc + containerPort: 8080 + protocol: TCP + - name: http + containerPort: 8089 + protocol: TCP + - name: debug + containerPort: 10254 + protocol: TCP + - name: connect + containerPort: 8081 + protocol: TCP + volumeMounts: + - name: db-pass + mountPath: /etc/db + - name: secrets + mountPath: /etc/secrets/union + - name: config + mountPath: /etc/config/ + env: + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 250Mi + livenessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: debug + initialDelaySeconds: 3 + periodSeconds: 3 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: organizations + app.kubernetes.io/instance: release-name + topologyKey: "kubernetes.io/hostname" +--- +# Source: controlplane/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment metadata: name: queue labels: @@ -8301,6 +8563,32 @@ spec: averageUtilization: 80 --- # Source: controlplane/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: organizations +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: organizations + minReplicas: 1 + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +# Source: controlplane/templates/hpa.yaml --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler @@ -8447,6 +8735,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; nginx.ingress.kubernetes.io/use-regex: "true" spec: ingressClassName: "controlplane" @@ -8971,6 +9279,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: @@ -9710,6 +10038,26 @@ metadata: nginx.ingress.kubernetes.io/auth-cache-key: $http_authorization$http_flyte_authorization$http_cookie nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-User-Subject,X-User-Claim-Identitytype,X-User-Claim-Preferred-Username,X-User-Token nginx.ingress.kubernetes.io/auth-url: http://flyteadmin.union.svc.cluster.local/me + nginx.ingress.kubernetes.io/configuration-snippet: | + auth_request_set $user_id $upstream_http_x_user_subject; + proxy_set_header X-User-Subject $user_id; + grpc_set_header X-User-Subject $user_id; + + auth_request_set $user_identitytype $upstream_http_x_user_claim_identitytype; + proxy_set_header X-User-Claim-Identitytype $user_identitytype; + grpc_set_header X-User-Claim-Identitytype $user_identitytype; + + auth_request_set $user_handle $upstream_http_x_user_claim_userhandle; + proxy_set_header X-User-Claim-userhandle $user_handle; + grpc_set_header X-User-Claim-userhandle $user_handle; + + auth_request_set $groups $upstream_http_x_user_claim_groups; + proxy_set_header X-User-Claim-groups $groups; + grpc_set_header X-User-Claim-groups $groups; + + more_set_headers "x-request-id: $request_id"; + proxy_set_header x-request-id $request_id; + grpc_set_header x-request-id $request_id; spec: ingressClassName: "controlplane" tls: