diff --git a/features.md b/features.md index dcf231b6e89..d5ef6fae0e0 100644 --- a/features.md +++ b/features.md @@ -11,6 +11,7 @@ | MultiArchInstallAzure| | | | | | | | | | ShortCertRotation| | | | | | | | | | MutableTopology| | | | Enabled | | | | | +| AuthenticationComponentProxy| | | | Enabled | | | | Enabled | | ClusterAPIComputeInstall| | | Enabled | Enabled | | | | | | ClusterAPIControlPlaneInstall| | | Enabled | Enabled | | | | | | ClusterUpdatePreflight| | | Enabled | Enabled | | | | | diff --git a/features/features.go b/features/features.go index 4a5484803fe..3b98fce99a4 100644 --- a/features/features.go +++ b/features/features.go @@ -368,6 +368,14 @@ var ( enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateAuthenticationComponentProxy = newFeatureGate("AuthenticationComponentProxy"). + reportProblemsToJiraComponent("authentication"). + contactPerson("liouk"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/2015"). + enable(inClusterProfile(SelfManaged), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + mustRegister() + FeatureGateExternalOIDCWithAdditionalClaimMappings = newFeatureGate("ExternalOIDCWithUIDAndExtraClaimMappings"). reportProblemsToJiraComponent("authentication"). contactPerson("bpalmer"). diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index d81301eaaa6..05dc1f79143 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -1090,7 +1090,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA operatorv1.AdditionalNetworkDefinition{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AdditionalNetworkDefinition(ref), operatorv1.AdditionalRoutingCapabilities{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AdditionalRoutingCapabilities(ref), operatorv1.Authentication{}.OpenAPIModelName(): schema_openshift_api_operator_v1_Authentication(ref), + operatorv1.AuthenticationConfigMapReference{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AuthenticationConfigMapReference(ref), operatorv1.AuthenticationList{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AuthenticationList(ref), + operatorv1.AuthenticationProxyConfig{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AuthenticationProxyConfig(ref), operatorv1.AuthenticationSpec{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AuthenticationSpec(ref), operatorv1.AuthenticationStatus{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AuthenticationStatus(ref), operatorv1.AzureCSIDriverConfigSpec{}.OpenAPIModelName(): schema_openshift_api_operator_v1_AzureCSIDriverConfigSpec(ref), @@ -53113,6 +53115,27 @@ func schema_openshift_api_operator_v1_Authentication(ref common.ReferenceCallbac } } +func schema_openshift_api_operator_v1_AuthenticationConfigMapReference(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "AuthenticationConfigMapReference references a ConfigMap in the openshift-config namespace.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name is the metadata.name of the referenced ConfigMap. Must be a valid DNS subdomain name (RFC 1123): at most 253 characters, only lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + } +} + func schema_openshift_api_operator_v1_AuthenticationList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -53163,6 +53186,62 @@ func schema_openshift_api_operator_v1_AuthenticationList(ref common.ReferenceCal } } +func schema_openshift_api_operator_v1_AuthenticationProxyConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "AuthenticationProxyConfig holds proxy configuration scoped to authentication components (the OAuth server and the cluster authentication operator).", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "httpProxy": { + SchemaProps: spec.SchemaProps{ + Description: "httpProxy is the URL of the proxy for HTTP requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + Type: []string{"string"}, + Format: "", + }, + }, + "httpsProxy": { + SchemaProps: spec.SchemaProps{ + Description: "httpsProxy is the URL of the proxy for HTTPS requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + Type: []string{"string"}, + Format: "", + }, + }, + "noProxy": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "set", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "noProxy is a list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. Must contain at least one entry when set. Each entry must be between 1 and 253 characters long and at most 64 entries are allowed. Duplicate entries are not permitted. Entries that are not valid hostnames, CIDRs, or IPs are silently ignored. Cluster-internal defaults (.cluster.local, .svc, 127.0.0.1, localhost) are always appended automatically and do not need to be included.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "trustedCA": { + SchemaProps: spec.SchemaProps{ + Description: "trustedCA is a reference to a ConfigMap in the openshift-config namespace containing a CA certificate bundle under the key \"ca-bundle.crt\". This bundle is appended to the system trust store used by authentication components for proxy TLS connections. When omitted, only the system trust store is used.", + Default: map[string]interface{}{}, + Ref: ref(operatorv1.AuthenticationConfigMapReference{}.OpenAPIModelName()), + }, + }, + }, + }, + }, + Dependencies: []string{ + operatorv1.AuthenticationConfigMapReference{}.OpenAPIModelName()}, + } +} + func schema_openshift_api_operator_v1_AuthenticationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -53203,12 +53282,19 @@ func schema_openshift_api_operator_v1_AuthenticationSpec(ref common.ReferenceCal Ref: ref(runtime.RawExtension{}.OpenAPIModelName()), }, }, + "proxy": { + SchemaProps: spec.SchemaProps{ + Description: "proxy configures proxy settings for outbound connections made by the authentication stack. When set, it replaces the cluster-wide proxy (proxy.config.openshift.io/cluster) entirely for authentication — individual fields are not inherited from the cluster-wide configuration. When omitted, the cluster-wide proxy is used if configured; otherwise no proxy is used.", + Default: map[string]interface{}{}, + Ref: ref(operatorv1.AuthenticationProxyConfig{}.OpenAPIModelName()), + }, + }, }, Required: []string{"managementState"}, }, }, Dependencies: []string{ - runtime.RawExtension{}.OpenAPIModelName()}, + operatorv1.AuthenticationProxyConfig{}.OpenAPIModelName(), runtime.RawExtension{}.OpenAPIModelName()}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index b3a2453c2de..c309af037b6 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -5271,6 +5271,100 @@ } } }, + "com.github.openshift.api.config.v1.CRIOCredentialProviderConfig": { + "description": "CRIOCredentialProviderConfig holds cluster-wide singleton resource configurations for CRI-O credential provider, the name of this instance is \"cluster\". CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources. For example, it can be used to fetch mirror registry credentials from secrets resources in the cluster within the same namespace the pod will be running in. CRIOCredentialProviderConfig configuration specifies the pod image sources registries that should trigger the CRI-O credential provider execution, which will resolve the CRI-O mirror configurations and obtain the necessary credentials for pod creation. Note: Configuration changes will only take effect after the kubelet restarts, which is automatically managed by the cluster during rollout.\n\nThe resource is a singleton named \"cluster\".\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", + "type": "object", + "required": [ + "spec" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "description": "spec defines the desired configuration of the CRI-O Credential Provider. This field is required and must be provided when creating the resource.", + "$ref": "#/definitions/com.github.openshift.api.config.v1.CRIOCredentialProviderConfigSpec" + }, + "status": { + "description": "status represents the current state of the CRIOCredentialProviderConfig. When omitted or nil, it indicates that the status has not yet been set by the controller. The controller will populate this field with validation conditions and operational state.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.CRIOCredentialProviderConfigStatus" + } + } + }, + "com.github.openshift.api.config.v1.CRIOCredentialProviderConfigList": { + "description": "CRIOCredentialProviderConfigList contains a list of CRIOCredentialProviderConfig resources\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", + "type": "object", + "required": [ + "metadata", + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.CRIOCredentialProviderConfig" + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "description": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + } + }, + "com.github.openshift.api.config.v1.CRIOCredentialProviderConfigSpec": { + "description": "CRIOCredentialProviderConfigSpec defines the desired configuration of the CRI-O Credential Provider.", + "type": "object", + "properties": { + "matchImages": { + "description": "matchImages is a list of string patterns used to determine whether the CRI-O credential provider should be invoked for a given image. This list is passed to the kubelet CredentialProviderConfig, and if any pattern matches the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling that image or its mirrors. Depending on the platform, the CRI-O credential provider may be installed alongside an existing platform specific provider. Conflicts between the existing platform specific provider image match configuration and this list will be handled by the following precedence rule: credentials from built-in kubelet providers (e.g., ECR, GCR, ACR) take precedence over those from the CRIOCredentialProviderConfig when both match the same image. To avoid uncertainty, it is recommended to avoid configuring your private image patterns to overlap with existing platform specific provider config(e.g., the entries from https://github.com/openshift/machine-config-operator/blob/main/templates/common/aws/files/etc-kubernetes-credential-providers-ecr-credential-provider.yaml). You can check the resource's Status conditions to see if any entries were ignored due to exact matches with known built-in provider patterns.\n\nThis field is optional, the items of the list must contain between 1 and 50 entries. The list is treated as a set, so duplicate entries are not allowed.\n\nFor more details, see: https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/ https://github.com/cri-o/crio-credential-provider#architecture\n\nEach entry in matchImages is a pattern which can optionally contain a port and a path. Each entry must be no longer than 512 characters. Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io', and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net'). A global wildcard '*' (matching any domain) is not allowed. Wildcards may replace an entire hostname label (e.g., *.example.com), but they cannot appear within a label (e.g., f*oo.example.com) and are not allowed in the port or path. For example, 'example.*.com' is valid, but 'exa*mple.*.com' is not. Each wildcard matches only a single domain label, so '*.io' does **not** match '*.k8s.io'.\n\nA match exists between an image and a matchImage when all of the below are true: Both contain the same number of domain parts and each part matches. The URL path of an matchImages must be a prefix of the target image URL path. If the matchImages contains a port, then the port must match in the image as well.\n\nExample values of matchImages: - 123456789.dkr.ecr.us-east-1.amazonaws.com - *.azurecr.io - gcr.io - *.*.registry.io - registry.io:8080/path", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "set" + } + } + }, + "com.github.openshift.api.config.v1.CRIOCredentialProviderConfigStatus": { + "description": "CRIOCredentialProviderConfigStatus defines the observed state of CRIOCredentialProviderConfig", + "type": "object", + "properties": { + "conditions": { + "description": "conditions represent the latest available observations of the configuration state. When omitted, it indicates that no conditions have been reported yet. The maximum number of conditions is 16. Conditions are stored as a map keyed by condition type, ensuring uniqueness.\n\nExpected condition types include: \"Validated\": indicates whether the matchImages configuration is valid", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Condition" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + } + }, "com.github.openshift.api.config.v1.CertInfo": { "description": "CertInfo relates a certificate with a private key", "type": "object", @@ -8418,7 +8512,7 @@ "$ref": "#/definitions/com.github.openshift.api.config.v1.ConfigMapFileReference" }, "controlPlaneTopology": { - "description": "controlPlaneTopology expresses the desired topology configuration for control nodes. The 'HighlyAvailable' mode represents a \"normal\", 3 control node cluster. The 'SingleReplica' mode represents configuration where there is a single control node. If left blank, no change is required and no transitions will be triggered.", + "description": "controlPlaneTopology expresses the desired topology configuration for control nodes.\n\nWhen status.controlPlaneTopology is 'SingleReplica' and spec.controlPlaneTopology is set to 'HighlyAvailable', a transition will be triggered to reconfigure the cluster from SingleReplica to HighlyAvailable.\n\nWhen left blank or status.controlPlaneTopology and spec.controlPlaneTopology are the same value, no changes are required and no transitions will be triggered.\n\nThis value may be set to match status.controlPlaneTopology regardless of the current value.", "type": "string" }, "platformSpec": { @@ -30498,6 +30592,14 @@ }, "x-kubernetes-list-type": "atomic" }, + "protocol": { + "description": "protocol specifies whether the Network Load Balancer uses PROXY protocol to forward connections to the IngressController.\n\nWhen set to \"TCP\", the NLB uses AWS's native client IP preservation. This may cause hairpin connection failures for internal load balancers when connections are made from pods to router pods on the same node.\n\nWhen set to \"PROXY\", the NLB disables native client IP preservation and uses PROXY protocol v2. The IngressController enables PROXY protocol on HAProxy so that it can parse PROXY protocol headers to obtain the original client IP. This avoids hairpin connection failures.\n\nThe following values are valid for this field:\n\n* \"TCP\". * \"PROXY\".\n\nWhen omitted, this means the user has no opinion and the value is left to the platform to choose a reasonable default, which is subject to change over time. The current default is \"PROXY\".\n\nNote that changing this field may cause brief connection failures during the transition as the NLB attribute change and router rollout occur independently.\n\n\nPossible enum values:\n - `\"PROXY\"` instructs the NLB to forward connections using PROXY protocol v2.\n - `\"TCP\"` instructs the NLB to forward connections using TCP without PROXY protocol.", + "type": "string", + "enum": [ + "PROXY", + "TCP" + ] + }, "subnets": { "description": "subnets specifies the subnets to which the load balancer will attach. The subnets may be specified by either their ID or name. The total number of subnets is limited to 10.\n\nIn order for the load balancer to be provisioned with subnets, each subnet must exist, each subnet must be from a different availability zone, and the load balancer service must be recreated to pick up new values.\n\nWhen omitted from the spec, the subnets will be auto-discovered for each availability zone. Auto-discovered subnets are not reported in the status of the IngressController object.", "$ref": "#/definitions/com.github.openshift.api.operator.v1.AWSSubnets" @@ -30658,6 +30760,19 @@ } } }, + "com.github.openshift.api.operator.v1.AuthenticationConfigMapReference": { + "description": "AuthenticationConfigMapReference references a ConfigMap in the openshift-config namespace.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "description": "name is the metadata.name of the referenced ConfigMap. Must be a valid DNS subdomain name (RFC 1123): at most 253 characters, only lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character.", + "type": "string" + } + } + }, "com.github.openshift.api.operator.v1.AuthenticationList": { "description": "AuthenticationList is a collection of items\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "type": "object", @@ -30688,6 +30803,34 @@ } } }, + "com.github.openshift.api.operator.v1.AuthenticationProxyConfig": { + "description": "AuthenticationProxyConfig holds proxy configuration scoped to authentication components (the OAuth server and the cluster authentication operator).", + "type": "object", + "properties": { + "httpProxy": { + "description": "httpProxy is the URL of the proxy for HTTP requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "type": "string" + }, + "httpsProxy": { + "description": "httpsProxy is the URL of the proxy for HTTPS requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "type": "string" + }, + "noProxy": { + "description": "noProxy is a list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. Must contain at least one entry when set. Each entry must be between 1 and 253 characters long and at most 64 entries are allowed. Duplicate entries are not permitted. Entries that are not valid hostnames, CIDRs, or IPs are silently ignored. Cluster-internal defaults (.cluster.local, .svc, 127.0.0.1, localhost) are always appended automatically and do not need to be included.", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "set" + }, + "trustedCA": { + "description": "trustedCA is a reference to a ConfigMap in the openshift-config namespace containing a CA certificate bundle under the key \"ca-bundle.crt\". This bundle is appended to the system trust store used by authentication components for proxy TLS connections. When omitted, only the system trust store is used.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.AuthenticationConfigMapReference" + } + } + }, "com.github.openshift.api.operator.v1.AuthenticationSpec": { "type": "object", "required": [ @@ -30711,6 +30854,11 @@ "description": "operatorLogLevel is an intent based logging for the operator itself. It does not give fine grained control, but it is a simple way to manage coarse grained logging choices that operators have to interpret for themselves.\n\nValid values are: \"Normal\", \"Debug\", \"Trace\", \"TraceAll\". Defaults to \"Normal\".", "type": "string" }, + "proxy": { + "description": "proxy configures proxy settings for outbound connections made by the authentication stack. When set, it replaces the cluster-wide proxy (proxy.config.openshift.io/cluster) entirely for authentication — individual fields are not inherited from the cluster-wide configuration. When omitted, the cluster-wide proxy is used if configured; otherwise no proxy is used.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.AuthenticationProxyConfig" + }, "unsupportedConfigOverrides": { "description": "unsupportedConfigOverrides overrides the final configuration that was computed by the operator. Red Hat does not support the use of this field. Misuse of this field could lead to unexpected behavior or conflict with other configuration options. Seek guidance from the Red Hat support before using this field. Use of this property blocks cluster upgrades, it must be removed before upgrading your cluster.", "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension" @@ -30903,7 +31051,7 @@ "$ref": "#/definitions/com.github.openshift.api.operator.v1.AzureCSIDriverConfigSpec" }, "driverType": { - "description": "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere and omitted. Consumers should treat unknown values as a NO-OP.", + "description": "driverType indicates type of CSI driver for which the driverConfig is being applied to. Valid values are: AWS, Azure, GCP, IBMCloud, vSphere, SecretsStore and omitted. Consumers should treat unknown values as a NO-OP.", "type": "string", "default": "" }, @@ -30915,6 +31063,11 @@ "description": "ibmcloud is used to configure the IBM Cloud CSI driver.", "$ref": "#/definitions/com.github.openshift.api.operator.v1.IBMCloudCSIDriverConfigSpec" }, + "secretsStore": { + "description": "secretsStore is used to configure the Secrets Store CSI driver.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.SecretsStoreCSIDriverConfigSpec" + }, "vSphere": { "description": "vSphere is used to configure the vsphere CSI driver.", "$ref": "#/definitions/com.github.openshift.api.operator.v1.VSphereCSIDriverConfigSpec" @@ -30928,6 +31081,7 @@ "azure": "Azure", "gcp": "GCP", "ibmcloud": "IBMCloud", + "secretsStore": "SecretsStore", "vSphere": "VSphere" } } @@ -31963,6 +32117,17 @@ } } }, + "com.github.openshift.api.operator.v1.CustomSecretRotation": { + "description": "CustomSecretRotation holds configuration for custom secret rotation behavior.", + "type": "object", + "properties": { + "rotationPollIntervalSeconds": { + "description": "rotationPollIntervalSeconds is the minimum time in seconds between secret rotation attempts. The driver skips provider calls if less than this interval has elapsed since the last successful rotation. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", + "type": "integer", + "format": "int32" + } + } + }, "com.github.openshift.api.operator.v1.DNS": { "description": "DNS manages the CoreDNS component to provide a name resolution service for pods and services in the cluster.\n\nThis supports the DNS-based service discovery specification: https://github.com/kubernetes/dns/blob/master/docs/specification.md\n\nMore details: https://kubernetes.io/docs/tasks/administer-cluster/coredns\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "type": "object", @@ -34908,6 +35073,24 @@ } } }, + "com.github.openshift.api.operator.v1.ManagedTokenRequests": { + "description": "ManagedTokenRequests holds the configuration for operator-managed service account token requests.", + "type": "object", + "properties": { + "audiences": { + "description": "audiences specifies service account token audiences that kubelet will provide to the CSI driver during NodePublishVolume calls. These tokens enable workload identity federation (WIF) with cloud providers such as AWS, Azure, and GCP. When empty, the operator clears all tokenRequests from the CSIDriver object.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.SecretsStoreTokenRequest" + }, + "x-kubernetes-list-map-keys": [ + "audience" + ], + "x-kubernetes-list-type": "map" + } + } + }, "com.github.openshift.api.operator.v1.MyOperatorResource": { "description": "MyOperatorResource is an example operator configuration type\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", "type": "object", @@ -36627,6 +36810,92 @@ } } }, + "com.github.openshift.api.operator.v1.SecretsStoreCSIDriverConfigSpec": { + "description": "SecretsStoreCSIDriverConfigSpec defines properties that can be configured for the Secrets Store CSI driver.", + "type": "object", + "properties": { + "secretRotation": { + "description": "secretRotation controls automatic secret rotation behavior. When omitted, secret rotation is enabled with a default poll interval of 2 minutes.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.SecretsStoreSecretRotation" + }, + "tokenRequests": { + "description": "tokenRequests controls service account token configuration for workload identity federation (WIF) with cloud providers. When omitted, the operator preserves any existing tokenRequests already configured on the CSIDriver object without modification.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.SecretsStoreTokenRequests" + } + } + }, + "com.github.openshift.api.operator.v1.SecretsStoreSecretRotation": { + "description": "SecretsStoreSecretRotation configures the automatic secret rotation behavior for the Secrets Store CSI driver.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "custom": { + "description": "custom holds the custom rotation configuration. Only valid when type is \"Custom\".", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.CustomSecretRotation" + }, + "type": { + "description": "type determines the secret rotation behavior. When \"None\", secret rotation is disabled and secrets are only fetched at initial pod mount time. When \"Custom\", secret rotation is enabled with the configuration specified in the custom field.", + "type": "string" + } + }, + "x-kubernetes-unions": [ + { + "discriminator": "type", + "fields-to-discriminateBy": { + "custom": "Custom" + } + } + ] + }, + "com.github.openshift.api.operator.v1.SecretsStoreTokenRequest": { + "description": "SecretsStoreTokenRequest specifies a service account token audience configuration for workload identity federation (WIF) with the Secrets Store CSI driver.", + "type": "object", + "required": [ + "audience" + ], + "properties": { + "audience": { + "description": "audience is the intended audience of the service account token. An empty string means the issued token will use the kube-apiserver's default APIAudiences.", + "type": "string" + }, + "expirationSeconds": { + "description": "expirationSeconds is the requested duration of validity of the service account token. The token issuer may return a token with a different validity duration. When omitted, the token expiration is determined by the kube-apiserver. Must be at least 600 seconds (10 minutes) and no more than 315360000 seconds (~10 years).", + "type": "integer", + "format": "int32" + } + } + }, + "com.github.openshift.api.operator.v1.SecretsStoreTokenRequests": { + "description": "SecretsStoreTokenRequests configures how service account tokens are provided to the Secrets Store CSI driver for workload identity federation.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "managed": { + "description": "managed holds configuration for operator-managed tokenRequests. Only valid when type is \"Managed\".", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.ManagedTokenRequests" + }, + "type": { + "description": "type determines how the operator manages tokenRequests on the CSIDriver object. When \"Unmanaged\", existing tokenRequests on the CSIDriver are preserved and the managed field is not used. When \"Managed\", the operator sets tokenRequests from the audiences specified in the managed field, replacing any previously configured values. Once set to \"Managed\", type cannot be reverted back to \"Unmanaged\".", + "type": "string" + } + }, + "x-kubernetes-unions": [ + { + "discriminator": "type", + "fields-to-discriminateBy": { + "managed": "Managed" + } + } + ] + }, "com.github.openshift.api.operator.v1.Server": { "description": "Server defines the schema for a server that runs per instance of CoreDNS.", "type": "object", diff --git a/operator/v1/tests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml b/operator/v1/tests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml new file mode 100644 index 00000000000..a705845a831 --- /dev/null +++ b/operator/v1/tests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml @@ -0,0 +1,281 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "Authentication" +crdName: authentications.operator.openshift.io +featureGates: + - AuthenticationComponentProxy +tests: + onCreate: + - name: Should accept a valid proxy configuration with httpProxy only + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128" + expected: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + logLevel: Normal + operatorLogLevel: Normal + proxy: + httpProxy: "http://proxy.example.com:3128" + - name: Should accept a valid proxy configuration with httpsProxy only + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3129" + expected: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + logLevel: Normal + operatorLogLevel: Normal + proxy: + httpsProxy: "http://proxy.example.com:3129" + - name: Should accept a valid proxy configuration with both httpProxy and httpsProxy + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128" + httpsProxy: "http://proxy.example.com:3129" + expected: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + logLevel: Normal + operatorLogLevel: Normal + proxy: + httpProxy: "http://proxy.example.com:3128" + httpsProxy: "http://proxy.example.com:3129" + - name: Should accept a valid proxy configuration with noProxy + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3128" + noProxy: + - "idp.internal.example.com" + - ".corp.example.com" + expected: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + logLevel: Normal + operatorLogLevel: Normal + proxy: + httpsProxy: "http://proxy.example.com:3128" + noProxy: + - "idp.internal.example.com" + - ".corp.example.com" + - name: Should accept a valid proxy configuration with trustedCA + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3128" + trustedCA: + name: "proxy-ca-bundle" + expected: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + logLevel: Normal + operatorLogLevel: Normal + proxy: + httpsProxy: "http://proxy.example.com:3128" + trustedCA: + name: "proxy-ca-bundle" + - name: Should reject proxy with neither httpProxy nor httpsProxy + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + noProxy: + - "example.com" + expectedError: "at least one of httpProxy or httpsProxy must be specified" + - name: Should reject httpProxy that is not a valid URL + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "not-a-url" + expectedError: "httpProxy must be a valid URL" + - name: Should reject httpProxy without a hostname + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://:3128" + expectedError: "httpProxy must contain a hostname" + - name: Should reject httpProxy with invalid scheme + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "ftp://proxy.example.com:3128" + expectedError: "httpProxy must use http or https scheme" + - name: Should reject httpProxy with a path + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128/path" + expectedError: "httpProxy must not contain a path" + - name: Should reject httpProxy with query parameters + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128?key=value" + expectedError: "httpProxy must not contain query parameters" + - name: Should reject httpProxy with a fragment + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128#frag" + expectedError: "httpProxy must not contain a fragment" + - name: Should reject httpsProxy that is not a valid URL + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "not-a-url" + expectedError: "httpsProxy must be a valid URL" + - name: Should reject httpsProxy without a hostname + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://:3128" + expectedError: "httpsProxy must contain a hostname" + - name: Should reject httpsProxy with invalid scheme + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "ftp://proxy.example.com:3128" + expectedError: "httpsProxy must use http or https scheme" + - name: Should reject httpsProxy with a path + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3128/path" + expectedError: "httpsProxy must not contain a path" + - name: Should reject httpsProxy with query parameters + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3128?key=value" + expectedError: "httpsProxy must not contain query parameters" + - name: Should reject httpsProxy with a fragment + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpsProxy: "http://proxy.example.com:3128#frag" + expectedError: "httpsProxy must not contain a fragment" + - name: Should reject duplicate noProxy entries + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128" + noProxy: + - "example.com" + - "example.com" + expectedError: "Duplicate value" + - name: Should reject empty noProxy entry + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128" + noProxy: + - "" + expectedError: "should be at least 1 chars long" + - name: Should reject empty noProxy list + initial: | + apiVersion: operator.openshift.io/v1 + kind: Authentication + metadata: + name: cluster + spec: + proxy: + httpProxy: "http://proxy.example.com:3128" + noProxy: [] + expectedError: "should have at least 1 items" diff --git a/operator/v1/types_authentication.go b/operator/v1/types_authentication.go index 4d0e9f6d682..55fc62a7915 100644 --- a/operator/v1/types_authentication.go +++ b/operator/v1/types_authentication.go @@ -33,6 +33,94 @@ type Authentication struct { type AuthenticationSpec struct { OperatorSpec `json:",inline"` + + // proxy configures proxy settings for outbound connections made + // by the authentication stack. When set, it replaces the + // cluster-wide proxy (proxy.config.openshift.io/cluster) + // entirely for authentication — individual fields are not + // inherited from the cluster-wide configuration. When omitted, + // the cluster-wide proxy is used if configured; otherwise no + // proxy is used. + // +openshift:enable:FeatureGate=AuthenticationComponentProxy + // +optional + Proxy AuthenticationProxyConfig `json:"proxy,omitzero"` +} + +// AuthenticationProxyConfig holds proxy configuration scoped to +// authentication components (the OAuth server and the cluster +// authentication operator). +// +kubebuilder:validation:MinProperties=1 +// +kubebuilder:validation:XValidation:rule="has(self.httpProxy) || has(self.httpsProxy)",message="at least one of httpProxy or httpsProxy must be specified" +type AuthenticationProxyConfig struct { + // httpProxy is the URL of the proxy for HTTP requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpProxy must not contain a fragment" + // +optional + HTTPProxy string `json:"httpProxy,omitempty"` + + // httpsProxy is the URL of the proxy for HTTPS requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpsProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpsProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpsProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpsProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpsProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpsProxy must not contain a fragment" + // +optional + HTTPSProxy string `json:"httpsProxy,omitempty"` + + // noProxy is a list of hostnames and/or CIDRs and/or IPs for which + // the proxy should not be used. Must contain at least one entry + // when set. Each entry must be between 1 and 253 characters long + // and at most 64 entries are allowed. Duplicate + // entries are not permitted. Entries that are not valid hostnames, + // CIDRs, or IPs are silently ignored. Cluster-internal defaults + // (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + // automatically and do not need to be included. + // +listType=set + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=64 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=253 + // +optional + NoProxy []string `json:"noProxy,omitempty"` + + // trustedCA is a reference to a ConfigMap in the openshift-config + // namespace containing a CA certificate bundle under the key + // "ca-bundle.crt". This bundle is appended to the system trust store + // used by authentication components for proxy TLS connections. + // When omitted, only the system trust store is used. + // +optional + TrustedCA AuthenticationConfigMapReference `json:"trustedCA,omitzero"` +} + +// AuthenticationConfigMapReference references a ConfigMap in the +// openshift-config namespace. +type AuthenticationConfigMapReference struct { + // name is the metadata.name of the referenced ConfigMap. + // Must be a valid DNS subdomain name (RFC 1123): at most 253 + // characters, only lowercase alphanumeric characters, '-' or + // '.', starting and ending with an alphanumeric character. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must be a valid DNS subdomain name: contain no more than 253 characters, contain only lowercase alphanumeric characters, '-' or '.', and start and end with an alphanumeric character" + // +required + Name string `json:"name,omitempty"` } type AuthenticationStatus struct { diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml index 3d5beb8c3c5..a1d80bd5d9d 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml index 9c6a6de7db2..9e8ba13fd55 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml index 196a05d6046..03b3daf02a1 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/operator/v1/zz_generated.deepcopy.go b/operator/v1/zz_generated.deepcopy.go index 0a6726b1998..3c244a9867e 100644 --- a/operator/v1/zz_generated.deepcopy.go +++ b/operator/v1/zz_generated.deepcopy.go @@ -285,6 +285,22 @@ func (in *Authentication) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationConfigMapReference) DeepCopyInto(out *AuthenticationConfigMapReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationConfigMapReference. +func (in *AuthenticationConfigMapReference) DeepCopy() *AuthenticationConfigMapReference { + if in == nil { + return nil + } + out := new(AuthenticationConfigMapReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationList) DeepCopyInto(out *AuthenticationList) { *out = *in @@ -318,10 +334,33 @@ func (in *AuthenticationList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationProxyConfig) DeepCopyInto(out *AuthenticationProxyConfig) { + *out = *in + if in.NoProxy != nil { + in, out := &in.NoProxy, &out.NoProxy + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.TrustedCA = in.TrustedCA + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationProxyConfig. +func (in *AuthenticationProxyConfig) DeepCopy() *AuthenticationProxyConfig { + if in == nil { + return nil + } + out := new(AuthenticationProxyConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) + in.Proxy.DeepCopyInto(&out.Proxy) return } diff --git a/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/operator/v1/zz_generated.featuregated-crd-manifests.yaml index 9edb02ec6e3..d01265c3f7b 100644 --- a/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -6,6 +6,7 @@ authentications.operator.openshift.io: Capability: "" Category: "" FeatureGates: + - AuthenticationComponentProxy - KMSEncryption FilenameOperatorName: authentication FilenameOperatorOrdering: "01" diff --git a/operator/v1/zz_generated.featuregated-crd-manifests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml b/operator/v1/zz_generated.featuregated-crd-manifests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml new file mode 100644 index 00000000000..f5f0c49aeef --- /dev/null +++ b/operator/v1/zz_generated.featuregated-crd-manifests/authentications.operator.openshift.io/AuthenticationComponentProxy.yaml @@ -0,0 +1,328 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/475 + api.openshift.io/filename-cvo-runlevel: "0000_50" + api.openshift.io/filename-operator: authentication + api.openshift.io/filename-ordering: "01" + feature-gate.release.openshift.io/AuthenticationComponentProxy: "true" + include.release.openshift.io/self-managed-high-availability: "true" + name: authentications.operator.openshift.io +spec: + group: operator.openshift.io + names: + kind: Authentication + listKind: AuthenticationList + plural: authentications + singular: authentication + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Authentication provides information to configure an operator to manage authentication. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + logLevel: + default: Normal + description: |- + logLevel is an intent based logging for an overall component. It does not give fine grained control, but it is a + simple way to manage coarse grained logging choices that operators have to interpret for their operands. + + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Unmanaged|Force|Removed)$ + type: string + observedConfig: + description: |- + observedConfig holds a sparse config that controller has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + default: Normal + description: |- + operatorLogLevel is an intent based logging for the operator itself. It does not give fine grained control, but it is a + simple way to manage coarse grained logging choices that operators have to interpret for themselves. + + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) + unsupportedConfigOverrides: + description: |- + unsupportedConfigOverrides overrides the final configuration that was computed by the operator. + Red Hat does not support the use of this field. + Misuse of this field could lead to unexpected behavior or conflict with other configuration options. + Seek guidance from the Red Hat support before using this field. + Use of this property blocks cluster upgrades, it must be removed before upgrading your cluster. + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + status: + properties: + conditions: + description: conditions is a list of conditions and their status + items: + description: OperatorCondition is just the standard condition fields. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + type: string + reason: + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + generations: + description: generations are used to determine when an item needs + to be reconciled or has changed in a way that needs a reaction. + items: + description: GenerationStatus keeps track of the generation for + a given resource so that decisions about forced updates can be + made. + properties: + group: + description: group is the group of the thing you're tracking + type: string + hash: + description: hash is an optional field set for resources without + generation that are content sensitive like secrets and configmaps + type: string + lastGeneration: + description: lastGeneration is the last generation of the workload + controller involved + format: int64 + type: integer + name: + description: name is the name of the thing you're tracking + type: string + namespace: + description: namespace is where the thing you're tracking is + type: string + resource: + description: resource is the resource type of the thing you're + tracking + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + - namespace + - name + x-kubernetes-list-type: map + latestAvailableRevision: + description: latestAvailableRevision is the deploymentID of the most + recent deployment + format: int32 + type: integer + x-kubernetes-validations: + - message: must only increase + rule: self >= oldSelf + oauthAPIServer: + description: oauthAPIServer holds status specific only to oauth-apiserver + properties: + latestAvailableRevision: + description: |- + latestAvailableRevision is the latest revision used as suffix of revisioned + secrets like encryption-config. A new revision causes a new deployment of pods. + format: int32 + minimum: 0 + type: integer + type: object + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + readyReplicas: + description: readyReplicas indicates how many replicas are ready and + at the desired state + format: int32 + type: integer + version: + description: version is the level this availability applies to + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/operator/v1/zz_generated.model_name.go b/operator/v1/zz_generated.model_name.go index c6a047d2ceb..271665a7eca 100644 --- a/operator/v1/zz_generated.model_name.go +++ b/operator/v1/zz_generated.model_name.go @@ -65,11 +65,21 @@ func (in Authentication) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.Authentication" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationConfigMapReference) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationConfigMapReference" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationList) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationList" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationProxyConfig) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationProxyConfig" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationSpec) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationSpec" diff --git a/operator/v1/zz_generated.swagger_doc_generated.go b/operator/v1/zz_generated.swagger_doc_generated.go index a79189ffc20..52efc49bb49 100644 --- a/operator/v1/zz_generated.swagger_doc_generated.go +++ b/operator/v1/zz_generated.swagger_doc_generated.go @@ -118,6 +118,15 @@ func (Authentication) SwaggerDoc() map[string]string { return map_Authentication } +var map_AuthenticationConfigMapReference = map[string]string{ + "": "AuthenticationConfigMapReference references a ConfigMap in the openshift-config namespace.", + "name": "name is the metadata.name of the referenced ConfigMap. Must be a valid DNS subdomain name (RFC 1123): at most 253 characters, only lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character.", +} + +func (AuthenticationConfigMapReference) SwaggerDoc() map[string]string { + return map_AuthenticationConfigMapReference +} + var map_AuthenticationList = map[string]string{ "": "AuthenticationList is a collection of items\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -127,6 +136,26 @@ func (AuthenticationList) SwaggerDoc() map[string]string { return map_AuthenticationList } +var map_AuthenticationProxyConfig = map[string]string{ + "": "AuthenticationProxyConfig holds proxy configuration scoped to authentication components (the OAuth server and the cluster authentication operator).", + "httpProxy": "httpProxy is the URL of the proxy for HTTP requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "httpsProxy": "httpsProxy is the URL of the proxy for HTTPS requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "noProxy": "noProxy is a list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. Must contain at least one entry when set. Each entry must be between 1 and 253 characters long and at most 64 entries are allowed. Duplicate entries are not permitted. Entries that are not valid hostnames, CIDRs, or IPs are silently ignored. Cluster-internal defaults (.cluster.local, .svc, 127.0.0.1, localhost) are always appended automatically and do not need to be included.", + "trustedCA": "trustedCA is a reference to a ConfigMap in the openshift-config namespace containing a CA certificate bundle under the key \"ca-bundle.crt\". This bundle is appended to the system trust store used by authentication components for proxy TLS connections. When omitted, only the system trust store is used.", +} + +func (AuthenticationProxyConfig) SwaggerDoc() map[string]string { + return map_AuthenticationProxyConfig +} + +var map_AuthenticationSpec = map[string]string{ + "proxy": "proxy configures proxy settings for outbound connections made by the authentication stack. When set, it replaces the cluster-wide proxy (proxy.config.openshift.io/cluster) entirely for authentication — individual fields are not inherited from the cluster-wide configuration. When omitted, the cluster-wide proxy is used if configured; otherwise no proxy is used.", +} + +func (AuthenticationSpec) SwaggerDoc() map[string]string { + return map_AuthenticationSpec +} + var map_AuthenticationStatus = map[string]string{ "oauthAPIServer": "oauthAPIServer holds status specific only to oauth-apiserver", } diff --git a/payload-manifests/crds/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml index 3d5beb8c3c5..a1d80bd5d9d 100644 --- a/payload-manifests/crds/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/payload-manifests/crds/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml index 9c6a6de7db2..9e8ba13fd55 100644 --- a/payload-manifests/crds/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/payload-manifests/crds/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml index 196a05d6046..03b3daf02a1 100644 --- a/payload-manifests/crds/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml index 08b45736271..27e73099738 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml @@ -29,6 +29,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml index 837a70a6f1d..56a3fa3b4f3 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-DevPreviewNoUpgrade.yaml @@ -16,6 +16,9 @@ "featureGates": [ { "disabled": [ + { + "name": "AuthenticationComponentProxy" + }, { "name": "ClientsAllowCBOR" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml index 43362b0d99e..97f54db7edf 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml @@ -31,6 +31,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml index 3730bbad887..66bf02a1dfc 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-TechPreviewNoUpgrade.yaml @@ -16,6 +16,9 @@ "featureGates": [ { "disabled": [ + { + "name": "AuthenticationComponentProxy" + }, { "name": "ClientsAllowCBOR" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml index 8f0f6d3a9d8..ae85dba6d34 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml @@ -29,6 +29,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml index d4ceb6cad5d..5dde0ac3933 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-DevPreviewNoUpgrade.yaml @@ -72,6 +72,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml index 01798d66dfa..f5156302c5c 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml @@ -31,6 +31,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml index 2f63db059a0..061d5df3ed5 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-TechPreviewNoUpgrade.yaml @@ -102,6 +102,9 @@ { "name": "AdditionalStorageConfig" }, + { + "name": "AuthenticationComponentProxy" + }, { "name": "AutomatedEtcdBackup" },