From 8ce50eec051ceb529616f630e0096cc5aa3151db Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 13:29:55 +0200
Subject: [PATCH 1/8] feat(azure): add Swift to AzurePrivateType enum and
AzureSwiftSpec struct
Add Swift as a new AzurePrivateType enum value and introduce
AzureSwiftSpec struct with topology and pod network instance fields.
Add PublicEndpointExposed condition type for shared ingress
convergence tracking.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
api/hypershift/v1beta1/azure.go | 44 +++++++++++++++++--
.../v1beta1/hostedcluster_conditions.go | 13 ++++++
2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/api/hypershift/v1beta1/azure.go b/api/hypershift/v1beta1/azure.go
index 76c9a3efbab..c95773e13bd 100644
--- a/api/hypershift/v1beta1/azure.go
+++ b/api/hypershift/v1beta1/azure.go
@@ -653,7 +653,7 @@ const (
// AzurePrivateType specifies the type of private connectivity mechanism used for the Azure
// hosted cluster's API server. This acts as the discriminator for the AzurePrivateSpec union.
//
-// +kubebuilder:validation:Enum=PrivateLink
+// +kubebuilder:validation:Enum=PrivateLink;Swift
type AzurePrivateType string
const (
@@ -661,23 +661,30 @@ const (
// In this mode, the operator creates a Private Link Service backed by the management cluster's
// internal load balancer, and a Private Endpoint in the guest VNet for private API server access.
AzurePrivateTypePrivateLink AzurePrivateType = "PrivateLink"
+
+ // AzurePrivateTypeSwift specifies private connectivity using Azure Swift pod networking.
+ // In this mode, Azure Swift assigns a private IP from the customer VNet directly
+ // to the hosted cluster's router pods, providing private API server access without a
+ // separate Private Link Service. This is used by ARO HCP managed clusters.
+ AzurePrivateTypeSwift AzurePrivateType = "Swift"
)
// AzurePrivateSpec configures private connectivity to an Azure hosted cluster's API server.
// It is a discriminated union keyed on the type field, which selects the private connectivity
-// mechanism. Currently only PrivateLink is supported; additional mechanisms (e.g., Swift) may
-// be added in the future.
+// mechanism.
//
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.type) || self.type == oldSelf.type",message="type is immutable"
// +kubebuilder:validation:XValidation:rule="self.type == 'PrivateLink' ? has(self.privateLink) : !has(self.privateLink)",message="privateLink is required when type is PrivateLink, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.type == 'Swift' ? has(self.swift) : !has(self.swift)",message="swift is required when type is Swift, and forbidden otherwise"
// +union
type AzurePrivateSpec struct {
// type specifies the private connectivity mechanism used for the hosted cluster's API server.
// "PrivateLink" selects Azure Private Link Service for private API server access.
+ // "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
// This field is immutable once set.
//
// +unionDiscriminator
// +required
- // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="type is immutable"
Type AzurePrivateType `json:"type,omitempty"`
// privateLink configures Azure Private Link Service for private API server access.
@@ -686,6 +693,15 @@ type AzurePrivateSpec struct {
// +optional
// +unionMember
PrivateLink AzurePrivateLinkSpec `json:"privateLink,omitzero"`
+
+ // swift configures Azure Swift pod networking for private API server access.
+ // Swift networking requires the management cluster to be pre-configured with
+ // Azure Swift support; this is not provisioned by HyperShift automatically.
+ // This field is required when type is "Swift" and must not be set otherwise.
+ //
+ // +optional
+ // +unionMember
+ Swift AzureSwiftSpec `json:"swift,omitzero"`
}
// AzurePrivateLinkSpec configures Azure Private Link Service connectivity.
@@ -716,6 +732,26 @@ type AzurePrivateLinkSpec struct {
AdditionalAllowedSubscriptions []AzureSubscriptionID `json:"additionalAllowedSubscriptions,omitempty"`
}
+// AzureSwiftSpec configures Azure Swift pod networking for private API server access.
+// Swift assigns a private IP from the customer VNet directly to the hosted cluster's
+// router pods, providing private connectivity without a separate Private Link Service.
+//
+// +kubebuilder:validation:XValidation:rule="self.podNetworkInstance == oldSelf.podNetworkInstance",message="podNetworkInstance is immutable"
+type AzureSwiftSpec struct {
+ // podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ // hosted control plane namespace. This resource configures Azure Swift pod networking
+ // for private connectivity to the hosted cluster's router pods.
+ // The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ // alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ // This field is immutable once set.
+ //
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:XValidation:rule="self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="podNetworkInstance must be a valid DNS label: lowercase alphanumeric characters or hyphens, must start and end with an alphanumeric character"
+ PodNetworkInstance string `json:"podNetworkInstance,omitempty"`
+}
+
// ControlPlaneManagedIdentities contains the managed identities on the HCP control plane needing to authenticate with
// Azure's API.
type ControlPlaneManagedIdentities struct {
diff --git a/api/hypershift/v1beta1/hostedcluster_conditions.go b/api/hypershift/v1beta1/hostedcluster_conditions.go
index 665eeb4ef66..9fda11a60a2 100644
--- a/api/hypershift/v1beta1/hostedcluster_conditions.go
+++ b/api/hypershift/v1beta1/hostedcluster_conditions.go
@@ -252,6 +252,19 @@ const (
// **False / AutoNodeProgressing** means AutoNode is being enabled or disabled — the operation is in progress.
// **False / AutoNodeNotConfigured** means AutoNode is not configured in the spec and all Karpenter components have been removed.
AutoNodeEnabled ConditionType = "AutoNodeEnabled"
+
+ // PublicEndpointExposed indicates whether public API server endpoints are
+ // currently configured and exposed for this cluster via the management
+ // cluster's shared ingress. Status reflects observed state: True means
+ // public endpoints are reachable, False means they are not.
+ PublicEndpointExposed ConditionType = "PublicEndpointExposed"
+)
+
+// Reasons for PublicEndpointExposed condition.
+const (
+ PublicEndpointSharedIngressConfiguredReason = "SharedIngressConfigured"
+ PublicEndpointTopologyPrivateReason = "TopologyPrivate"
+ PublicEndpointConvergenceInProgressReason = "ConvergenceInProgress"
)
// Reasons.
From d3e14d63b2e575f9c42a6228bee3b3dd57b14fbd Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 13:30:01 +0200
Subject: [PATCH 2/8] chore(api): regenerate CRDs, deepcopy, apply
configurations, and docs
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../v1beta1/zz_generated.deepcopy.go | 16 +++++
.../AAA_ungated.yaml | 39 ++++++++++-
.../ClusterUpdateAcceptRisks.yaml | 39 ++++++++++-
.../ClusterVersionOperatorConfiguration.yaml | 39 ++++++++++-
.../ExternalOIDC.yaml | 39 ++++++++++-
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 39 ++++++++++-
.../ExternalOIDCWithUpstreamParity.yaml | 39 ++++++++++-
.../GCPPlatform.yaml | 39 ++++++++++-
.../HCPEtcdBackup.yaml | 39 ++++++++++-
...perShiftOnlyDynamicResourceAllocation.yaml | 39 ++++++++++-
.../ImageStreamImportMode.yaml | 39 ++++++++++-
.../KMSEncryptionProvider.yaml | 39 ++++++++++-
.../OpenStack.yaml | 39 ++++++++++-
.../TLSAdherence.yaml | 39 ++++++++++-
.../AAA_ungated.yaml | 39 ++++++++++-
.../ClusterUpdateAcceptRisks.yaml | 39 ++++++++++-
.../ClusterVersionOperatorConfiguration.yaml | 39 ++++++++++-
.../ExternalOIDC.yaml | 39 ++++++++++-
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 39 ++++++++++-
.../ExternalOIDCWithUpstreamParity.yaml | 39 ++++++++++-
.../GCPPlatform.yaml | 39 ++++++++++-
.../HCPEtcdBackup.yaml | 39 ++++++++++-
...perShiftOnlyDynamicResourceAllocation.yaml | 39 ++++++++++-
.../ImageStreamImportMode.yaml | 39 ++++++++++-
.../KMSEncryptionProvider.yaml | 39 ++++++++++-
.../OpenStack.yaml | 39 ++++++++++-
.../TLSAdherence.yaml | 39 ++++++++++-
.../hypershift/v1beta1/azureprivatespec.go | 9 +++
.../hypershift/v1beta1/azureswiftspec.go | 38 ++++++++++
client/applyconfiguration/utils.go | 2 +
...usters-Hypershift-CustomNoUpgrade.crd.yaml | 39 ++++++++++-
...hostedclusters-Hypershift-Default.crd.yaml | 39 ++++++++++-
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 39 ++++++++++-
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 39 ++++++++++-
...dcontrolplanes-Hypershift-Default.crd.yaml | 39 ++++++++++-
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 39 ++++++++++-
docs/content/reference/aggregated-docs.md | 69 ++++++++++++++++++-
docs/content/reference/api.md | 69 ++++++++++++++++++-
.../api/hypershift/v1beta1/azure.go | 44 ++++++++++--
.../v1beta1/hostedcluster_conditions.go | 13 ++++
.../v1beta1/zz_generated.deepcopy.go | 16 +++++
41 files changed, 1420 insertions(+), 104 deletions(-)
create mode 100644 client/applyconfiguration/hypershift/v1beta1/azureswiftspec.go
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index a3d882374d2..c022c3e918d 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -863,6 +863,7 @@ func (in *AzurePrivateLinkSpec) DeepCopy() *AzurePrivateLinkSpec {
func (in *AzurePrivateSpec) DeepCopyInto(out *AzurePrivateSpec) {
*out = *in
in.PrivateLink.DeepCopyInto(&out.PrivateLink)
+ out.Swift = in.Swift
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzurePrivateSpec.
@@ -892,6 +893,21 @@ func (in *AzureResourceManagedIdentities) DeepCopy() *AzureResourceManagedIdenti
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureSwiftSpec) DeepCopyInto(out *AzureSwiftSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureSwiftSpec.
+func (in *AzureSwiftSpec) DeepCopy() *AzureSwiftSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(AzureSwiftSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureVMImage) DeepCopyInto(out *AzureVMImage) {
*out = *in
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
index e5e928dc898..4ed2391e13e 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
@@ -5276,25 +5276,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 40083476fa4..9185fb00d93 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -5267,25 +5267,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 955788dbad9..2269797a21d 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -5287,25 +5287,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
index fe08c90b5c2..0a1a136fa30 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
@@ -5599,25 +5599,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 6afcef0d203..cebc53316ac 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -5739,25 +5739,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 9faf2cdb0f5..1270fd8cb1f 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -5730,25 +5730,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
index 990cee3aae3..f7170ecada7 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
@@ -5267,25 +5267,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
index abe0886f01f..fd458cb1f13 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -5332,25 +5332,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 76cee1f00bd..461ae7dc798 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -5289,25 +5289,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
index bf1e2c27397..f741a117e78 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -5285,25 +5285,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
index a1263ec4683..33c70e1bc31 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -5343,25 +5343,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
index 93eee39d119..bdb6610a924 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
@@ -5267,25 +5267,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
index 377f44044e1..517516cd2f4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/TLSAdherence.yaml
@@ -5307,25 +5307,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index 1d833e21ca6..7faf853bd17 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -5156,25 +5156,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 8194e7799d5..927f2b9ffc2 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -5147,25 +5147,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index ee97b0bf9ea..ad6e7742c0e 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -5167,25 +5167,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index 03882677840..1b9da7de525 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -5479,25 +5479,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 31cb9e39a95..3cd3503473b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -5619,25 +5619,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index dac1ead4844..9d7a73cb3bf 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -5610,25 +5610,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index a862e1dc02f..1527b355549 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -5147,25 +5147,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
index f8dc77d0c2e..36a11500968 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -5212,25 +5212,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 667923bb2e9..5ea38844b58 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -5169,25 +5169,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index 55a2555f888..9de4ad90ead 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -5165,25 +5165,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index 4dcb4e6c362..db3f3840a8c 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -5223,25 +5223,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index da6e7167b43..c3c0b64fcf2 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -5147,25 +5147,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
index 75d60b7d459..e52cbe485e1 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
@@ -5187,25 +5187,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/client/applyconfiguration/hypershift/v1beta1/azureprivatespec.go b/client/applyconfiguration/hypershift/v1beta1/azureprivatespec.go
index 3fe2eae5bc0..5d65112e28d 100644
--- a/client/applyconfiguration/hypershift/v1beta1/azureprivatespec.go
+++ b/client/applyconfiguration/hypershift/v1beta1/azureprivatespec.go
@@ -26,6 +26,7 @@ import (
type AzurePrivateSpecApplyConfiguration struct {
Type *hypershiftv1beta1.AzurePrivateType `json:"type,omitempty"`
PrivateLink *AzurePrivateLinkSpecApplyConfiguration `json:"privateLink,omitempty"`
+ Swift *AzureSwiftSpecApplyConfiguration `json:"swift,omitempty"`
}
// AzurePrivateSpecApplyConfiguration constructs a declarative configuration of the AzurePrivateSpec type for use with
@@ -49,3 +50,11 @@ func (b *AzurePrivateSpecApplyConfiguration) WithPrivateLink(value *AzurePrivate
b.PrivateLink = value
return b
}
+
+// WithSwift sets the Swift field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Swift field is set to the value of the last call.
+func (b *AzurePrivateSpecApplyConfiguration) WithSwift(value *AzureSwiftSpecApplyConfiguration) *AzurePrivateSpecApplyConfiguration {
+ b.Swift = value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/azureswiftspec.go b/client/applyconfiguration/hypershift/v1beta1/azureswiftspec.go
new file mode 100644
index 00000000000..d328964e02b
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/azureswiftspec.go
@@ -0,0 +1,38 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// AzureSwiftSpecApplyConfiguration represents a declarative configuration of the AzureSwiftSpec type for use
+// with apply.
+type AzureSwiftSpecApplyConfiguration struct {
+ PodNetworkInstance *string `json:"podNetworkInstance,omitempty"`
+}
+
+// AzureSwiftSpecApplyConfiguration constructs a declarative configuration of the AzureSwiftSpec type for use with
+// apply.
+func AzureSwiftSpec() *AzureSwiftSpecApplyConfiguration {
+ return &AzureSwiftSpecApplyConfiguration{}
+}
+
+// WithPodNetworkInstance sets the PodNetworkInstance field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the PodNetworkInstance field is set to the value of the last call.
+func (b *AzureSwiftSpecApplyConfiguration) WithPodNetworkInstance(value string) *AzureSwiftSpecApplyConfiguration {
+ b.PodNetworkInstance = &value
+ return b
+}
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index 6c7a8f85bb0..cee82f9177f 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -133,6 +133,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.AzurePrivateSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureResourceManagedIdentities"):
return &hypershiftv1beta1.AzureResourceManagedIdentitiesApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("AzureSwiftSpec"):
+ return &hypershiftv1beta1.AzureSwiftSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureVMImage"):
return &hypershiftv1beta1.AzureVMImageApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("AzureWorkloadIdentities"):
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
index 742c4609575..d406b89a759 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
@@ -6118,25 +6118,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
index b70562b4dbf..bbafc3f882a 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
@@ -5768,25 +5768,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
index c56f7d18bce..30d17382b0f 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -5989,25 +5989,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 8fed73ad00d..798d4f0664f 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -5998,25 +5998,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index ac2928451c8..5fd583a45ff 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -5648,25 +5648,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index a2f47dbfdca..25068f5cf7f 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -5869,25 +5869,58 @@ spec:
(e.g., /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{subnet})
rule: self.matches('^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft\\.Network/virtualNetworks/[^/]+/subnets/[^/]+$')
type: object
+ swift:
+ description: |-
+ swift configures Azure Swift pod networking for private API server access.
+ Swift networking requires the management cluster to be pre-configured with
+ Azure Swift support; this is not provisioned by HyperShift automatically.
+ This field is required when type is "Swift" and must not be set otherwise.
+ properties:
+ podNetworkInstance:
+ description: |-
+ podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ hosted control plane namespace. This resource configures Azure Swift pod networking
+ for private connectivity to the hosted cluster's router pods.
+ The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ This field is immutable once set.
+ maxLength: 63
+ minLength: 1
+ type: string
+ x-kubernetes-validations:
+ - message: 'podNetworkInstance must be a valid DNS
+ label: lowercase alphanumeric characters or hyphens,
+ must start and end with an alphanumeric character'
+ rule: self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')
+ required:
+ - podNetworkInstance
+ type: object
+ x-kubernetes-validations:
+ - message: podNetworkInstance is immutable
+ rule: self.podNetworkInstance == oldSelf.podNetworkInstance
type:
description: |-
type specifies the private connectivity mechanism used for the hosted cluster's API server.
"PrivateLink" selects Azure Private Link Service for private API server access.
+ "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
This field is immutable once set.
enum:
- PrivateLink
+ - Swift
type: string
- x-kubernetes-validations:
- - message: type is immutable
- rule: self == oldSelf
required:
- type
type: object
x-kubernetes-validations:
+ - message: type is immutable
+ rule: '!has(oldSelf.type) || self.type == oldSelf.type'
- message: privateLink is required when type is PrivateLink,
and forbidden otherwise
rule: 'self.type == ''PrivateLink'' ? has(self.privateLink)
: !has(self.privateLink)'
+ - message: swift is required when type is Swift, and forbidden
+ otherwise
+ rule: 'self.type == ''Swift'' ? has(self.swift) : !has(self.swift)'
resourceGroup:
default: default
description: |-
diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md
index e1e9658ac27..5d0ca2e0ee9 100644
--- a/docs/content/reference/aggregated-docs.md
+++ b/docs/content/reference/aggregated-docs.md
@@ -40066,8 +40066,7 @@ in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AzurePrivateSpec configures private connectivity to an Azure hosted cluster’s API server.
It is a discriminated union keyed on the type field, which selects the private connectivity
-mechanism. Currently only PrivateLink is supported; additional mechanisms (e.g., Swift) may
-be added in the future.
+mechanism.
AzureSwiftSpec configures Azure Swift pod networking for private API server access.
+Swift assigns a private IP from the customer VNet directly to the hosted cluster’s
+router pods, providing private connectivity without a separate Private Link Service.
+
+AzureSwiftSpec configures Azure Swift pod networking for private API server access.
+Swift assigns a private IP from the customer VNet directly to the hosted cluster’s
+router pods, providing private connectivity without a separate Private Link Service.
+
+"ReconciliationActive" |
ReconciliationActive indicates if reconciliation of the HostedCluster is
active or paused hostedCluster.spec.pausedUntil.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
index 76c9a3efbab..c95773e13bd 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/azure.go
@@ -653,7 +653,7 @@ const (
// AzurePrivateType specifies the type of private connectivity mechanism used for the Azure
// hosted cluster's API server. This acts as the discriminator for the AzurePrivateSpec union.
//
-// +kubebuilder:validation:Enum=PrivateLink
+// +kubebuilder:validation:Enum=PrivateLink;Swift
type AzurePrivateType string
const (
@@ -661,23 +661,30 @@ const (
// In this mode, the operator creates a Private Link Service backed by the management cluster's
// internal load balancer, and a Private Endpoint in the guest VNet for private API server access.
AzurePrivateTypePrivateLink AzurePrivateType = "PrivateLink"
+
+ // AzurePrivateTypeSwift specifies private connectivity using Azure Swift pod networking.
+ // In this mode, Azure Swift assigns a private IP from the customer VNet directly
+ // to the hosted cluster's router pods, providing private API server access without a
+ // separate Private Link Service. This is used by ARO HCP managed clusters.
+ AzurePrivateTypeSwift AzurePrivateType = "Swift"
)
// AzurePrivateSpec configures private connectivity to an Azure hosted cluster's API server.
// It is a discriminated union keyed on the type field, which selects the private connectivity
-// mechanism. Currently only PrivateLink is supported; additional mechanisms (e.g., Swift) may
-// be added in the future.
+// mechanism.
//
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.type) || self.type == oldSelf.type",message="type is immutable"
// +kubebuilder:validation:XValidation:rule="self.type == 'PrivateLink' ? has(self.privateLink) : !has(self.privateLink)",message="privateLink is required when type is PrivateLink, and forbidden otherwise"
+// +kubebuilder:validation:XValidation:rule="self.type == 'Swift' ? has(self.swift) : !has(self.swift)",message="swift is required when type is Swift, and forbidden otherwise"
// +union
type AzurePrivateSpec struct {
// type specifies the private connectivity mechanism used for the hosted cluster's API server.
// "PrivateLink" selects Azure Private Link Service for private API server access.
+ // "Swift" selects Azure Swift pod networking for private API server access, used by ARO HCP.
// This field is immutable once set.
//
// +unionDiscriminator
// +required
- // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="type is immutable"
Type AzurePrivateType `json:"type,omitempty"`
// privateLink configures Azure Private Link Service for private API server access.
@@ -686,6 +693,15 @@ type AzurePrivateSpec struct {
// +optional
// +unionMember
PrivateLink AzurePrivateLinkSpec `json:"privateLink,omitzero"`
+
+ // swift configures Azure Swift pod networking for private API server access.
+ // Swift networking requires the management cluster to be pre-configured with
+ // Azure Swift support; this is not provisioned by HyperShift automatically.
+ // This field is required when type is "Swift" and must not be set otherwise.
+ //
+ // +optional
+ // +unionMember
+ Swift AzureSwiftSpec `json:"swift,omitzero"`
}
// AzurePrivateLinkSpec configures Azure Private Link Service connectivity.
@@ -716,6 +732,26 @@ type AzurePrivateLinkSpec struct {
AdditionalAllowedSubscriptions []AzureSubscriptionID `json:"additionalAllowedSubscriptions,omitempty"`
}
+// AzureSwiftSpec configures Azure Swift pod networking for private API server access.
+// Swift assigns a private IP from the customer VNet directly to the hosted cluster's
+// router pods, providing private connectivity without a separate Private Link Service.
+//
+// +kubebuilder:validation:XValidation:rule="self.podNetworkInstance == oldSelf.podNetworkInstance",message="podNetworkInstance is immutable"
+type AzureSwiftSpec struct {
+ // podNetworkInstance is the name of a PodNetworkInstance custom resource in the
+ // hosted control plane namespace. This resource configures Azure Swift pod networking
+ // for private connectivity to the hosted cluster's router pods.
+ // The value must be a valid Kubernetes object name (RFC 1123 DNS label): lowercase
+ // alphanumeric characters or hyphens, must start and end with an alphanumeric character.
+ // This field is immutable once set.
+ //
+ // +required
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=63
+ // +kubebuilder:validation:XValidation:rule="self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="podNetworkInstance must be a valid DNS label: lowercase alphanumeric characters or hyphens, must start and end with an alphanumeric character"
+ PodNetworkInstance string `json:"podNetworkInstance,omitempty"`
+}
+
// ControlPlaneManagedIdentities contains the managed identities on the HCP control plane needing to authenticate with
// Azure's API.
type ControlPlaneManagedIdentities struct {
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
index 665eeb4ef66..9fda11a60a2 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hostedcluster_conditions.go
@@ -252,6 +252,19 @@ const (
// **False / AutoNodeProgressing** means AutoNode is being enabled or disabled — the operation is in progress.
// **False / AutoNodeNotConfigured** means AutoNode is not configured in the spec and all Karpenter components have been removed.
AutoNodeEnabled ConditionType = "AutoNodeEnabled"
+
+ // PublicEndpointExposed indicates whether public API server endpoints are
+ // currently configured and exposed for this cluster via the management
+ // cluster's shared ingress. Status reflects observed state: True means
+ // public endpoints are reachable, False means they are not.
+ PublicEndpointExposed ConditionType = "PublicEndpointExposed"
+)
+
+// Reasons for PublicEndpointExposed condition.
+const (
+ PublicEndpointSharedIngressConfiguredReason = "SharedIngressConfigured"
+ PublicEndpointTopologyPrivateReason = "TopologyPrivate"
+ PublicEndpointConvergenceInProgressReason = "ConvergenceInProgress"
)
// Reasons.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
index a3d882374d2..c022c3e918d 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -863,6 +863,7 @@ func (in *AzurePrivateLinkSpec) DeepCopy() *AzurePrivateLinkSpec {
func (in *AzurePrivateSpec) DeepCopyInto(out *AzurePrivateSpec) {
*out = *in
in.PrivateLink.DeepCopyInto(&out.PrivateLink)
+ out.Swift = in.Swift
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzurePrivateSpec.
@@ -892,6 +893,21 @@ func (in *AzureResourceManagedIdentities) DeepCopy() *AzureResourceManagedIdenti
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureSwiftSpec) DeepCopyInto(out *AzureSwiftSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureSwiftSpec.
+func (in *AzureSwiftSpec) DeepCopy() *AzureSwiftSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(AzureSwiftSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureVMImage) DeepCopyInto(out *AzureVMImage) {
*out = *in
From 0bfc62c0c99707579502d93dba7c380d417b2f9a Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 13:30:12 +0200
Subject: [PATCH 3/8] feat(azure): add API-driven Swift networking and shared
ingress helpers
Add per-cluster helper functions that derive topology behavior from
the Topology and Private API fields instead of isAroHCP() env-var checks:
- UseSwiftNetworkingHCP/HC: checks Private.Type == Swift with legacy
annotation fallback for unmigrated clusters
- UseSharedIngressHCP/HC: UseSwiftNetworking && IsPublic, with env-var
fallback for ARO HCP without Swift API fields (e.g. CI)
- SwiftPodNetworkInstanceHCP: API field first, annotation fallback
- IsAroHCPByHCP/HC: checks ManagedIdentities auth type as definitive
per-cluster ARO HCP indicator, decoupled from Swift detection
Update IsPrivateHCP/HC with Phase 1 fallback for Topology="" + Swift.
Update LabelHCPRoutes to use UseSharedIngress || UseSwiftNetworking.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
support/azureutil/azureutil.go | 17 ++++-
support/netutil/visibility.go | 117 ++++++++++++++++++++++++++++-----
2 files changed, 117 insertions(+), 17 deletions(-)
diff --git a/support/azureutil/azureutil.go b/support/azureutil/azureutil.go
index 56dbbcac1b3..7a6daa1809c 100644
--- a/support/azureutil/azureutil.go
+++ b/support/azureutil/azureutil.go
@@ -11,6 +11,7 @@ import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
"github.com/openshift/hypershift/support/config"
+ "github.com/openshift/hypershift/support/netutil"
"github.com/openshift/hypershift/support/upsert"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
@@ -260,11 +261,25 @@ func IsPrivateKeyVault(hcp *hyperv1.HostedControlPlane) bool {
return hcp.Spec.SecretEncryption.KMS.Azure.KeyVaultAccess == hyperv1.AzureKeyVaultPrivate
}
-// IsAroHCP returns true if the managed service environment variable is set to ARO-HCP
+// IsAroHCP returns true if the managed service environment variable is set to ARO-HCP.
+// Use this only for management-cluster-level decisions where no HC/HCP context is available.
+// For per-cluster decisions, use IsAroHCPByHCP or IsAroHCPByHC instead.
func IsAroHCP() bool {
return os.Getenv("MANAGED_SERVICE") == hyperv1.AroHCP
}
+// IsAroHCPByHCP returns true when this HCP belongs to an ARO-managed cluster.
+// Delegates to netutil.IsAroHCPByHCP — defined there to avoid circular imports
+// with UseSharedIngressHCP.
+func IsAroHCPByHCP(hcp *hyperv1.HostedControlPlane) bool {
+ return netutil.IsAroHCPByHCP(hcp)
+}
+
+// IsAroHCPByHC returns true when this HostedCluster belongs to an ARO-managed cluster.
+func IsAroHCPByHC(hc *hyperv1.HostedCluster) bool {
+ return netutil.IsAroHCPByHC(hc)
+}
+
// IsSelfManagedAzure returns true when the platform is Azure and the managed service is not ARO-HCP
func IsSelfManagedAzure(platform hyperv1.PlatformType) bool {
return platform == hyperv1.AzurePlatform && !IsAroHCP()
diff --git a/support/netutil/visibility.go b/support/netutil/visibility.go
index ddaa41ef337..0cf53e96f6a 100644
--- a/support/netutil/visibility.go
+++ b/support/netutil/visibility.go
@@ -5,6 +5,7 @@ import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ "k8s.io/klog/v2"
"k8s.io/utils/ptr"
)
@@ -14,25 +15,110 @@ func isAroHCP() bool {
return os.Getenv(managedServiceEnvVar) == hyperv1.AroHCP
}
-func IsPrivateHCP(hcp *hyperv1.HostedControlPlane) bool {
- // ARO always have swift enabled.
- // We still check the annotation to keep CI working.
- // TODO(alberto): Remove this once CI has swift enabled.
+// UseSwiftNetworkingHCP returns true when the HCP uses Azure Swift pod networking.
+// Checks the Private.Type API field first; falls back to env var + annotation
+// for unmigrated clusters during the Phase 1 migration window.
+func UseSwiftNetworkingHCP(hcp *hyperv1.HostedControlPlane) bool {
+ if hcp.Spec.Platform.Type != hyperv1.AzurePlatform {
+ return false
+ }
+ azure := ptr.Deref(hcp.Spec.Platform.Azure, hyperv1.AzurePlatformSpec{})
+ if azure.Private.Type == hyperv1.AzurePrivateTypeSwift {
+ return true
+ }
if isAroHCP() && hcp.Annotations[hyperv1.SwiftPodNetworkInstanceAnnotation] != "" {
+ klog.V(2).Info("Using legacy annotation fallback for Swift networking detection on HostedControlPlane", "namespace", hcp.Namespace, "name", hcp.Name)
return true
}
+ return false
+}
+
+// UseSwiftNetworkingHC returns true when the HostedCluster uses Azure Swift pod networking.
+func UseSwiftNetworkingHC(hc *hyperv1.HostedCluster) bool {
+ if hc.Spec.Platform.Type != hyperv1.AzurePlatform {
+ return false
+ }
+ azure := ptr.Deref(hc.Spec.Platform.Azure, hyperv1.AzurePlatformSpec{})
+ if azure.Private.Type == hyperv1.AzurePrivateTypeSwift {
+ return true
+ }
+ if isAroHCP() && hc.Annotations[hyperv1.SwiftPodNetworkInstanceAnnotation] != "" {
+ klog.V(2).Info("Using legacy annotation fallback for Swift networking detection on HostedCluster", "namespace", hc.Namespace, "name", hc.Name)
+ return true
+ }
+ return false
+}
+
+// IsAroHCPByHCP returns true when this HCP belongs to an ARO-managed cluster.
+// Checks AzureAuthenticationConfigType == ManagedIdentities as the per-cluster
+// API indicator. Falls back to the MANAGED_SERVICE env var when the Azure spec
+// is nil (unmigrated clusters during Phase 1).
+func IsAroHCPByHCP(hcp *hyperv1.HostedControlPlane) bool {
+ if hcp.Spec.Platform.Type != hyperv1.AzurePlatform {
+ return false
+ }
+ azure := hcp.Spec.Platform.Azure
+ if azure != nil {
+ return azure.AzureAuthenticationConfig.AzureAuthenticationConfigType == hyperv1.AzureAuthenticationTypeManagedIdentities
+ }
+ return isAroHCP()
+}
+
+// IsAroHCPByHC returns true when this HostedCluster belongs to an ARO-managed cluster.
+func IsAroHCPByHC(hc *hyperv1.HostedCluster) bool {
+ if hc.Spec.Platform.Type != hyperv1.AzurePlatform {
+ return false
+ }
+ azure := hc.Spec.Platform.Azure
+ if azure != nil {
+ return azure.AzureAuthenticationConfig.AzureAuthenticationConfigType == hyperv1.AzureAuthenticationTypeManagedIdentities
+ }
+ return isAroHCP()
+}
+
+// UseSharedIngressHCP returns true when this specific HCP should use the
+// management cluster's shared ingress (HAProxy) for public endpoints.
+// IsAroHCPByHCP includes an env var fallback for unmigrated clusters.
+func UseSharedIngressHCP(hcp *hyperv1.HostedControlPlane) bool {
+ return IsAroHCPByHCP(hcp) && IsPublicHCP(hcp)
+}
+
+// UseSharedIngressHC returns true when this specific HostedCluster should use
+// the management cluster's shared ingress for public endpoints.
+func UseSharedIngressHC(hc *hyperv1.HostedCluster) bool {
+ return IsAroHCPByHC(hc) && IsPublicHC(hc)
+}
+
+// SwiftPodNetworkInstanceHCP returns the Swift pod network instance name for
+// the HCP. Checks the API field first; falls back to the annotation for
+// unmigrated clusters.
+func SwiftPodNetworkInstanceHCP(hcp *hyperv1.HostedControlPlane) string {
+ if hcp.Spec.Platform.Type != hyperv1.AzurePlatform {
+ return ""
+ }
+ azure := ptr.Deref(hcp.Spec.Platform.Azure, hyperv1.AzurePlatformSpec{})
+ if azure.Private.Type == hyperv1.AzurePrivateTypeSwift {
+ return azure.Private.Swift.PodNetworkInstance
+ }
+ return hcp.Annotations[hyperv1.SwiftPodNetworkInstanceAnnotation]
+}
+
+func IsPrivateHCP(hcp *hyperv1.HostedControlPlane) bool {
if hcp.Spec.Platform.Type == hyperv1.AWSPlatform {
access := ptr.Deref(hcp.Spec.Platform.AWS, hyperv1.AWSPlatformSpec{}).EndpointAccess
return access == hyperv1.PublicAndPrivate || access == hyperv1.Private
}
-
if hcp.Spec.Platform.Type == hyperv1.GCPPlatform {
access := ptr.Deref(hcp.Spec.Platform.GCP, hyperv1.GCPPlatformSpec{}).EndpointAccess
return access == hyperv1.GCPEndpointAccessPublicAndPrivate || access == hyperv1.GCPEndpointAccessPrivate
}
if hcp.Spec.Platform.Type == hyperv1.AzurePlatform {
topology := ptr.Deref(hcp.Spec.Platform.Azure, hyperv1.AzurePlatformSpec{}).Topology
- return topology == hyperv1.AzureTopologyPublicAndPrivate || topology == hyperv1.AzureTopologyPrivate
+ if topology != "" {
+ return topology == hyperv1.AzureTopologyPublicAndPrivate || topology == hyperv1.AzureTopologyPrivate
+ }
+ // Phase 1 fallback: unmigrated clusters with empty topology
+ return UseSwiftNetworkingHCP(hcp)
}
return false
}
@@ -54,12 +140,6 @@ func IsPublicHCP(hcp *hyperv1.HostedControlPlane) bool {
}
func IsPrivateHC(hc *hyperv1.HostedCluster) bool {
- // ARO always have swift enabled.
- // We still check the annotation to keep CI working.
- // TODO(alberto): Remove this once CI has swift enabled.
- if isAroHCP() && hc.Annotations[hyperv1.SwiftPodNetworkInstanceAnnotation] != "" {
- return true
- }
if hc.Spec.Platform.Type == hyperv1.AWSPlatform {
access := ptr.Deref(hc.Spec.Platform.AWS, hyperv1.AWSPlatformSpec{}).EndpointAccess
return access == hyperv1.PublicAndPrivate || access == hyperv1.Private
@@ -70,7 +150,11 @@ func IsPrivateHC(hc *hyperv1.HostedCluster) bool {
}
if hc.Spec.Platform.Type == hyperv1.AzurePlatform {
topology := ptr.Deref(hc.Spec.Platform.Azure, hyperv1.AzurePlatformSpec{}).Topology
- return topology == hyperv1.AzureTopologyPublicAndPrivate || topology == hyperv1.AzureTopologyPrivate
+ if topology != "" {
+ return topology == hyperv1.AzureTopologyPublicAndPrivate || topology == hyperv1.AzureTopologyPrivate
+ }
+ // Phase 1 fallback: unmigrated clusters with empty topology
+ return UseSwiftNetworkingHC(hc)
}
return false
}
@@ -148,9 +232,10 @@ func IsPublicHC(hc *hyperv1.HostedCluster) bool {
// Returns true when routes should be labeled for HCP router; false when routes should
// use the management cluster router.
func LabelHCPRoutes(hcp *hyperv1.HostedControlPlane) bool {
- // When shared ingress is active (e.g., ARO HCP), all routes must be labeled
- // so the SharedIngressReconciler can discover and admit them.
- if isAroHCP() {
+ // When shared ingress or Swift networking is active, all routes must be
+ // labeled so the SharedIngressReconciler can discover them and the HCP
+ // router can serve them.
+ if UseSharedIngressHCP(hcp) || UseSwiftNetworkingHCP(hcp) {
return true
}
From 129a9811e6d229e6b775ba47a6898617df7fd86c Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 13:30:28 +0200
Subject: [PATCH 4/8] refactor(cpo): replace isAroHCP/UseSharedIngress with
API-driven helpers
Replace azureutil.IsAroHCP() env-var checks with API-driven per-cluster
helpers across all CPO controllers:
- v2 components: CNO, CCM, storage, registry operator, ingress operator
predicates and adapt functions now use IsAroHCPByHCP(cpContext.HCP)
- KAS, CPO deployment, router config adapt functions
- Router deployment: SwiftPodNetworkInstanceHCP instead of annotation read
- UseHCPRouter: UseSwiftNetworkingHCP for Swift routing, with
UseSharedIngressHCP guard for shared ingress clusters
- reconcileHCPRouterServices: UseSwiftNetworkingHCP for ClusterIP vs LB
- reconcileExternalRouterServiceStatus: UseSharedIngressHCP
- reconcileAPIServerServiceStatus: UseSharedIngressHCP
- KAS healthcheck: UseSharedIngressHCP
- HCCO credential and platform resource reconciliation
- verifyResourceGroupLocationsMatch: reverted to IsAroHCP() env var
(management-cluster-level check, not per-cluster)
Management-cluster-level calls in main.go are intentionally kept.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../hostedcontrolplane_controller.go | 2 +-
.../controllers/hostedcontrolplane/infra/infra.go | 15 +++++++--------
.../hostedcontrolplane/ingress/router.go | 4 ++--
.../hostedcontrolplane/kas/healthcheck.go | 5 +++--
.../controllers/hostedcontrolplane/kas/service.go | 2 +-
.../cloud_controller_manager/azure/component.go | 4 ++--
.../v2/cloud_controller_manager/azure/config.go | 10 +++++-----
.../cloud_controller_manager/azure/deployment.go | 6 +++---
.../hostedcontrolplane/v2/cno/component.go | 2 +-
.../hostedcontrolplane/v2/cno/deployment.go | 2 +-
.../v2/controlplaneoperator/deployment.go | 4 ++--
.../v2/controlplaneoperator/role.go | 2 +-
.../v2/ingressoperator/component.go | 2 +-
.../v2/ingressoperator/deployment.go | 2 +-
.../hostedcontrolplane/v2/kas/component.go | 2 +-
.../hostedcontrolplane/v2/kas/deployment.go | 2 +-
.../v2/registryoperator/component.go | 2 +-
.../v2/registryoperator/deployment.go | 2 +-
.../hostedcontrolplane/v2/router/config.go | 2 +-
.../hostedcontrolplane/v2/router/deployment.go | 6 +++---
.../hostedcontrolplane/v2/router/util/util.go | 10 ++++------
.../hostedcontrolplane/v2/storage/azure.go | 12 ++++++------
.../hostedcontrolplane/v2/storage/component.go | 2 +-
.../hostedcontrolplane/v2/storage/deployment.go | 2 +-
.../controllers/resources/resources.go | 8 ++++----
25 files changed, 55 insertions(+), 57 deletions(-)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
index 9337ae39d11..23f391db605 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
@@ -3029,7 +3029,7 @@ func (r *HostedControlPlaneReconciler) validateAzureKMSConfig(ctx context.Contex
}
azureKmsSpec := hcp.Spec.SecretEncryption.KMS.Azure
- if hyperazureutil.IsAroHCP() {
+ if hyperazureutil.IsAroHCPByHCP(hcp) {
key := hcp.Namespace + kmsAzureCredentials
// We need to only store the Azure credentials once and reuse them after that.
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
index 6f5f85a5190..4e04c187d53 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
@@ -15,7 +15,6 @@ import (
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/oauth"
routerutil "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/router/util"
sharedingress "github.com/openshift/hypershift/hypershift-operator/controllers/sharedingress"
- hyperazureutil "github.com/openshift/hypershift/support/azureutil"
"github.com/openshift/hypershift/support/config"
"github.com/openshift/hypershift/support/events"
"github.com/openshift/hypershift/support/k8sutil"
@@ -454,9 +453,9 @@ func (r *Reconciler) reconcileHCPRouterServices(ctx context.Context, hcp *hyperv
return nil
}
- // ARO HCP doesn't need LB services; Swift handles connectivity.
- // Only reconcile a ClusterIP private router service.
- if hyperazureutil.IsAroHCP() {
+ // ARO HCP doesn't need LB services; shared ingress or Swift handles
+ // connectivity. Only reconcile a ClusterIP private router service.
+ if netutil.UseSwiftNetworkingHCP(hcp) || netutil.UseSharedIngressHCP(hcp) {
if _, err := k8sutil.DeleteIfNeeded(ctx, r.Client, pubSvc); err != nil {
return fmt.Errorf("failed to delete public router service: %w", err)
}
@@ -527,7 +526,7 @@ func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *h
return "", 0, "", errors.New("APIServer service strategy not specified")
}
- if sharedingress.UseSharedIngress() || (hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform && serviceStrategy.Type == hyperv1.Route) {
+ if netutil.UseSharedIngressHCP(hcp) || (hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform && serviceStrategy.Type == hyperv1.Route) {
return sharedingress.KasRouteHostname(hcp), sharedingress.ExternalDNSLBPort, "", nil
}
@@ -684,15 +683,15 @@ func (r *Reconciler) reconcileClusterIPServiceStatus(ctx context.Context, svc *c
}
func (r *Reconciler) reconcileInternalRouterServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, needed bool, message string, err error) {
- // ARO is always private but there's no router service. Connection goes through swift.
- if !netutil.IsPrivateHCP(hcp) || hyperazureutil.IsAroHCP() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
+ // Skip when not private, or when shared ingress / Swift handles connectivity, or IBM Cloud.
+ if !netutil.IsPrivateHCP(hcp) || netutil.UseSwiftNetworkingHCP(hcp) || netutil.UseSharedIngressHCP(hcp) || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
return
}
return r.reconcileRouterServiceStatus(ctx, manifests.PrivateRouterService(hcp.Namespace), events.NewMessageCollector(ctx, r.Client))
}
func (r *Reconciler) reconcileExternalRouterServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, needed bool, message string, err error) {
- if !netutil.IsPublicHCP(hcp) || !netutil.LabelHCPRoutes(hcp) || sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
+ if !netutil.IsPublicHCP(hcp) || !netutil.LabelHCPRoutes(hcp) || netutil.UseSharedIngressHCP(hcp) || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
return
}
return r.reconcileRouterServiceStatus(ctx, manifests.RouterPublicService(hcp.Namespace), events.NewMessageCollector(ctx, r.Client))
diff --git a/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go b/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go
index 8421a068550..ae5c24b5cfa 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go
@@ -58,7 +58,7 @@ func ReconcileRouterService(svc *corev1.Service, internal, crossZoneLoadBalancin
}
}
- if hcp.Spec.Platform.Type == hyperv1.AzurePlatform && !azureutil.IsAroHCP() {
+ if hcp.Spec.Platform.Type == hyperv1.AzurePlatform && !azureutil.IsAroHCPByHCP(hcp) {
if svc.Annotations == nil {
svc.Annotations = map[string]string{}
}
@@ -98,7 +98,7 @@ func ReconcileRouterService(svc *corev1.Service, internal, crossZoneLoadBalancin
// Apply LoadBalancerSourceRanges for external router services to restrict CIDR access
// Only apply for external (non-internal) services and when not running on ARO HCP
allowedCIDRBlocks := netutil.AllowedCIDRBlocks(hcp)
- if !internal && !azureutil.IsAroHCP() {
+ if !internal && !azureutil.IsAroHCPByHCP(hcp) {
svc.Spec.LoadBalancerSourceRanges = allowedCIDRBlocks
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck.go b/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck.go
index 082bc4c4888..20ff972d0cb 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck.go
@@ -7,6 +7,7 @@ import (
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests"
"github.com/openshift/hypershift/hypershift-operator/controllers/sharedingress"
"github.com/openshift/hypershift/support/config"
+ "github.com/openshift/hypershift/support/netutil"
routev1 "github.com/openshift/api/route/v1"
)
@@ -20,12 +21,12 @@ func GetHealthcheckEndpointForRoute(externalRoute *routev1.Route, hcp *hyperv1.H
endpoint = externalRoute.Status.Ingress[0].RouterCanonicalHostname
port = 443
- if sharedingress.UseSharedIngress() {
+ if netutil.UseSharedIngressHCP(hcp) {
endpoint = externalRoute.Spec.Host
port = sharedingress.ExternalDNSLBPort
}
- if sharedingress.UseSharedIngress() &&
+ if netutil.UseSharedIngressHCP(hcp) &&
hcp.Spec.Networking.APIServer != nil && len(hcp.Spec.Networking.APIServer.AllowedCIDRBlocks) > 0 {
// When there's AllowedCIDRBlocks input, we have no guarantees the healthcheck can roundtrip through the haproxy load balancer.
// Hence we use KubeAPIServerService as a best effort.
diff --git a/control-plane-operator/controllers/hostedcontrolplane/kas/service.go b/control-plane-operator/controllers/hostedcontrolplane/kas/service.go
index 1c69a7d4697..ffd30fb0c04 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/kas/service.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/kas/service.go
@@ -79,7 +79,7 @@ func ReconcileService(svc *corev1.Service, strategy *hyperv1.ServicePublishingSt
if strategy.LoadBalancer != nil && strategy.LoadBalancer.Hostname != "" {
svc.Annotations[hyperv1.ExternalDNSHostnameAnnotation] = strategy.LoadBalancer.Hostname
}
- if !azureutil.IsAroHCP() {
+ if !azureutil.IsAroHCPByHCP(hcp) {
svc.Spec.LoadBalancerSourceRanges = apiAllowedCIDRBlocks
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/component.go
index 9aa87ef2839..1c1e7acc341 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/component.go
@@ -90,9 +90,9 @@ func adaptServiceAccount(cpContext component.WorkloadContext, sa *corev1.Service
}
func isAroHCP(cpContext component.WorkloadContext) bool {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
func isSelfManagedAzure(cpContext component.WorkloadContext) bool {
- return !azureutil.IsAroHCP()
+ return !azureutil.IsAroHCPByHCP(cpContext.HCP)
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/config.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/config.go
index 060fee3aeb2..623c0adac07 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/config.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/config.go
@@ -43,7 +43,7 @@ func adaptConfigSecret(cpContext component.WorkloadContext, secret *corev1.Secre
return err
}
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
cfg.UseManagedIdentityExtension = false
cfg.UseInstanceMetadata = false
}
@@ -58,7 +58,7 @@ func adaptConfigSecret(cpContext component.WorkloadContext, secret *corev1.Secre
}
func adaptSecretProvider(cpContext component.WorkloadContext, secretProvider *secretsstorev1.SecretProviderClass) error {
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
secretproviderclass.ReconcileManagedAzureSecretProviderClass(secretProvider, cpContext.HCP, cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.CloudProvider)
}
return nil
@@ -146,10 +146,10 @@ func azureConfig(cpContext component.WorkloadContext, withCredentials bool) (Azu
}
// Configure authentication method based on platform type
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(hcp) {
// ARO HCP uses managed identity
azureConfig.UseManagedIdentityExtension = true
- } else if azureutil.IsSelfManagedAzure(hcp.Spec.Platform.Type) {
+ } else {
// Self-managed Azure uses workload identity
azureConfig.UseFederatedWorkloadIdentityExtension = true
azureConfig.AADClientID = string(azureplatform.AzureAuthenticationConfig.WorkloadIdentities.CloudProvider.ClientID)
@@ -157,7 +157,7 @@ func azureConfig(cpContext component.WorkloadContext, withCredentials bool) (Azu
}
if withCredentials {
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(hcp) {
azureConfig.AADMSIDataPlaneIdentityPath = config.ManagedAzureCertificatePath + hcp.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.CloudProvider.CredentialsSecretName
}
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/deployment.go
index cd79cf9a4d8..0841db52ed1 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/azure/deployment.go
@@ -21,18 +21,18 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
c.Args = append(c.Args,
fmt.Sprintf("--cluster-name=%s", cpContext.HCP.Spec.InfraID),
)
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
c.VolumeMounts = append(c.VolumeMounts,
azureutil.CreateVolumeMountForAzureSecretStoreProviderClass(config.ManagedAzureCloudProviderSecretStoreVolumeName),
)
}
})
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes,
azureutil.CreateVolumeForAzureSecretStoreProviderClass(config.ManagedAzureCloudProviderSecretStoreVolumeName, config.ManagedAzureCloudProviderSecretProviderClassName),
)
- } else if azureutil.IsSelfManagedAzure(cpContext.HCP.Spec.Platform.Type) {
+ } else {
deployment.Spec.Template.Spec.ServiceAccountName = "azure-cloud-controller-manager"
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go
index f6f884301e0..139e1163995 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go
@@ -79,7 +79,7 @@ func NewComponent() component.ControlPlaneComponent {
}
func isAroHCP(cpContext component.WorkloadContext) bool {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
func SetRestartAnnotationAndPatch(ctx context.Context, crclient client.Client, dep *appsv1.Deployment, restartAnnotation string) error {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go
index 986c930145e..b647e6c4cab 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go
@@ -148,7 +148,7 @@ func buildCNOEnvVars(cpContext component.WorkloadContext) []corev1.EnvVar {
// For managed Azure deployments, we pass the env variables for:
// - the SecretProviderClass for the Secrets Store CSI driver to use on the CNCC deployment
// - the filepath of the credentials
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(hcp) {
cnoEnv = append(cnoEnv,
corev1.EnvVar{
Name: config.ManagedAzureSecretProviderClassEnvVarKey,
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/deployment.go
index a3620f1c028..2e54e823c3d 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/deployment.go
@@ -223,7 +223,7 @@ func (cpo *ControlPlaneOperatorOptions) applyPlatformSpecificConfig(hcp *hyperv1
MountPath: "/etc/provider",
})
case hyperv1.AzurePlatform:
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(hcp) {
// Add the client ID of the managed Azure key vault as an environment variable on the CPO. This is used in
// configuring the SecretProviderClass CRs for OpenShift components on the HCP needing to authenticate with
// Azure cloud API.
@@ -254,7 +254,7 @@ func (cpo *ControlPlaneOperatorOptions) applyPlatformSpecificConfig(hcp *hyperv1
azureutil.CreateVolumeForAzureSecretStoreProviderClass(config.ManagedAzureKMSSecretStoreVolumeName, config.ManagedAzureKMSSecretProviderClassName),
)
}
- } else if azureutil.IsSelfManagedAzure(hcp.Spec.Platform.Type) {
+ } else {
if hcp.Spec.Platform.Azure.AzureAuthenticationConfig.WorkloadIdentities != nil &&
hcp.Spec.Platform.Azure.AzureAuthenticationConfig.WorkloadIdentities.ControlPlaneOperator.ClientID != "" {
deployment.Spec.Template.Spec.Containers[0].Env = append(
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/role.go b/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/role.go
index b9bdc48f189..e7ded7121b5 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/role.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/controlplaneoperator/role.go
@@ -39,7 +39,7 @@ func adaptRole(cpContext component.WorkloadContext, role *rbacv1.Role) error {
})
}
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
role.Rules = append(role.Rules, rbacv1.PolicyRule{
APIGroups: []string{"secrets-store.csi.x-k8s.io"},
Resources: []string{"secretproviderclasses"},
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/component.go
index caae5a3205c..728dd1a70af 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/component.go
@@ -87,5 +87,5 @@ func isIngressCapabilityEnabled(cpContext component.WorkloadContext) (bool, erro
}
func isAroHCP(cpContext component.WorkloadContext) bool {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/deployment.go
index a7283b9e79e..74c97a55ddb 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ingressoperator/deployment.go
@@ -32,7 +32,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
// we authenticate with Azure API through UserAssignedCredential authentication. We also mount the
// SecretProviderClass for the Secrets Store CSI driver to use; it will grab the JSON object stored in the
// MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH and mount it as a volume in the ingress pod in the path.
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
c.Env = append(c.Env,
azureutil.CreateEnvVarsForAzureManagedIdentity(cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.Ingress.CredentialsSecretName)...)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/component.go
index d28a7c380f3..404cd9ff81f 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/component.go
@@ -130,7 +130,7 @@ func NewComponent() component.ControlPlaneComponent {
func enableAzureKMSSecretProvider(cpContext component.WorkloadContext) bool {
if cpContext.HCP.Spec.SecretEncryption != nil && cpContext.HCP.Spec.SecretEncryption.KMS != nil && cpContext.HCP.Spec.SecretEncryption.Type == hyperv1.KMS {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
return false
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
index a8f0aa04000..d0ecc5523bc 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go
@@ -141,7 +141,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
// sidecar resolves the Key Vault FQDN to the private-router Service ClusterIP.
// The private router has access to the customer VNet (via Swift) and can reach the
// Key Vault's private endpoint, acting as a TCP passthrough relay.
- if azureutil.IsAroHCP() && azureutil.IsPrivateKeyVault(hcp) {
+ if azureutil.IsAroHCPByHCP(hcp) && azureutil.IsPrivateKeyVault(hcp) {
kvFQDN, err := azureutil.GetKeyVaultFQDN(hcp)
if err != nil {
return fmt.Errorf("failed to get Key Vault FQDN for hostAlias: %w", err)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/component.go
index 5d56595c0ca..144a54c8c3d 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/component.go
@@ -64,5 +64,5 @@ func isImageRegistryCapabilityEnabled(cpContext component.WorkloadContext) (bool
}
func isAroHCP(cpContext component.WorkloadContext) bool {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/deployment.go
index d1f563dd685..8703b193a1c 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/registryoperator/deployment.go
@@ -28,7 +28,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
// we authenticate with Azure API through UserAssignedCredential authentication. We also mount the
// SecretProviderClass for the Secrets Store CSI driver to use; it will grab the JSON object stored in the
// MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH and mount it as a volume in the image registry pod in the path.
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
c.Env = append(c.Env,
azureutil.CreateEnvVarsForAzureManagedIdentity(cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.ImageRegistry.CredentialsSecretName)...)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go
index 674f9021e5b..b7ce7f9541c 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go
@@ -62,7 +62,7 @@ func adaptConfig(cpContext component.WorkloadContext, cm *corev1.ConfigMap) erro
}
var keyVaultFQDN string
- if azureutil.IsAroHCP() && azureutil.IsPrivateKeyVault(cpContext.HCP) {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) && azureutil.IsPrivateKeyVault(cpContext.HCP) {
kvFQDN, err := azureutil.GetKeyVaultFQDN(cpContext.HCP)
if err != nil {
return fmt.Errorf("failed to get Key Vault FQDN: %w", err)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/deployment.go
index 205e96ec02b..0b34e02f698 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/deployment.go
@@ -1,18 +1,18 @@
package router
import (
- hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
component "github.com/openshift/hypershift/support/controlplane-component"
+ "github.com/openshift/hypershift/support/netutil"
appsv1 "k8s.io/api/apps/v1"
)
func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Deployment) error {
- if swiftPodNetworkInstance := cpContext.HCP.Annotations[hyperv1.SwiftPodNetworkInstanceAnnotation]; swiftPodNetworkInstance != "" {
+ if pni := netutil.SwiftPodNetworkInstanceHCP(cpContext.HCP); pni != "" {
if deployment.Spec.Template.Labels == nil {
deployment.Spec.Template.Labels = map[string]string{}
}
- deployment.Spec.Template.Labels["kubernetes.azure.com/pod-network-instance"] = swiftPodNetworkInstance
+ deployment.Spec.Template.Labels["kubernetes.azure.com/pod-network-instance"] = pni
}
return nil
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go
index 0caa883956b..f277685141f 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go
@@ -2,7 +2,6 @@ package util
import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
- "github.com/openshift/hypershift/support/azureutil"
"github.com/openshift/hypershift/support/netutil"
)
@@ -17,11 +16,10 @@ func UseHCPRouter(hcp *hyperv1.HostedControlPlane) bool {
if hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform {
return false
}
- // For ARO HCP, the dedicated HCP router is only needed when the cluster is private
- // (Swift enabled). LabelHCPRoutes returns true for all ARO to support the
- // SharedIngressReconciler, but that doesn't mean a dedicated router deployment is needed.
- if azureutil.IsAroHCP() {
- return netutil.IsPrivateHCP(hcp)
+ // SharedIngress handles public routing for ARO-HCP; a dedicated HCP
+ // router is only needed when the cluster also has private access.
+ if netutil.UseSharedIngressHCP(hcp) && !netutil.IsPrivateHCP(hcp) {
+ return false
}
// Router infrastructure is needed when:
// 1. Cluster has private access (Private or PublicAndPrivate) - for internal routes, OR
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/azure.go b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/azure.go
index 5b6ba52bd1b..4bf3381dadd 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/azure.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/azure.go
@@ -28,9 +28,9 @@ func adaptAzureCSISecret(cpContext component.WorkloadContext, managedIdentity hy
Location: azureSpec.Location,
}
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
azureConfig.AADMSIDataPlaneIdentityPath = path.Join(hyperconfig.ManagedAzureCertificatePath, managedIdentity.CredentialsSecretName)
- } else if azureutil.IsSelfManagedAzure(cpContext.HCP.Spec.Platform.Type) {
+ } else {
azureConfig.UseFederatedWorkloadIdentityExtension = true
azureConfig.AADClientID = string(workloadIdentity.ClientID)
azureConfig.AADFederatedTokenFile = "/var/run/secrets/openshift/serviceaccount/token"
@@ -55,9 +55,9 @@ func adaptAzureCSISecret(cpContext component.WorkloadContext, managedIdentity hy
func adaptAzureCSIDiskSecret(cpContext component.WorkloadContext, secret *corev1.Secret) error {
var managedIdentity hyperv1.ManagedIdentity
var workloadIdentity hyperv1.WorkloadIdentity
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
managedIdentity = cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.Disk
- } else if azureutil.IsSelfManagedAzure(cpContext.HCP.Spec.Platform.Type) {
+ } else {
workloadIdentity = cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.WorkloadIdentities.Disk
}
return adaptAzureCSISecret(cpContext, managedIdentity, workloadIdentity, secret)
@@ -72,9 +72,9 @@ func adaptAzureCSIDiskSecretProvider(cpContext component.WorkloadContext, secret
func adaptAzureCSIFileSecret(cpContext component.WorkloadContext, secret *corev1.Secret) error {
var managedIdentity hyperv1.ManagedIdentity
var workloadIdentity hyperv1.WorkloadIdentity
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
managedIdentity = cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.ManagedIdentities.ControlPlane.File
- } else if azureutil.IsSelfManagedAzure(cpContext.HCP.Spec.Platform.Type) {
+ } else {
workloadIdentity = cpContext.HCP.Spec.Platform.Azure.AzureAuthenticationConfig.WorkloadIdentities.File
}
return adaptAzureCSISecret(cpContext, managedIdentity, workloadIdentity, secret)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/component.go
index 4655da99660..6caf7e91625 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/component.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/component.go
@@ -83,7 +83,7 @@ func isStorageAndCSIManaged(cpContext component.WorkloadContext) (bool, error) {
}
func isAroHCP(cpContext component.WorkloadContext) bool {
- return azureutil.IsAroHCP()
+ return azureutil.IsAroHCPByHCP(cpContext.HCP)
}
type operand struct {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/deployment.go
index 98e152c5c07..92f030271e7 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/storage/deployment.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/storage/deployment.go
@@ -20,7 +20,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
// For managed Azure, we need to supply a couple of environment variables for CSO to pass on to the CSI controllers for disk and file.
// CSO passes those on to the CSI deployment here - https://github.com/openshift/cluster-storage-operator/pull/517/files.
// CSI then mounts the Secrets Provider Class here - https://github.com/openshift/csi-operator/pull/309/files.
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(cpContext.HCP) {
c.Env = append(c.Env,
corev1.EnvVar{
Name: "ARO_HCP_SECRET_PROVIDER_CLASS_FOR_DISK",
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
index d9a9e1394da..122b46d8c1c 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
@@ -1362,7 +1362,7 @@ func (r *reconciler) reconcileRBAC(ctx context.Context, hcp *hyperv1.HostedContr
manifestAndReconcile[*rbacv1.RoleBinding]{manifest: manifests.KASConnectionCheckerRoleBinding, reconcile: rbac.ReconcileKASConnectionCheckerRoleBinding},
}
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHCP(hcp) {
rbacReconciler = append(rbacReconciler,
manifestAndReconcile[*rbacv1.ClusterRole]{manifest: manifests.AzureDiskCSIDriverNodeServiceAccountRole, reconcile: rbac.ReconcileAzureDiskCSIDriverNodeServiceAccountClusterRole},
manifestAndReconcile[*rbacv1.ClusterRoleBinding]{manifest: manifests.AzureDiskCSIDriverNodeServiceAccountRoleBinding, reconcile: rbac.ReconcileAzureDiskCSIDriverNodeServiceAccountClusterRoleBinding},
@@ -1515,7 +1515,7 @@ func (r *reconciler) reconcileAuthOIDC(ctx context.Context, hcp *hyperv1.HostedC
errs = append(errs, fmt.Errorf("failed to get OIDCClient secret %s: %w", oidcClient.ClientSecret.Name, err))
continue
}
- if azureutil.IsAroHCP() && k8sutil.HasAnnotationWithValue(&src, hyperv1.HostedClusterSourcedAnnotation, "true") {
+ if azureutil.IsAroHCPByHCP(hcp) && k8sutil.HasAnnotationWithValue(&src, hyperv1.HostedClusterSourcedAnnotation, "true") {
// This is a day-2 secret. We shouldn't copy it, instead it'll be provided by the end-user on the hosted cluster.
continue
}
@@ -2187,7 +2187,7 @@ func (r *reconciler) reconcileCloudCredentialSecrets(ctx context.Context, hcp *h
}
// Set up the operand credentials for either managed or self-managed Azure environments
- errs = azureresources.SetupOperandCredentials(ctx, r.client, r.CreateOrUpdateProvider, hcp, secretData, azureutil.IsAroHCP())
+ errs = azureresources.SetupOperandCredentials(ctx, r.client, r.CreateOrUpdateProvider, hcp, secretData, azureutil.IsAroHCPByHCP(hcp))
if len(errs) > 0 {
return errs
}
@@ -3465,7 +3465,7 @@ func (r *reconciler) reconcileStorage(ctx context.Context, hcp *hyperv1.HostedCo
operatorv1.ManilaCSIDriver,
}
case hyperv1.AzurePlatform:
- if azureutil.IsSelfManagedAzure(hcp.Spec.Platform.Type) {
+ if !azureutil.IsAroHCPByHCP(hcp) {
driverNames = []operatorv1.CSIDriverName{
operatorv1.AzureDiskCSIDriver,
operatorv1.AzureFileCSIDriver,
From eb9d9f95c31ebbdc4ad82baa0c3a90e6994057b2 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 14:32:20 +0200
Subject: [PATCH 5/8] refactor(ho): replace isAroHCP/UseSharedIngress with
API-driven helpers
Replace env-var and parameterless checks with per-cluster API-driven
helpers in HO controllers:
- Config-generator: add UseSharedIngressHC cluster-level filter to skip
Private clusters entirely from HAProxy config (security-critical)
- NodePool HAProxy: UseSharedIngressHC for worker node backend selection
- NodePool controller: UseSharedIngressHC for HAProxy image selection,
preventing unnecessary rollouts on Private+Swift clusters
- Network policies: UseSharedIngressHC for shared ingress policy
- HostedCluster controller: UseSwiftNetworkingHC and IsAroHCPByHC
for PrivateLink validation, SecretProviderClass, and hosted resources
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../hostedcluster/hostedcluster_controller.go | 11 ++++++-----
.../hostedcluster/network_policies.go | 2 +-
.../nodepool/apiserver-haproxy/haproxy.go | 4 ++--
.../controllers/nodepool/nodepool_controller.go | 16 ++++++----------
sharedingress-config-generator/config.go | 4 ++++
5 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index 095522e7bd2..19c012d1260 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -991,7 +991,7 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
// Copy Azure Private Link conditions from the AzurePrivateLinkService resources.
// ARO HCP uses Swift networking, not Private Link Services.
- if hcluster.Spec.Platform.Type == hyperv1.AzurePlatform && !azureutil.IsAroHCP() {
+ if hcluster.Spec.Platform.Type == hyperv1.AzurePlatform && !netutil.UseSwiftNetworkingHC(hcluster) {
hcpNamespace := manifests.HostedControlPlaneNamespace(hcluster.Namespace, hcluster.Name)
var azPLSList hyperv1.AzurePrivateLinkServiceList
if err := r.List(ctx, &azPLSList, &client.ListOptions{Namespace: hcpNamespace}); err != nil {
@@ -2069,7 +2069,7 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, err
}
case hyperv1.AzurePlatform:
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHC(hcluster) {
// Reconcile CPO SecretProviderClass CR
cpoSecretProviderClass := cpomanifests.ManagedAzureSecretProviderClass(config.ManagedAzureCPOSecretProviderClassName, hcp.Namespace)
if _, err = createOrUpdate(ctx, r, cpoSecretProviderClass, func() error {
@@ -2090,7 +2090,7 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
}
if hcluster.Spec.SecretEncryption != nil && hcluster.Spec.SecretEncryption.KMS != nil {
- if azureutil.IsAroHCP() {
+ if azureutil.IsAroHCPByHC(hcluster) {
// Reconcile KMS SecretProviderClass CR
kmsSecretProviderClass := cpomanifests.ManagedAzureSecretProviderClass(config.ManagedAzureKMSSecretProviderClassName, hcp.Namespace)
if _, err := createOrUpdate(ctx, r, kmsSecretProviderClass, func() error {
@@ -2112,6 +2112,7 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
if err := r.reconcileKarpenterOperator(cpContext, hcluster, r.HypershiftOperatorImage, controlPlaneOperatorImage); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to reconcile karpenter operator: %w", err)
}
+ }
log.Info("successfully reconciled")
result := ctrl.Result{}
@@ -3996,7 +3997,7 @@ func (r *HostedClusterReconciler) validateAzureConfig(hc *hyperv1.HostedCluster)
// When topology is Private or PublicAndPrivate, the private field must be configured
// to provide Azure Private Link Service settings for private API server access.
// ARO HCP uses Swift networking, not Private Link Services.
- if !azureutil.IsAroHCP() &&
+ if !netutil.UseSwiftNetworkingHC(hc) &&
hc.Spec.Platform.Azure.Topology != "" &&
hc.Spec.Platform.Azure.Topology != hyperv1.AzureTopologyPublic &&
hc.Spec.Platform.Azure.Private.Type == "" {
@@ -5217,7 +5218,7 @@ func ensureReferencedResourceAnnotation(ctx context.Context, client client.Clien
}
func ensureHostedResourcesAreEmpty(ctx context.Context, crclient client.Client, hcluster *hyperv1.HostedCluster, obj client.Object) error {
- if !azureutil.IsAroHCP() || !k8sutil.HasAnnotationWithValue(obj, hyperv1.HostedClusterSourcedAnnotation, "true") {
+ if !azureutil.IsAroHCPByHC(hcluster) || !k8sutil.HasAnnotationWithValue(obj, hyperv1.HostedClusterSourcedAnnotation, "true") {
return nil
}
var cm corev1.Secret
diff --git a/hypershift-operator/controllers/hostedcluster/network_policies.go b/hypershift-operator/controllers/hostedcluster/network_policies.go
index 056d3ce3611..1d94c5857f4 100644
--- a/hypershift-operator/controllers/hostedcluster/network_policies.go
+++ b/hypershift-operator/controllers/hostedcluster/network_policies.go
@@ -79,7 +79,7 @@ func (r *HostedClusterReconciler) reconcileNetworkPolicies(ctx context.Context,
return err
}
- if sharedingress.UseSharedIngress() {
+ if netutil.UseSharedIngressHC(hcluster) {
policy := networkpolicy.SharedIngressNetworkPolicy(controlPlaneNamespaceName)
if _, err := createOrUpdate(ctx, r.Client, policy, func() error {
return reconcileSharedIngressNetworkPolicy(policy, hcluster)
diff --git a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go
index df8ba33615e..1118e8f1f2a 100644
--- a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go
+++ b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go
@@ -157,7 +157,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster *
}
// This is true for ARO in CI while swift is not available.
- if sharedingress.UseSharedIngress() && !netutil.IsPrivateHC(hcluster) {
+ if netutil.UseSharedIngressHC(hcluster) && !netutil.IsPrivateHC(hcluster) {
sharedIngressRouteSVC := &corev1.Service{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
@@ -175,7 +175,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster *
apiServerExternalPort = sharedingress.KASSVCLBPort
}
- useProxyProtocol := sharedingress.UseSharedIngress() && !netutil.IsPrivateHC(hcluster)
+ useProxyProtocol := netutil.UseSharedIngressHC(hcluster) && !netutil.IsPrivateHC(hcluster)
serializedConfig, err := apiServerProxyConfig(r.HAProxyImage, controlPlaneOperatorImage, hcluster.Spec.ClusterID,
apiServerExternalAddress, apiServerInternalAddress,
apiServerExternalPort, apiServerInternalPort,
diff --git a/hypershift-operator/controllers/nodepool/nodepool_controller.go b/hypershift-operator/controllers/nodepool/nodepool_controller.go
index 8a550972e4a..b2b89f4f769 100644
--- a/hypershift-operator/controllers/nodepool/nodepool_controller.go
+++ b/hypershift-operator/controllers/nodepool/nodepool_controller.go
@@ -16,12 +16,12 @@ import (
haproxy "github.com/openshift/hypershift/hypershift-operator/controllers/nodepool/apiserver-haproxy"
"github.com/openshift/hypershift/hypershift-operator/controllers/nodepool/instancetype"
"github.com/openshift/hypershift/hypershift-operator/controllers/nodepool/kubevirt"
- "github.com/openshift/hypershift/hypershift-operator/controllers/sharedingress"
kvinfra "github.com/openshift/hypershift/kubevirtexternalinfra"
"github.com/openshift/hypershift/support/awsapi"
"github.com/openshift/hypershift/support/capabilities"
"github.com/openshift/hypershift/support/images"
"github.com/openshift/hypershift/support/k8sutil"
+ "github.com/openshift/hypershift/support/netutil"
"github.com/openshift/hypershift/support/releaseinfo"
"github.com/openshift/hypershift/support/supportedversion"
"github.com/openshift/hypershift/support/upsert"
@@ -1084,21 +1084,17 @@ func (r *NodePoolReconciler) getAdditionalTrustBundle(ctx context.Context, hoste
// resolveHAProxyImage determines which HAProxy image to use based on priority:
// 1. NodePool annotation (highest priority)
-// 2. Environment variable override (when shared ingress enabled)
-// 3. Hardcoded default (when shared ingress enabled)
-// 4. Release payload (default)
-func resolveHAProxyImage(nodePool *hyperv1.NodePool, releaseImage *releaseinfo.ReleaseImage) (string, error) {
- // Check NodePool annotation first (highest priority)
+// 2. Shared ingress image (when cluster uses shared ingress for public endpoints)
+// 3. Release payload (default)
+func resolveHAProxyImage(nodePool *hyperv1.NodePool, hcluster *hyperv1.HostedCluster, releaseImage *releaseinfo.ReleaseImage) (string, error) {
if annotationImage := strings.TrimSpace(nodePool.Annotations[hyperv1.NodePoolHAProxyImageAnnotation]); annotationImage != "" {
return annotationImage, nil
}
- // Check if shared ingress is enabled
- if sharedingress.UseSharedIngress() {
+ if netutil.UseSharedIngressHC(hcluster) {
return images.GetSharedIngressHAProxyImage(), nil
}
- // Fall back to release payload image
haProxyImage, ok := releaseImage.ComponentImages()[haproxy.HAProxyRouterImageName]
if !ok {
return "", fmt.Errorf("release image doesn't have a %s image", haproxy.HAProxyRouterImageName)
@@ -1107,7 +1103,7 @@ func resolveHAProxyImage(nodePool *hyperv1.NodePool, releaseImage *releaseinfo.R
}
func (r *NodePoolReconciler) generateHAProxyRawConfig(ctx context.Context, nodePool *hyperv1.NodePool, hcluster *hyperv1.HostedCluster, releaseImage *releaseinfo.ReleaseImage) (string, error) {
- haProxyImage, err := resolveHAProxyImage(nodePool, releaseImage)
+ haProxyImage, err := resolveHAProxyImage(nodePool, hcluster, releaseImage)
if err != nil {
return "", err
}
diff --git a/sharedingress-config-generator/config.go b/sharedingress-config-generator/config.go
index 6810c004e99..998bdd04e66 100644
--- a/sharedingress-config-generator/config.go
+++ b/sharedingress-config-generator/config.go
@@ -85,6 +85,10 @@ func generateRouterConfig(ctx context.Context, client crclient.Client, w io.Writ
if !hc.DeletionTimestamp.IsZero() {
continue
}
+ // Skip clusters that don't use shared ingress (Private topology or non-Swift).
+ if !netutil.UseSharedIngressHC(&hc) {
+ continue
+ }
backends, externalDNSBackends, err := getBackendsForHostedCluster(ctx, hc, client)
if err != nil {
From cf0eb682d4c144e462f943a6807ea8183516a647 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 14:32:40 +0200
Subject: [PATCH 6/8] feat(azure): reconcile PublicEndpointExposed condition
via TLS probe
Add reconciliation logic for the PublicEndpointExposed condition on
HostedCluster. The HC controller probes the shared ingress Service's
ClusterIP with the cluster's KAS hostname as SNI to determine whether
public API server endpoints are actually reachable.
The probe function is injectable via ProbeSharedIngressEndpoint field
on the reconciler for unit testing.
Condition truth table (observed state):
- LB not ready + UseSharedIngress: False/ConvergenceInProgress
- Probe success + UseSharedIngress: True/SharedIngressConfigured
- Probe failure + UseSharedIngress: False/ConvergenceInProgress
- Probe success + !UseSharedIngress: True/ConvergenceInProgress
- Probe failure + !UseSharedIngress: False/TopologyPrivate
Convergence cases requeue after 10s to re-check. Only set on Swift
clusters; non-Swift clusters (PrivateLink) don't get this condition.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../hostedcluster/hostedcluster_controller.go | 117 ++++++++++
.../public_endpoint_condition_test.go | 209 ++++++++++++++++++
2 files changed, 326 insertions(+)
create mode 100644 hypershift-operator/controllers/hostedcluster/public_endpoint_condition_test.go
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index 19c012d1260..f7c2deac532 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -213,6 +213,11 @@ type HostedClusterReconciler struct {
FeatureSet configv1.FeatureSet
OpenShiftTrustedCAFilePath string
+
+ // ProbeSharedIngressEndpoint tests whether a public endpoint is reachable
+ // via the shared ingress. Defaults to probeSharedIngressEndpoint. Override
+ // in tests to avoid real network calls.
+ ProbeSharedIngressEndpoint func(context context.Context, serviceIP string, servicePort int, kasHostname string) bool
}
// +kubebuilder:rbac:groups=hypershift.openshift.io,resources=hostedclusters,verbs=get;list;watch;create;update;patch;delete
@@ -2112,6 +2117,11 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
if err := r.reconcileKarpenterOperator(cpContext, hcluster, r.HypershiftOperatorImage, controlPlaneOperatorImage); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to reconcile karpenter operator: %w", err)
}
+
+ if pubEndpointRequeue, err := r.reconcilePublicEndpointExposedCondition(ctx, hcluster); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to reconcile PublicEndpointExposed condition: %w", err)
+ } else if pubEndpointRequeue != nil && (requeueAfter == nil || *pubEndpointRequeue < *requeueAfter) {
+ requeueAfter = pubEndpointRequeue
}
log.Info("successfully reconciled")
@@ -5409,3 +5419,110 @@ func computeAzurePLSCondition(azPLSList hyperv1.AzurePrivateLinkServiceList, con
}
return computeEndpointServiceCondition(resourceConditions, conditionType, hyperv1.AzurePLSErrorReason, hyperv1.AzurePLSSuccessReason, "AzurePrivateLinkService conditions not found")
}
+
+const publicEndpointProbeTimeout = 3 * time.Second
+
+func (r *HostedClusterReconciler) reconcilePublicEndpointExposedCondition(ctx context.Context, hc *hyperv1.HostedCluster) (*time.Duration, error) {
+ if !netutil.UseSwiftNetworkingHC(hc) {
+ return nil, nil
+ }
+
+ kasStrategy := netutil.ServicePublishingStrategyByTypeByHC(hc, hyperv1.APIServer)
+ if kasStrategy == nil || kasStrategy.Route == nil || kasStrategy.Route.Hostname == "" {
+ return nil, nil
+ }
+ kasHostname := kasStrategy.Route.Hostname
+
+ svc := &corev1.Service{}
+ svcKey := client.ObjectKey{Namespace: "hypershift-sharedingress", Name: "router"}
+ if err := r.Client.Get(ctx, svcKey, svc); err != nil {
+ if apierrors.IsNotFound(err) {
+ return nil, nil
+ }
+ return nil, fmt.Errorf("failed to get shared ingress service: %w", err)
+ }
+ if svc.Spec.ClusterIP == "" || svc.Spec.ClusterIP == "None" {
+ return nil, nil
+ }
+
+ lbReady := len(svc.Status.LoadBalancer.Ingress) > 0 &&
+ (svc.Status.LoadBalancer.Ingress[0].Hostname != "" || svc.Status.LoadBalancer.Ingress[0].IP != "")
+ usesSharedIngress := netutil.UseSharedIngressHC(hc)
+
+ if !lbReady && usesSharedIngress {
+ condition := metav1.Condition{
+ Type: string(hyperv1.PublicEndpointExposed),
+ Status: metav1.ConditionFalse,
+ Reason: hyperv1.PublicEndpointConvergenceInProgressReason,
+ Message: "Shared ingress LoadBalancer is not ready",
+ ObservedGeneration: hc.Generation,
+ }
+ if meta.SetStatusCondition(&hc.Status.Conditions, condition) {
+ if err := r.Client.Status().Update(ctx, hc); err != nil {
+ return nil, fmt.Errorf("failed to update PublicEndpointExposed condition: %w", err)
+ }
+ }
+ d := 10 * time.Second
+ return &d, nil
+ }
+
+ probeFn := r.ProbeSharedIngressEndpoint
+ if probeFn == nil {
+ probeFn = probeSharedIngressEndpoint
+ }
+ exposed := probeFn(ctx, svc.Spec.ClusterIP, 443, kasHostname)
+
+ var condition metav1.Condition
+ condition.Type = string(hyperv1.PublicEndpointExposed)
+ condition.ObservedGeneration = hc.Generation
+ var requeue *time.Duration
+
+ switch {
+ case exposed && usesSharedIngress:
+ condition.Status = metav1.ConditionTrue
+ condition.Reason = hyperv1.PublicEndpointSharedIngressConfiguredReason
+ condition.Message = "Public API server endpoint is reachable via shared ingress"
+
+ case !exposed && usesSharedIngress:
+ condition.Status = metav1.ConditionFalse
+ condition.Reason = hyperv1.PublicEndpointConvergenceInProgressReason
+ condition.Message = "Public endpoint configuration in progress"
+ d := 10 * time.Second
+ requeue = &d
+
+ case exposed && !usesSharedIngress:
+ condition.Status = metav1.ConditionTrue
+ condition.Reason = hyperv1.PublicEndpointConvergenceInProgressReason
+ condition.Message = "Public endpoint removal in progress"
+ d := 10 * time.Second
+ requeue = &d
+
+ case !exposed && !usesSharedIngress:
+ condition.Status = metav1.ConditionFalse
+ condition.Reason = hyperv1.PublicEndpointTopologyPrivateReason
+ condition.Message = "Public API server endpoint is not exposed via shared ingress"
+ }
+
+ if meta.SetStatusCondition(&hc.Status.Conditions, condition) {
+ if err := r.Client.Status().Update(ctx, hc); err != nil {
+ return nil, fmt.Errorf("failed to update PublicEndpointExposed condition: %w", err)
+ }
+ }
+ return requeue, nil
+}
+
+func probeSharedIngressEndpoint(context context.Context, serviceIP string, servicePort int, kasHostname string) bool {
+ dialer := &tls.Dialer{
+ NetDialer: &net.Dialer{Timeout: publicEndpointProbeTimeout},
+ Config: &tls.Config{
+ ServerName: kasHostname,
+ InsecureSkipVerify: true, //nolint:gosec
+ },
+ }
+ conn, err := dialer.DialContext(context, "tcp", net.JoinHostPort(serviceIP, strconv.Itoa(servicePort)))
+ if err != nil {
+ return false
+ }
+ conn.Close()
+ return true
+}
diff --git a/hypershift-operator/controllers/hostedcluster/public_endpoint_condition_test.go b/hypershift-operator/controllers/hostedcluster/public_endpoint_condition_test.go
new file mode 100644
index 00000000000..0e7f88805d1
--- /dev/null
+++ b/hypershift-operator/controllers/hostedcluster/public_endpoint_condition_test.go
@@ -0,0 +1,209 @@
+package hostedcluster
+
+import (
+ "context"
+ "testing"
+ "time"
+
+ . "github.com/onsi/gomega"
+
+ hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
+ api "github.com/openshift/hypershift/support/api"
+
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ crclient "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+)
+
+func sharedIngressService(clusterIP string, lbHostname string) *corev1.Service {
+ svc := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "router",
+ Namespace: "hypershift-sharedingress",
+ },
+ Spec: corev1.ServiceSpec{
+ ClusterIP: clusterIP,
+ },
+ }
+ if lbHostname != "" {
+ svc.Status.LoadBalancer.Ingress = []corev1.LoadBalancerIngress{
+ {Hostname: lbHostname},
+ }
+ }
+ return svc
+}
+
+func swiftHostedCluster(name string, topology hyperv1.AzureTopologyType, kasHostname string) *hyperv1.HostedCluster {
+ return &hyperv1.HostedCluster{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: "clusters",
+ Generation: 1,
+ },
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: topology,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ Services: []hyperv1.ServicePublishingStrategyMapping{
+ {
+ Service: hyperv1.APIServer,
+ ServicePublishingStrategy: hyperv1.ServicePublishingStrategy{
+ Type: hyperv1.Route,
+ Route: &hyperv1.RoutePublishingStrategy{
+ Hostname: kasHostname,
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func TestReconcilePublicEndpointExposedCondition(t *testing.T) {
+ tests := []struct {
+ name string
+ hc *hyperv1.HostedCluster
+ svc *corev1.Service
+ probeResult bool
+ expectCondition bool
+ expectStatus metav1.ConditionStatus
+ expectReason string
+ expectRequeue bool
+ }{
+ {
+ name: "When cluster is not Swift it should not set condition",
+ hc: &hyperv1.HostedCluster{
+ ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "clusters", Generation: 1},
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ },
+ },
+ },
+ expectCondition: false,
+ },
+ {
+ name: "When shared ingress service is not found it should not set condition",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPublicAndPrivate, "api.test.example.com"),
+ svc: nil,
+ expectCondition: false,
+ },
+ {
+ name: "When KAS hostname is not configured it should not set condition",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPublicAndPrivate, ""),
+ svc: sharedIngressService("10.0.0.1", "lb.example.com"),
+ expectCondition: false,
+ },
+ {
+ name: "When LB is not ready and cluster uses shared ingress it should set False with ConvergenceInProgress",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPublicAndPrivate, "api.test.example.com"),
+ svc: sharedIngressService("10.0.0.1", ""),
+ expectCondition: true,
+ expectStatus: metav1.ConditionFalse,
+ expectReason: hyperv1.PublicEndpointConvergenceInProgressReason,
+ expectRequeue: true,
+ },
+ {
+ name: "When probe succeeds and cluster uses shared ingress it should set True with SharedIngressConfigured",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPublicAndPrivate, "api.test.example.com"),
+ svc: sharedIngressService("10.0.0.1", "lb.example.com"),
+ probeResult: true,
+ expectCondition: true,
+ expectStatus: metav1.ConditionTrue,
+ expectReason: hyperv1.PublicEndpointSharedIngressConfiguredReason,
+ expectRequeue: false,
+ },
+ {
+ name: "When probe fails and cluster uses shared ingress it should set False with ConvergenceInProgress",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPublicAndPrivate, "api.test.example.com"),
+ svc: sharedIngressService("10.0.0.1", "lb.example.com"),
+ probeResult: false,
+ expectCondition: true,
+ expectStatus: metav1.ConditionFalse,
+ expectReason: hyperv1.PublicEndpointConvergenceInProgressReason,
+ expectRequeue: true,
+ },
+ {
+ name: "When probe succeeds but cluster is Private it should set True with ConvergenceInProgress",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPrivate, "api.test.example.com"),
+ svc: sharedIngressService("10.0.0.1", "lb.example.com"),
+ probeResult: true,
+ expectCondition: true,
+ expectStatus: metav1.ConditionTrue,
+ expectReason: hyperv1.PublicEndpointConvergenceInProgressReason,
+ expectRequeue: true,
+ },
+ {
+ name: "When probe fails and cluster is Private it should set False with TopologyPrivate",
+ hc: swiftHostedCluster("test", hyperv1.AzureTopologyPrivate, "api.test.example.com"),
+ svc: sharedIngressService("10.0.0.1", "lb.example.com"),
+ probeResult: false,
+ expectCondition: true,
+ expectStatus: metav1.ConditionFalse,
+ expectReason: hyperv1.PublicEndpointTopologyPrivateReason,
+ expectRequeue: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+
+ objects := []crclient.Object{tt.hc}
+ if tt.svc != nil {
+ objects = append(objects, tt.svc)
+ }
+ cl := fake.NewClientBuilder().
+ WithScheme(api.Scheme).
+ WithObjects(objects...).
+ WithStatusSubresource(tt.hc).
+ Build()
+
+ r := &HostedClusterReconciler{
+ Client: cl,
+ ProbeSharedIngressEndpoint: func(context context.Context, serviceIP string, servicePort int, kasHostname string) bool {
+ return tt.probeResult
+ },
+ }
+
+ requeue, err := r.reconcilePublicEndpointExposedCondition(t.Context(), tt.hc)
+ g.Expect(err).ToNot(HaveOccurred())
+
+ if tt.expectRequeue {
+ g.Expect(requeue).ToNot(BeNil(), "expected requeue")
+ g.Expect(*requeue).To(Equal(10 * time.Second))
+ } else {
+ g.Expect(requeue).To(BeNil(), "expected no requeue")
+ }
+
+ updatedHC := &hyperv1.HostedCluster{}
+ g.Expect(cl.Get(t.Context(), crclient.ObjectKeyFromObject(tt.hc), updatedHC)).To(Succeed())
+
+ condition := meta.FindStatusCondition(updatedHC.Status.Conditions, string(hyperv1.PublicEndpointExposed))
+ if !tt.expectCondition {
+ g.Expect(condition).To(BeNil(), "expected no PublicEndpointExposed condition")
+ return
+ }
+
+ g.Expect(condition).ToNot(BeNil(), "expected PublicEndpointExposed condition to be set")
+ g.Expect(condition.Status).To(Equal(tt.expectStatus), "unexpected condition status")
+ g.Expect(condition.Reason).To(Equal(tt.expectReason), "unexpected condition reason")
+ g.Expect(condition.ObservedGeneration).To(Equal(tt.hc.Generation))
+ })
+ }
+}
From 189a75a9b52fa6b6cd0417d7665e58588c3a3b4f Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Fri, 5 Jun 2026 14:32:53 +0200
Subject: [PATCH 7/8] test(azure): update tests to use Swift API fields and
API-driven helpers
Update test objects across CPO and HO controllers to use Swift API
fields (Private.Type=Swift, Topology) for API-driven Swift detection.
Add unit tests for UseSwiftNetworkingHCP/HC, UseSharedIngressHCP/HC,
IsAroHCPByHCP/HC, and SwiftPodNetworkInstanceHCP covering API field,
annotation fallback, env-var fallback, and negative cases.
Split infra test cases into annotation-only, API-only, and both
variants for comprehensive Swift detection coverage.
Update test fixtures to set AzureAuthenticationConfigType=ManagedIdentities
when simulating ARO HCP clusters.
Add envtest test suite for Azure Swift topology validation.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
...stable.hostedclusters.azure.testsuite.yaml | 1016 +++++++++++++++++
.../hostedcontrolplane_controller_test.go | 8 +
.../hostedcontrolplane/infra/infra_test.go | 214 +++-
...ure_ARO_Route_SharedIngress_APIField.yaml} | 0
...ute_SharedIngress_AnnotationFallback.yaml} | 42 +-
...tructure_ARO_Route_SharedIngress_Both.yaml | 280 +++++
.../kas/healthcheck_test.go | 33 +-
...mponents_azure_cloud_config_configmap.yaml | 6 +-
...eComponents_azure_cloud_config_secret.yaml | 2 +-
...e_cloud_controller_manager_deployment.yaml | 3 +-
...mponents_azure_cloud_config_configmap.yaml | 6 +-
...eComponents_azure_cloud_config_secret.yaml | 2 +-
...e_cloud_controller_manager_deployment.yaml | 3 +-
...mponents_azure_cloud_config_configmap.yaml | 6 +-
...eComponents_azure_cloud_config_secret.yaml | 2 +-
...e_cloud_controller_manager_deployment.yaml | 3 +-
...mponents_azure_cloud_config_configmap.yaml | 6 +-
...eComponents_azure_cloud_config_secret.yaml | 2 +-
...e_cloud_controller_manager_deployment.yaml | 3 +-
.../controllers/resources/resources_test.go | 14 +
.../hostedcluster_controller_test.go | 30 +-
.../hostedcluster/network_policies.go | 1 +
.../apiserver-haproxy/haproxy_test.go | 22 +-
...ice_IP__port_6443_and_proxy_protocol.yaml} | 0
.../nodepool/nodepool_controller_test.go | 29 +-
sharedingress-config-generator/config_test.go | 42 +-
...d_it_should_skip_the_dataplane_kas_svc.cfg | 8 -
...g_with_frontends_and_backends_for_both.cfg | 10 -
support/azureutil/azureutil_test.go | 187 +++
support/netutil/visibility_test.go | 561 ++++++++-
30 files changed, 2468 insertions(+), 73 deletions(-)
rename control-plane-operator/controllers/hostedcontrolplane/infra/testdata/{zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_And_Swift.yaml => zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml} (100%)
rename control-plane-operator/controllers/hostedcontrolplane/infra/testdata/{zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress.yaml => zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_AnnotationFallback.yaml} (85%)
create mode 100644 control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml
rename hypershift-operator/controllers/nodepool/apiserver-haproxy/testdata/{zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO__and_no_Swift_is_used_CI__it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml => zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO_shared_ingress_is_used_it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml} (100%)
diff --git a/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.azure.testsuite.yaml b/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.azure.testsuite.yaml
index 84fbbe40b96..d8833e0ac52 100644
--- a/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.azure.testsuite.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.azure.testsuite.yaml
@@ -955,3 +955,1019 @@ tests:
type: Route
route: {}
expectedError: "private is required when topology is Private or PublicAndPrivate, and forbidden otherwise"
+ # --- Azure Swift private networking validation ---
+ - name: When Private.Type is Swift with valid Swift spec it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ - name: When Private.Type is Swift but privateLink is also set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ privateLink:
+ natSubnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/nat-subnet"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "privateLink is required when type is PrivateLink, and forbidden otherwise"
+
+ - name: When Private.Type is Swift but swift spec is missing it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "swift is required when type is Swift, and forbidden otherwise"
+
+ - name: When Private.Type is PrivateLink but swift is also set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: PrivateLink
+ privateLink:
+ natSubnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/nat-subnet"
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "swift is required when type is Swift, and forbidden otherwise"
+
+ - name: When Topology is Private with Private.Type Swift it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ onUpdate:
+ # --- Azure Swift private networking immutability ---
+ - name: When Private.Type changes from PrivateLink to Swift it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: PrivateLink
+ privateLink:
+ natSubnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/nat-subnet"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "type is immutable"
+
+ - name: When Swift.PodNetworkInstance changes it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "pni-old"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "pni-new"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "podNetworkInstance is immutable"
+
+ - name: When Topology changes from PublicAndPrivate to Private it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ - name: When Topology changes from Private to PublicAndPrivate it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: PublicAndPrivate
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ - name: When Topology changes from Private to Public it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Private
+ private:
+ type: Swift
+ swift:
+ podNetworkInstance: "test-pni"
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ dns:
+ baseDomain: example.com
+ platform:
+ type: Azure
+ azure:
+ location: eastus
+ resourceGroupName: test-rg
+ vnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet"
+ subnetID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet"
+ subscriptionID: "12345678-1234-5678-9012-123456789012"
+ securityGroupID: "/subscriptions/12345678-1234-5678-9012-123456789012/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/test-nsg"
+ tenantID: "87654321-4321-8765-2109-876543210987"
+ topology: Public
+ azureAuthenticationConfig:
+ azureAuthenticationConfigType: WorkloadIdentities
+ workloadIdentities:
+ imageRegistry:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ ingress:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ file:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ disk:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ nodePoolManagement:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ cloudProvider:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ network:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ controlPlaneOperator:
+ clientID: "12345678-1234-5678-9012-123456789012"
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "transitions between Public and non-Public topology are not supported"
diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go
index 7fbcdb4032c..d09a4c7dba7 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go
@@ -1079,6 +1079,14 @@ func TestControlPlaneComponents(t *testing.T) {
hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
},
mutateHCP: func(hcp *hyperv1.HostedControlPlane) {
+ // Configure Swift API fields for ARO-HCP
+ hcp.Spec.Platform.Azure.Private = hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "swift-network-instance",
+ },
+ }
+ hcp.Spec.Platform.Azure.Topology = hyperv1.AzureTopologyPublicAndPrivate
// Configure Azure KMS for ARO-HCP
hcp.Spec.Platform.Azure.Cloud = "AzurePublicCloud"
hcp.Spec.SecretEncryption = &hyperv1.SecretEncryptionSpec{
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
index 1636e722d9b..21ad694605b 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
@@ -535,20 +535,28 @@ func TestReconcileInfrastructure(t *testing.T) {
},
},
// ARO HCP test cases - use shared ingress
+ // Three variants cover each Swift detection path independently:
+ // 1. Annotation-only (legacy fallback: env var + annotation, no API fields)
+ // 2. API-only (Private.Type=Swift, no annotation)
+ // 3. Both annotation AND API fields (coexistence during migration)
{
- name: "ARO_Route_SharedIngress",
- hcp: withServices(
- baseAzureHCP(),
- allServicesRouteWithHostnames(),
- ),
+ name: "ARO_Route_SharedIngress_AnnotationFallback",
+ hcp: func() *hyperv1.HostedControlPlane {
+ hcp := withServices(baseAzureHCP(), allServicesRouteWithHostnames())
+ hcp.Annotations = map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
+ }
+ hcp.Spec.Platform.Azure.AzureAuthenticationConfig = hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ }
+ return hcp
+ }(),
setupEnv: func(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
expectError: false,
- // For ARO with shared ingress:
- // - APIHost comes directly from strategy.Route.Hostname
- // - Port is 443 (ExternalDNSLBPort)
- // - No internal/external routers needed (shared ingress handles it)
+ // Legacy fallback: Swift detected via env var + annotation.
+ // Same behavior as API field path: shared ingress, no routers.
expectedStatus: &InfrastructureStatus{
APIHost: testKASHostname,
APIPort: 443,
@@ -562,23 +570,62 @@ func TestReconcileInfrastructure(t *testing.T) {
},
},
{
- name: "ARO_Route_SharedIngress_And_Swift",
+ name: "ARO_Route_SharedIngress_APIField",
+ hcp: func() *hyperv1.HostedControlPlane {
+ hcp := withServices(baseAzureHCP(), allServicesRouteWithHostnames())
+ hcp.Spec.Platform.Azure.Private = hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ }
+ hcp.Spec.Platform.Azure.AzureAuthenticationConfig = hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ }
+ return hcp
+ }(),
+ setupEnv: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ expectError: false,
+ // New path: Swift detected via Private.Type=Swift API field.
+ // Same behavior: shared ingress, no routers.
+ expectedStatus: &InfrastructureStatus{
+ APIHost: testKASHostname,
+ APIPort: 443,
+ OAuthEnabled: true,
+ OAuthHost: testOAuthHostname,
+ OAuthPort: 443,
+ KonnectivityHost: testKonnectivityHost,
+ KonnectivityPort: 443,
+ NeedInternalRouter: false,
+ NeedExternalRouter: false,
+ },
+ },
+ {
+ name: "ARO_Route_SharedIngress_Both",
hcp: func() *hyperv1.HostedControlPlane {
hcp := withServices(baseAzureHCP(), allServicesRouteWithHostnames())
hcp.Annotations = map[string]string{
hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
}
+ hcp.Spec.Platform.Azure.Private = hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "swift-network-instance",
+ },
+ }
+ hcp.Spec.Platform.Azure.AzureAuthenticationConfig = hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ }
return hcp
}(),
setupEnv: func(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
expectError: false,
- // For ARO with Swift:
- // - Swift handles pod networking, so no router services are needed
- // - APIHost comes from shared ingress (KasRouteHostname)
- // - Port is 443 (ExternalDNSLBPort)
- // - Konnectivity (and ignition see v2/ignitionserver) Routes use hypershift.local, kas and auth use both hypershift.local and external routes
+ // Coexistence: both annotation and API field set during migration.
+ // API field takes precedence; same behavior as API-only path.
expectedStatus: &InfrastructureStatus{
APIHost: testKASHostname,
APIPort: 443,
@@ -1573,20 +1620,84 @@ func TestReconcileHCPRouterServices(t *testing.T) {
expectedServices: nil,
},
{
- name: "When ARO is enabled it should not create any services",
+ name: "When ARO with Swift annotation fallback it should create only a ClusterIP private router service",
endpointAccess: hyperv1.Public,
exposeAPIServerThroughRouter: true,
- expectedServices: nil,
+ expectedServices: []corev1.Service{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "private-router",
+ Namespace: namespace,
+ Labels: map[string]string{"app": "private-router"},
+ },
+ Spec: corev1.ServiceSpec{
+ Type: corev1.ServiceTypeClusterIP,
+ Selector: map[string]string{"app": "private-router"},
+ Ports: []corev1.ServicePort{
+ {
+ Name: "https",
+ Port: 443,
+ TargetPort: intstr.FromString("https"),
+ Protocol: corev1.ProtocolTCP,
+ },
+ },
+ },
+ },
+ },
setupEnv: func(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
hcpModifier: func(hcp *hyperv1.HostedControlPlane) {
hcp.Spec.Platform.Type = hyperv1.AzurePlatform
hcp.Spec.Platform.AWS = nil
+ hcp.Annotations = map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
+ }
},
},
{
- name: "When ARO with Swift is enabled it should create only a ClusterIP private router service",
+ name: "When ARO with Swift API fields it should create only a ClusterIP private router service",
+ endpointAccess: hyperv1.Public,
+ exposeAPIServerThroughRouter: true,
+ expectedServices: []corev1.Service{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "private-router",
+ Namespace: namespace,
+ Labels: map[string]string{"app": "private-router"},
+ },
+ Spec: corev1.ServiceSpec{
+ Type: corev1.ServiceTypeClusterIP,
+ Selector: map[string]string{"app": "private-router"},
+ Ports: []corev1.ServicePort{
+ {
+ Name: "https",
+ Port: 443,
+ TargetPort: intstr.FromString("https"),
+ Protocol: corev1.ProtocolTCP,
+ },
+ },
+ },
+ },
+ },
+ setupEnv: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ hcpModifier: func(hcp *hyperv1.HostedControlPlane) {
+ hcp.Spec.Platform.Type = hyperv1.AzurePlatform
+ hcp.Spec.Platform.AWS = nil
+ hcp.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ }
+ },
+ },
+ {
+ name: "When ARO with both Swift annotation and API fields it should create only a ClusterIP private router service",
endpointAccess: hyperv1.Public,
exposeAPIServerThroughRouter: true,
expectedServices: []corev1.Service{
@@ -1619,6 +1730,14 @@ func TestReconcileHCPRouterServices(t *testing.T) {
hcp.Annotations = map[string]string{
hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
}
+ hcp.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "swift-network-instance",
+ },
+ },
+ }
},
},
}
@@ -1788,7 +1907,7 @@ func TestReconcileInternalRouterServiceStatus(t *testing.T) {
wantMsg string
}{
{
- name: "When ARO swift is enabled it should not need internal router",
+ name: "When ARO swift is enabled via annotation fallback it should not need internal router",
setup: func(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
@@ -1811,6 +1930,63 @@ func TestReconcileInternalRouterServiceStatus(t *testing.T) {
},
wantNeeded: false,
},
+ {
+ name: "When ARO swift is enabled via API field it should not need internal router",
+ setup: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ hcp: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test-hcp",
+ Namespace: "test-namespace",
+ },
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Location: "eastus",
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "swift-network-instance",
+ },
+ },
+ },
+ },
+ },
+ },
+ wantNeeded: false,
+ },
+ {
+ name: "When ARO swift is enabled via both annotation and API field it should not need internal router",
+ setup: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ hcp: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test-hcp",
+ Namespace: "test-namespace",
+ Annotations: map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
+ },
+ },
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Location: "eastus",
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "swift-network-instance",
+ },
+ },
+ },
+ },
+ },
+ },
+ wantNeeded: false,
+ },
}
for _, tc := range testCases {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_And_Swift.yaml b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml
similarity index 100%
rename from control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_And_Swift.yaml
rename to control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress.yaml b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_AnnotationFallback.yaml
similarity index 85%
rename from control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress.yaml
rename to control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_AnnotationFallback.yaml
index be61f321699..b343e2bfb91 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_AnnotationFallback.yaml
@@ -5,6 +5,7 @@ routes:
haproxy.router.openshift.io/balance: roundrobin
labels:
hypershift.openshift.io/hosted-control-plane: test-namespace
+ hypershift.openshift.io/internal-route: "true"
name: konnectivity-server
namespace: test-namespace
ownerReferences:
@@ -15,7 +16,7 @@ routes:
name: test-cluster
uid: ""
spec:
- host: konnectivity.test.example.com
+ host: konnectivity-server.apps.test-cluster.hypershift.local
tls:
insecureEdgeTerminationPolicy: None
termination: passthrough
@@ -91,6 +92,29 @@ routes:
name: oauth-openshift
weight: null
status: {}
+ - metadata:
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ hypershift.openshift.io/internal-route: "true"
+ name: oauth-internal
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: oauth.apps.test-cluster.hypershift.local
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: oauth-openshift
+ weight: null
+ status: {}
metadata: {}
services:
items:
@@ -237,4 +261,20 @@ services:
type: ClusterIP
status:
loadBalancer: {}
+ - metadata:
+ labels:
+ app: private-router
+ name: private-router
+ namespace: test-namespace
+ spec:
+ ports:
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: https
+ selector:
+ app: private-router
+ type: ClusterIP
+ status:
+ loadBalancer: {}
metadata: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml
new file mode 100644
index 00000000000..b343e2bfb91
--- /dev/null
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml
@@ -0,0 +1,280 @@
+routes:
+ items:
+ - metadata:
+ annotations:
+ haproxy.router.openshift.io/balance: roundrobin
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ hypershift.openshift.io/internal-route: "true"
+ name: konnectivity-server
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: konnectivity-server.apps.test-cluster.hypershift.local
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: konnectivity-server
+ weight: null
+ status: {}
+ - metadata:
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ name: kube-apiserver
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: api.test.example.com
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: kube-apiserver
+ weight: null
+ status: {}
+ - metadata:
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ hypershift.openshift.io/internal-route: "true"
+ name: kube-apiserver-internal
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: api.test-cluster.hypershift.local
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: kube-apiserver
+ weight: null
+ status: {}
+ - metadata:
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ name: oauth
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: oauth.test.example.com
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: oauth-openshift
+ weight: null
+ status: {}
+ - metadata:
+ labels:
+ hypershift.openshift.io/hosted-control-plane: test-namespace
+ hypershift.openshift.io/internal-route: "true"
+ name: oauth-internal
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ host: oauth.apps.test-cluster.hypershift.local
+ tls:
+ insecureEdgeTerminationPolicy: None
+ termination: passthrough
+ to:
+ kind: Service
+ name: oauth-openshift
+ weight: null
+ status: {}
+ metadata: {}
+services:
+ items:
+ - metadata:
+ name: konnectivity-server
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ports:
+ - port: 8091
+ protocol: TCP
+ targetPort: 8091
+ selector:
+ app: kube-apiserver
+ hypershift.openshift.io/control-plane-component: kube-apiserver
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ labels:
+ app: kube-apiserver
+ hypershift.openshift.io/control-plane-component: kube-apiserver
+ name: kube-apiserver
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ipFamilyPolicy: PreferDualStack
+ ports:
+ - port: 6443
+ protocol: TCP
+ targetPort: client
+ selector:
+ app: kube-apiserver
+ hypershift.openshift.io/control-plane-component: kube-apiserver
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ name: oauth-openshift
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ipFamilyPolicy: PreferDualStack
+ ports:
+ - port: 6443
+ protocol: TCP
+ targetPort: 6443
+ selector:
+ app: oauth-openshift
+ hypershift.openshift.io/control-plane-component: oauth-openshift
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ labels:
+ app: openshift-apiserver
+ hypershift.openshift.io/control-plane-component: openshift-apiserver
+ name: openshift-apiserver
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ports:
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 8443
+ selector:
+ app: openshift-apiserver
+ hypershift.openshift.io/control-plane-component: openshift-apiserver
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ labels:
+ app: openshift-apiserver
+ hypershift.openshift.io/control-plane-component: openshift-apiserver
+ name: openshift-oauth-apiserver
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ports:
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 8443
+ selector:
+ app: openshift-oauth-apiserver
+ hypershift.openshift.io/control-plane-component: openshift-oauth-apiserver
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ labels:
+ app: openshift-apiserver
+ hypershift.openshift.io/control-plane-component: openshift-apiserver
+ name: packageserver
+ namespace: test-namespace
+ ownerReferences:
+ - apiVersion: hypershift.openshift.io/v1beta1
+ blockOwnerDeletion: true
+ controller: true
+ kind: HostedControlPlane
+ name: test-cluster
+ uid: ""
+ spec:
+ ports:
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 5443
+ selector:
+ app: packageserver
+ hypershift.openshift.io/control-plane-component: packageserver
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ - metadata:
+ labels:
+ app: private-router
+ name: private-router
+ namespace: test-namespace
+ spec:
+ ports:
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: https
+ selector:
+ app: private-router
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+ metadata: {}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck_test.go b/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck_test.go
index df1ddedcad7..04539407885 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/kas/healthcheck_test.go
@@ -64,7 +64,24 @@ func TestGetHealthcheckEndpoint(t *testing.T) {
},
},
},
- hcp: &hyperv1.HostedControlPlane{},
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
useSharedIngress: true,
expectedEndpoint: "route.example.com",
expectedPort: sharedingress.ExternalDNSLBPort,
@@ -85,6 +102,20 @@ func TestGetHealthcheckEndpoint(t *testing.T) {
},
hcp: &hyperv1.HostedControlPlane{
Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
Networking: hyperv1.ClusterNetworking{
APIServer: &hyperv1.APIServerNetworking{
AllowedCIDRBlocks: []hyperv1.CIDRBlock{"10.0.0.0/16"},
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
index 7e185cd1eb5..854f8ab8982 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
@@ -5,12 +5,12 @@ data:
"cloud": "",
"tenantId": "",
"useManagedIdentityExtension": false,
- "useFederatedWorkloadIdentityExtension": false,
+ "useFederatedWorkloadIdentityExtension": true,
"subscriptionId": "",
- "aadClientId": "",
+ "aadClientId": "myClientID",
"aadClientSecret": "",
"aadClientCertPath": "",
- "aadFederatedTokenFile": "",
+ "aadFederatedTokenFile": "/var/run/secrets/openshift/serviceaccount/token",
"aadMSIDataPlaneIdentityPath": "",
"resourceGroup": "",
"location": "",
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
index 6c4df55d61f..daa214bfed8 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
@@ -1,6 +1,6 @@
apiVersion: v1
data:
- cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IGZhbHNlLAogICJzdWJzY3JpcHRpb25JZCI6ICIiLAogICJhYWRDbGllbnRJZCI6ICIiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIiIsCiAgImFhZE1TSURhdGFQbGFuZUlkZW50aXR5UGF0aCI6ICIiLAogICJyZXNvdXJjZUdyb3VwIjogIiIsCiAgImxvY2F0aW9uIjogIiIsCiAgInZuZXROYW1lIjogIm15Vm5ldE5hbWUiLAogICJ2bmV0UmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAic3VibmV0TmFtZSI6ICJteVN1Ym5ldE5hbWUiLAogICJzZWN1cml0eUdyb3VwTmFtZSI6ICJteU5TR05hbWUiLAogICJzZWN1cml0eUdyb3VwUmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAicm91dGVUYWJsZU5hbWUiOiAiIiwKICAiY2xvdWRQcm92aWRlckJhY2tvZmYiOiB0cnVlLAogICJjbG91ZFByb3ZpZGVyQmFja29mZkR1cmF0aW9uIjogNiwKICAidXNlSW5zdGFuY2VNZXRhZGF0YSI6IHRydWUsCiAgImxvYWRCYWxhbmNlclNrdSI6ICJzdGFuZGFyZCIsCiAgImRpc2FibGVPdXRib3VuZFNOQVQiOiB0cnVlLAogICJsb2FkQmFsYW5jZXJOYW1lIjogIiIsCiAgImNsdXN0ZXJTZXJ2aWNlTG9hZEJhbGFuY2VySGVhbHRoUHJvYmVNb2RlIjogInNoYXJlZCIKfQ==
+ cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IHRydWUsCiAgInN1YnNjcmlwdGlvbklkIjogIiIsCiAgImFhZENsaWVudElkIjogIm15Q2xpZW50SUQiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIi92YXIvcnVuL3NlY3JldHMvb3BlbnNoaWZ0L3NlcnZpY2VhY2NvdW50L3Rva2VuIiwKICAiYWFkTVNJRGF0YVBsYW5lSWRlbnRpdHlQYXRoIjogIiIsCiAgInJlc291cmNlR3JvdXAiOiAiIiwKICAibG9jYXRpb24iOiAiIiwKICAidm5ldE5hbWUiOiAibXlWbmV0TmFtZSIsCiAgInZuZXRSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJzdWJuZXROYW1lIjogIm15U3VibmV0TmFtZSIsCiAgInNlY3VyaXR5R3JvdXBOYW1lIjogIm15TlNHTmFtZSIsCiAgInNlY3VyaXR5R3JvdXBSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJyb3V0ZVRhYmxlTmFtZSI6ICIiLAogICJjbG91ZFByb3ZpZGVyQmFja29mZiI6IHRydWUsCiAgImNsb3VkUHJvdmlkZXJCYWNrb2ZmRHVyYXRpb24iOiA2LAogICJ1c2VJbnN0YW5jZU1ldGFkYXRhIjogdHJ1ZSwKICAibG9hZEJhbGFuY2VyU2t1IjogInN0YW5kYXJkIiwKICAiZGlzYWJsZU91dGJvdW5kU05BVCI6IHRydWUsCiAgImxvYWRCYWxhbmNlck5hbWUiOiAiIiwKICAiY2x1c3RlclNlcnZpY2VMb2FkQmFsYW5jZXJIZWFsdGhQcm9iZU1vZGUiOiAic2hhcmVkIgp9
kind: Secret
metadata:
name: azure-cloud-config
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
index 82e9a468ede..f04b83971e7 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/GCP/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
@@ -25,7 +25,7 @@ spec:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: cloud-token,tmp-dir
- component.hypershift.openshift.io/config-hash: 6390db5f
+ component.hypershift.openshift.io/config-hash: 5e25069a
hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
labels:
app: cloud-controller-manager
@@ -139,6 +139,7 @@ spec:
- mountPath: /etc/kubernetes
name: kubeconfig
priorityClassName: hypershift-control-plane
+ serviceAccountName: azure-cloud-controller-manager
tolerations:
- effect: NoSchedule
key: hypershift.openshift.io/control-plane
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
index 7e185cd1eb5..854f8ab8982 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
@@ -5,12 +5,12 @@ data:
"cloud": "",
"tenantId": "",
"useManagedIdentityExtension": false,
- "useFederatedWorkloadIdentityExtension": false,
+ "useFederatedWorkloadIdentityExtension": true,
"subscriptionId": "",
- "aadClientId": "",
+ "aadClientId": "myClientID",
"aadClientSecret": "",
"aadClientCertPath": "",
- "aadFederatedTokenFile": "",
+ "aadFederatedTokenFile": "/var/run/secrets/openshift/serviceaccount/token",
"aadMSIDataPlaneIdentityPath": "",
"resourceGroup": "",
"location": "",
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
index 6c4df55d61f..daa214bfed8 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
@@ -1,6 +1,6 @@
apiVersion: v1
data:
- cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IGZhbHNlLAogICJzdWJzY3JpcHRpb25JZCI6ICIiLAogICJhYWRDbGllbnRJZCI6ICIiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIiIsCiAgImFhZE1TSURhdGFQbGFuZUlkZW50aXR5UGF0aCI6ICIiLAogICJyZXNvdXJjZUdyb3VwIjogIiIsCiAgImxvY2F0aW9uIjogIiIsCiAgInZuZXROYW1lIjogIm15Vm5ldE5hbWUiLAogICJ2bmV0UmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAic3VibmV0TmFtZSI6ICJteVN1Ym5ldE5hbWUiLAogICJzZWN1cml0eUdyb3VwTmFtZSI6ICJteU5TR05hbWUiLAogICJzZWN1cml0eUdyb3VwUmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAicm91dGVUYWJsZU5hbWUiOiAiIiwKICAiY2xvdWRQcm92aWRlckJhY2tvZmYiOiB0cnVlLAogICJjbG91ZFByb3ZpZGVyQmFja29mZkR1cmF0aW9uIjogNiwKICAidXNlSW5zdGFuY2VNZXRhZGF0YSI6IHRydWUsCiAgImxvYWRCYWxhbmNlclNrdSI6ICJzdGFuZGFyZCIsCiAgImRpc2FibGVPdXRib3VuZFNOQVQiOiB0cnVlLAogICJsb2FkQmFsYW5jZXJOYW1lIjogIiIsCiAgImNsdXN0ZXJTZXJ2aWNlTG9hZEJhbGFuY2VySGVhbHRoUHJvYmVNb2RlIjogInNoYXJlZCIKfQ==
+ cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IHRydWUsCiAgInN1YnNjcmlwdGlvbklkIjogIiIsCiAgImFhZENsaWVudElkIjogIm15Q2xpZW50SUQiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIi92YXIvcnVuL3NlY3JldHMvb3BlbnNoaWZ0L3NlcnZpY2VhY2NvdW50L3Rva2VuIiwKICAiYWFkTVNJRGF0YVBsYW5lSWRlbnRpdHlQYXRoIjogIiIsCiAgInJlc291cmNlR3JvdXAiOiAiIiwKICAibG9jYXRpb24iOiAiIiwKICAidm5ldE5hbWUiOiAibXlWbmV0TmFtZSIsCiAgInZuZXRSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJzdWJuZXROYW1lIjogIm15U3VibmV0TmFtZSIsCiAgInNlY3VyaXR5R3JvdXBOYW1lIjogIm15TlNHTmFtZSIsCiAgInNlY3VyaXR5R3JvdXBSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJyb3V0ZVRhYmxlTmFtZSI6ICIiLAogICJjbG91ZFByb3ZpZGVyQmFja29mZiI6IHRydWUsCiAgImNsb3VkUHJvdmlkZXJCYWNrb2ZmRHVyYXRpb24iOiA2LAogICJ1c2VJbnN0YW5jZU1ldGFkYXRhIjogdHJ1ZSwKICAibG9hZEJhbGFuY2VyU2t1IjogInN0YW5kYXJkIiwKICAiZGlzYWJsZU91dGJvdW5kU05BVCI6IHRydWUsCiAgImxvYWRCYWxhbmNlck5hbWUiOiAiIiwKICAiY2x1c3RlclNlcnZpY2VMb2FkQmFsYW5jZXJIZWFsdGhQcm9iZU1vZGUiOiAic2hhcmVkIgp9
kind: Secret
metadata:
name: azure-cloud-config
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
index 46764bcf7cb..c1fc8dcb56c 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/IBMCloud/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
@@ -25,7 +25,7 @@ spec:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: tmp-dir
- component.hypershift.openshift.io/config-hash: 6390db5f
+ component.hypershift.openshift.io/config-hash: 5e25069a
hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
labels:
app: cloud-controller-manager
@@ -94,6 +94,7 @@ spec:
- mountPath: /tmp
name: tmp-dir
priorityClassName: hypershift-control-plane
+ serviceAccountName: azure-cloud-controller-manager
tolerations:
- effect: NoSchedule
key: hypershift.openshift.io/control-plane
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
index 7e185cd1eb5..854f8ab8982 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
@@ -5,12 +5,12 @@ data:
"cloud": "",
"tenantId": "",
"useManagedIdentityExtension": false,
- "useFederatedWorkloadIdentityExtension": false,
+ "useFederatedWorkloadIdentityExtension": true,
"subscriptionId": "",
- "aadClientId": "",
+ "aadClientId": "myClientID",
"aadClientSecret": "",
"aadClientCertPath": "",
- "aadFederatedTokenFile": "",
+ "aadFederatedTokenFile": "/var/run/secrets/openshift/serviceaccount/token",
"aadMSIDataPlaneIdentityPath": "",
"resourceGroup": "",
"location": "",
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
index 6c4df55d61f..daa214bfed8 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
@@ -1,6 +1,6 @@
apiVersion: v1
data:
- cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IGZhbHNlLAogICJzdWJzY3JpcHRpb25JZCI6ICIiLAogICJhYWRDbGllbnRJZCI6ICIiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIiIsCiAgImFhZE1TSURhdGFQbGFuZUlkZW50aXR5UGF0aCI6ICIiLAogICJyZXNvdXJjZUdyb3VwIjogIiIsCiAgImxvY2F0aW9uIjogIiIsCiAgInZuZXROYW1lIjogIm15Vm5ldE5hbWUiLAogICJ2bmV0UmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAic3VibmV0TmFtZSI6ICJteVN1Ym5ldE5hbWUiLAogICJzZWN1cml0eUdyb3VwTmFtZSI6ICJteU5TR05hbWUiLAogICJzZWN1cml0eUdyb3VwUmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAicm91dGVUYWJsZU5hbWUiOiAiIiwKICAiY2xvdWRQcm92aWRlckJhY2tvZmYiOiB0cnVlLAogICJjbG91ZFByb3ZpZGVyQmFja29mZkR1cmF0aW9uIjogNiwKICAidXNlSW5zdGFuY2VNZXRhZGF0YSI6IHRydWUsCiAgImxvYWRCYWxhbmNlclNrdSI6ICJzdGFuZGFyZCIsCiAgImRpc2FibGVPdXRib3VuZFNOQVQiOiB0cnVlLAogICJsb2FkQmFsYW5jZXJOYW1lIjogIiIsCiAgImNsdXN0ZXJTZXJ2aWNlTG9hZEJhbGFuY2VySGVhbHRoUHJvYmVNb2RlIjogInNoYXJlZCIKfQ==
+ cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IHRydWUsCiAgInN1YnNjcmlwdGlvbklkIjogIiIsCiAgImFhZENsaWVudElkIjogIm15Q2xpZW50SUQiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIi92YXIvcnVuL3NlY3JldHMvb3BlbnNoaWZ0L3NlcnZpY2VhY2NvdW50L3Rva2VuIiwKICAiYWFkTVNJRGF0YVBsYW5lSWRlbnRpdHlQYXRoIjogIiIsCiAgInJlc291cmNlR3JvdXAiOiAiIiwKICAibG9jYXRpb24iOiAiIiwKICAidm5ldE5hbWUiOiAibXlWbmV0TmFtZSIsCiAgInZuZXRSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJzdWJuZXROYW1lIjogIm15U3VibmV0TmFtZSIsCiAgInNlY3VyaXR5R3JvdXBOYW1lIjogIm15TlNHTmFtZSIsCiAgInNlY3VyaXR5R3JvdXBSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJyb3V0ZVRhYmxlTmFtZSI6ICIiLAogICJjbG91ZFByb3ZpZGVyQmFja29mZiI6IHRydWUsCiAgImNsb3VkUHJvdmlkZXJCYWNrb2ZmRHVyYXRpb24iOiA2LAogICJ1c2VJbnN0YW5jZU1ldGFkYXRhIjogdHJ1ZSwKICAibG9hZEJhbGFuY2VyU2t1IjogInN0YW5kYXJkIiwKICAiZGlzYWJsZU91dGJvdW5kU05BVCI6IHRydWUsCiAgImxvYWRCYWxhbmNlck5hbWUiOiAiIiwKICAiY2x1c3RlclNlcnZpY2VMb2FkQmFsYW5jZXJIZWFsdGhQcm9iZU1vZGUiOiAic2hhcmVkIgp9
kind: Secret
metadata:
name: azure-cloud-config
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
index db98131c478..355ee94448a 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
@@ -25,7 +25,7 @@ spec:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: cloud-token,tmp-dir
- component.hypershift.openshift.io/config-hash: 6390db5f
+ component.hypershift.openshift.io/config-hash: 5e25069a
hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
labels:
app: cloud-controller-manager
@@ -128,6 +128,7 @@ spec:
- mountPath: /etc/kubernetes
name: kubeconfig
priorityClassName: hypershift-control-plane
+ serviceAccountName: azure-cloud-controller-manager
tolerations:
- effect: NoSchedule
key: hypershift.openshift.io/control-plane
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
index 7e185cd1eb5..854f8ab8982 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_configmap.yaml
@@ -5,12 +5,12 @@ data:
"cloud": "",
"tenantId": "",
"useManagedIdentityExtension": false,
- "useFederatedWorkloadIdentityExtension": false,
+ "useFederatedWorkloadIdentityExtension": true,
"subscriptionId": "",
- "aadClientId": "",
+ "aadClientId": "myClientID",
"aadClientSecret": "",
"aadClientCertPath": "",
- "aadFederatedTokenFile": "",
+ "aadFederatedTokenFile": "/var/run/secrets/openshift/serviceaccount/token",
"aadMSIDataPlaneIdentityPath": "",
"resourceGroup": "",
"location": "",
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
index 6c4df55d61f..daa214bfed8 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_config_secret.yaml
@@ -1,6 +1,6 @@
apiVersion: v1
data:
- cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IGZhbHNlLAogICJzdWJzY3JpcHRpb25JZCI6ICIiLAogICJhYWRDbGllbnRJZCI6ICIiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIiIsCiAgImFhZE1TSURhdGFQbGFuZUlkZW50aXR5UGF0aCI6ICIiLAogICJyZXNvdXJjZUdyb3VwIjogIiIsCiAgImxvY2F0aW9uIjogIiIsCiAgInZuZXROYW1lIjogIm15Vm5ldE5hbWUiLAogICJ2bmV0UmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAic3VibmV0TmFtZSI6ICJteVN1Ym5ldE5hbWUiLAogICJzZWN1cml0eUdyb3VwTmFtZSI6ICJteU5TR05hbWUiLAogICJzZWN1cml0eUdyb3VwUmVzb3VyY2VHcm91cCI6ICJteVJlc291cmNlR3JvdXBOYW1lIiwKICAicm91dGVUYWJsZU5hbWUiOiAiIiwKICAiY2xvdWRQcm92aWRlckJhY2tvZmYiOiB0cnVlLAogICJjbG91ZFByb3ZpZGVyQmFja29mZkR1cmF0aW9uIjogNiwKICAidXNlSW5zdGFuY2VNZXRhZGF0YSI6IHRydWUsCiAgImxvYWRCYWxhbmNlclNrdSI6ICJzdGFuZGFyZCIsCiAgImRpc2FibGVPdXRib3VuZFNOQVQiOiB0cnVlLAogICJsb2FkQmFsYW5jZXJOYW1lIjogIiIsCiAgImNsdXN0ZXJTZXJ2aWNlTG9hZEJhbGFuY2VySGVhbHRoUHJvYmVNb2RlIjogInNoYXJlZCIKfQ==
+ cloud.conf: ewogICJjbG91ZCI6ICIiLAogICJ0ZW5hbnRJZCI6ICIiLAogICJ1c2VNYW5hZ2VkSWRlbnRpdHlFeHRlbnNpb24iOiBmYWxzZSwKICAidXNlRmVkZXJhdGVkV29ya2xvYWRJZGVudGl0eUV4dGVuc2lvbiI6IHRydWUsCiAgInN1YnNjcmlwdGlvbklkIjogIiIsCiAgImFhZENsaWVudElkIjogIm15Q2xpZW50SUQiLAogICJhYWRDbGllbnRTZWNyZXQiOiAiIiwKICAiYWFkQ2xpZW50Q2VydFBhdGgiOiAiIiwKICAiYWFkRmVkZXJhdGVkVG9rZW5GaWxlIjogIi92YXIvcnVuL3NlY3JldHMvb3BlbnNoaWZ0L3NlcnZpY2VhY2NvdW50L3Rva2VuIiwKICAiYWFkTVNJRGF0YVBsYW5lSWRlbnRpdHlQYXRoIjogIiIsCiAgInJlc291cmNlR3JvdXAiOiAiIiwKICAibG9jYXRpb24iOiAiIiwKICAidm5ldE5hbWUiOiAibXlWbmV0TmFtZSIsCiAgInZuZXRSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJzdWJuZXROYW1lIjogIm15U3VibmV0TmFtZSIsCiAgInNlY3VyaXR5R3JvdXBOYW1lIjogIm15TlNHTmFtZSIsCiAgInNlY3VyaXR5R3JvdXBSZXNvdXJjZUdyb3VwIjogIm15UmVzb3VyY2VHcm91cE5hbWUiLAogICJyb3V0ZVRhYmxlTmFtZSI6ICIiLAogICJjbG91ZFByb3ZpZGVyQmFja29mZiI6IHRydWUsCiAgImNsb3VkUHJvdmlkZXJCYWNrb2ZmRHVyYXRpb24iOiA2LAogICJ1c2VJbnN0YW5jZU1ldGFkYXRhIjogdHJ1ZSwKICAibG9hZEJhbGFuY2VyU2t1IjogInN0YW5kYXJkIiwKICAiZGlzYWJsZU91dGJvdW5kU05BVCI6IHRydWUsCiAgImxvYWRCYWxhbmNlck5hbWUiOiAiIiwKICAiY2x1c3RlclNlcnZpY2VMb2FkQmFsYW5jZXJIZWFsdGhQcm9iZU1vZGUiOiAic2hhcmVkIgp9
kind: Secret
metadata:
name: azure-cloud-config
diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
index db98131c478..355ee94448a 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/azure-cloud-controller-manager/zz_fixture_TestControlPlaneComponents_azure_cloud_controller_manager_deployment.yaml
@@ -25,7 +25,7 @@ spec:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes: cloud-token,tmp-dir
- component.hypershift.openshift.io/config-hash: 6390db5f
+ component.hypershift.openshift.io/config-hash: 5e25069a
hypershift.openshift.io/release-image: quay.io/openshift-release-dev/ocp-release:4.16.10-x86_64
labels:
app: cloud-controller-manager
@@ -128,6 +128,7 @@ spec:
- mountPath: /etc/kubernetes
name: kubeconfig
priorityClassName: hypershift-control-plane
+ serviceAccountName: azure-cloud-controller-manager
tolerations:
- effect: NoSchedule
key: hypershift.openshift.io/control-plane
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go
index 7017deac878..8e1c5de8e35 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go
@@ -2033,6 +2033,20 @@ func TestReconcileAuthOIDC(t *testing.T) {
Namespace: testNamespace,
},
Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
Configuration: &hyperv1.ClusterConfiguration{
Authentication: &configv1.AuthenticationSpec{
Type: configv1.AuthenticationTypeOIDC,
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
index 668ffd25206..a2bb4c59082 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
@@ -1804,7 +1804,7 @@ func TestHostedClusterWatchesEverythingItCreates(t *testing.T) {
SubscriptionID: "12345678-1234-1234-1234-123456789abc",
SecurityGroupID: "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/test-resource-group/providers/Microsoft.Network/networkSecurityGroups/test-nsg",
AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
- AzureAuthenticationConfigType: "WorkloadIdentities",
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
WorkloadIdentities: &hyperv1.AzureWorkloadIdentities{
ImageRegistry: hyperv1.WorkloadIdentity{ClientID: "12345678-1234-1234-1234-123456789abc"},
Ingress: hyperv1.WorkloadIdentity{ClientID: "12345678-1234-1234-1234-123456789abc"},
@@ -1868,6 +1868,12 @@ func TestHostedClusterWatchesEverythingItCreates(t *testing.T) {
},
},
TenantID: "12345678-1234-1234-1234-123456789abc",
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
},
},
Release: hyperv1.Release{
@@ -5395,6 +5401,22 @@ func TestEnsureHostedResourcesAreEmpty(t *testing.T) {
Namespace: namespace,
},
}
+ if tc.setAROHCP {
+ hcluster.Spec.Platform = hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ }
+ }
// Create a Secret that would exist in the cluster
secret := &corev1.Secret{
@@ -6939,6 +6961,12 @@ func TestValidateAzureConfig(t *testing.T) {
Type: hyperv1.AzurePlatform,
Azure: &hyperv1.AzurePlatformSpec{
Topology: hyperv1.AzureTopologyPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
},
},
},
diff --git a/hypershift-operator/controllers/hostedcluster/network_policies.go b/hypershift-operator/controllers/hostedcluster/network_policies.go
index 1d94c5857f4..684fbbd710a 100644
--- a/hypershift-operator/controllers/hostedcluster/network_policies.go
+++ b/hypershift-operator/controllers/hostedcluster/network_policies.go
@@ -15,6 +15,7 @@ import (
"github.com/openshift/hypershift/support/awsutil"
"github.com/openshift/hypershift/support/capabilities"
"github.com/openshift/hypershift/support/config"
+ "github.com/openshift/hypershift/support/netutil"
"github.com/openshift/hypershift/support/rhobsmonitoring"
"github.com/openshift/hypershift/support/upsert"
diff --git a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy_test.go b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy_test.go
index 44b32b29ba3..c938f1a9962 100644
--- a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy_test.go
+++ b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy_test.go
@@ -396,6 +396,14 @@ kind: Config`
hc: hc(func(hc *hyperv1.HostedCluster) {
hc.Spec.Platform.Type = hyperv1.AzurePlatform
hc.Spec.Platform.AWS = nil
+ hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-swift-instance",
+ },
+ },
+ }
hc.ObjectMeta.Annotations = map[string]string{
hyperv1.SwiftPodNetworkInstanceAnnotation: "test-swift-instance",
}
@@ -422,13 +430,25 @@ kind: Config`
expectedHAProxyConfigContent: []string{"api.hc.hypershift.local:443"},
},
{
- name: "When ARO and no Swift is used (CI) it should use the shared ingress LB service IP, port 6443 and proxy protocol",
+ name: "When ARO shared ingress is used it should use the shared ingress LB service IP, port 6443 and proxy protocol",
setupEnv: func(t *testing.T) {
azureutil.SetAsAroHCPTest(t)
},
hc: hc(func(hc *hyperv1.HostedCluster) {
hc.Spec.Platform.Type = hyperv1.AzurePlatform
hc.Spec.Platform.AWS = nil
+ hc.Spec.Platform.Azure = &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublic,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ }
hc.Status.KubeConfig = &corev1.LocalObjectReference{Name: "kk"}
hc.Spec.Networking.ServiceNetwork = []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}}
hc.Spec.Services = []hyperv1.ServicePublishingStrategyMapping{
diff --git a/hypershift-operator/controllers/nodepool/apiserver-haproxy/testdata/zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO__and_no_Swift_is_used_CI__it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml b/hypershift-operator/controllers/nodepool/apiserver-haproxy/testdata/zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO_shared_ingress_is_used_it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml
similarity index 100%
rename from hypershift-operator/controllers/nodepool/apiserver-haproxy/testdata/zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO__and_no_Swift_is_used_CI__it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml
rename to hypershift-operator/controllers/nodepool/apiserver-haproxy/testdata/zz_fixture_TestReconcileHAProxyIgnitionConfig_When_ARO_shared_ingress_is_used_it_should_use_the_shared_ingress_LB_service_IP__port_6443_and_proxy_protocol.yaml
diff --git a/hypershift-operator/controllers/nodepool/nodepool_controller_test.go b/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
index 210b69afcef..2783e89f120 100644
--- a/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
+++ b/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
@@ -2652,12 +2652,29 @@ kind: Config`),
Namespace: "clusters",
},
Spec: hyperv1.HostedClusterSpec{
- Platform: hyperv1.PlatformSpec{
- Type: hyperv1.AWSPlatform,
- AWS: &hyperv1.AWSPlatformSpec{
- EndpointAccess: hyperv1.Public,
- },
- },
+ Platform: func() hyperv1.PlatformSpec {
+ if tc.useSharedIngress {
+ return hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{PodNetworkInstance: "test-pni"},
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ }
+ }
+ return hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ AWS: &hyperv1.AWSPlatformSpec{
+ EndpointAccess: hyperv1.Public,
+ },
+ }
+ }(),
Networking: hyperv1.ClusterNetworking{
ServiceNetwork: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
},
diff --git a/sharedingress-config-generator/config_test.go b/sharedingress-config-generator/config_test.go
index 53bd460f05c..962d6698e78 100644
--- a/sharedingress-config-generator/config_test.go
+++ b/sharedingress-config-generator/config_test.go
@@ -108,6 +108,21 @@ func TestGenerateConfig(t *testing.T) {
Spec: hyperv1.HostedClusterSpec{
ClusterID: "hc1-UUID",
KubeAPIServerDNSName: "kube-apiserver-public-custom.example.com",
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
},
},
routes: []client.Object{
@@ -139,6 +154,21 @@ func TestGenerateConfig(t *testing.T) {
},
},
},
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
},
},
routes: []client.Object{
@@ -174,14 +204,20 @@ func TestGenerateConfig(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "hc1",
Namespace: "test",
- Annotations: map[string]string{
- hyperv1.SwiftPodNetworkInstanceAnnotation: "test-swift-instance",
- },
},
Spec: hyperv1.HostedClusterSpec{
ClusterID: "hc1-UUID",
Platform: hyperv1.PlatformSpec{
Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ Topology: hyperv1.AzureTopologyPrivate,
+ },
},
},
},
diff --git a/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_ARO_Swift_is_enabled_it_should_skip_the_dataplane_kas_svc.cfg b/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_ARO_Swift_is_enabled_it_should_skip_the_dataplane_kas_svc.cfg
index f658e9893cf..0c125167bdc 100644
--- a/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_ARO_Swift_is_enabled_it_should_skip_the_dataplane_kas_svc.cfg
+++ b/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_ARO_Swift_is_enabled_it_should_skip_the_dataplane_kas_svc.cfg
@@ -39,10 +39,6 @@ frontend external-dns
tcp-request content set-var(sess.src_ip) src
log-format "%{+Q}o\ src_ip = %[var(sess.src_ip)], %ci:%cp / %si:%sp -> %fi:%fp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
- acl is_test-hc1-ignition req_ssl_sni -i ignition-server.example.com
- acl is_test-hc1-apiserver req_ssl_sni -i kube-apiserver-public.example.com
- use_backend test-hc1-ignition if is_test-hc1-ignition
- use_backend test-hc1-apiserver if is_test-hc1-apiserver
default_backend no-match
@@ -54,10 +50,6 @@ listen health_check_http_url
# Backends for the KAS SVCs to support traffic coming form the data plane via kubernetes.svc.
# Backends support any traffic coming from external DNS.
-backend test-hc1-ignition
- server test-hc1-ignition 1.1.1.1:443
-backend test-hc1-apiserver
- server test-hc1-apiserver 4.4.4.4:6443
backend no-match
tcp-request content reject
diff --git a/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_there_s_two_HostedClusters_with_all_their_Routes_and_SVCs_it_should_generate_the_config_with_frontends_and_backends_for_both.cfg b/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_there_s_two_HostedClusters_with_all_their_Routes_and_SVCs_it_should_generate_the_config_with_frontends_and_backends_for_both.cfg
index dac4686b904..d8ea59b32dc 100644
--- a/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_there_s_two_HostedClusters_with_all_their_Routes_and_SVCs_it_should_generate_the_config_with_frontends_and_backends_for_both.cfg
+++ b/sharedingress-config-generator/testdata/zz_fixture_TestGenerateConfig_When_there_s_two_HostedClusters_with_all_their_Routes_and_SVCs_it_should_generate_the_config_with_frontends_and_backends_for_both.cfg
@@ -27,12 +27,6 @@ frontend dataplane-kas-svc
# example output: cluster_id = "4954e6da-fc87-4e74-9861-05895fe9549d", "169.254.169.1":38984 -> "172.20.0.1":6443 [10/Jul/2024:14:02:09.943] "dataplane-kas-svc" ""/"" 11/8/90052 3373 -- 25/7/2/2/0 0/0
# see https://www.haproxy.com/blog/introduction-to-haproxy-logging
log-format "%{+Q}o\ cluster_id = %[var(sess.cluster_id)], %ci:%cp -> %fi:%fp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
- acl is_test-hc1-kube-apiserver var(sess.cluster_id) -m str hc1-UUID
- acl is_test-hc2-kube-apiserver var(sess.cluster_id) -m str hc2-UUID
- acl is_test-hc2-kube-apiserver_request_allowed fc_src 1.1.1.1/32
- acl is_test-hc2-kube-apiserver_request_allowed fc_src 192.168.1.1/24
- use_backend test-hc1-kube-apiserver if is_test-hc1-kube-apiserver
- use_backend test-hc2-kube-apiserver if is_test-hc2-kube-apiserver is_test-hc2-kube-apiserver_request_allowed
default_backend no-match
@@ -84,10 +78,6 @@ listen health_check_http_url
monitor-uri /haproxy_ready
# Backends for the KAS SVCs to support traffic coming form the data plane via kubernetes.svc.
-backend test-hc1-kube-apiserver
- server test-hc1-kube-apiserver 4.4.4.4:6443
-backend test-hc2-kube-apiserver
- server test-hc2-kube-apiserver 4.4.4.4:6443
# Backends support any traffic coming from external DNS.
backend test-hc1-ignition
diff --git a/support/azureutil/azureutil_test.go b/support/azureutil/azureutil_test.go
index e0dc89d3777..33edfdc6b23 100644
--- a/support/azureutil/azureutil_test.go
+++ b/support/azureutil/azureutil_test.go
@@ -188,6 +188,193 @@ func TestIsAroHCP(t *testing.T) {
}
}
+func TestIsAroHCPByHCP(t *testing.T) {
+ tests := []struct {
+ name string
+ hcp *hyperv1.HostedControlPlane
+ envVar string
+ expected bool
+ }{
+ {
+ name: "When AzureAuthenticationConfigType is ManagedIdentities it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ {
+ name: "When AzureAuthenticationConfigType is WorkloadIdentities it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeWorkloadIdentities,
+ },
+ },
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When platform is not Azure it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When Azure spec is nil it should fall back to env var",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ envVar: hyperv1.AroHCP,
+ expected: true,
+ },
+ {
+ name: "When Azure spec is nil and env var is not set it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When WorkloadIdentities with ARO HCP env var it should return false because API takes precedence",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeWorkloadIdentities,
+ },
+ },
+ },
+ },
+ },
+ envVar: hyperv1.AroHCP,
+ expected: false,
+ },
+ }
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ g := NewGomegaWithT(t)
+ if tc.envVar != "" {
+ t.Setenv("MANAGED_SERVICE", tc.envVar)
+ }
+ g.Expect(IsAroHCPByHCP(tc.hcp)).To(Equal(tc.expected))
+ })
+ }
+}
+
+func TestIsAroHCPByHC(t *testing.T) {
+ tests := []struct {
+ name string
+ hc *hyperv1.HostedCluster
+ envVar string
+ expected bool
+ }{
+ {
+ name: "When AzureAuthenticationConfigType is ManagedIdentities it should return true",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ {
+ name: "When AzureAuthenticationConfigType is WorkloadIdentities it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeWorkloadIdentities,
+ },
+ },
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When platform is not Azure it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When Azure spec is nil it should fall back to env var",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ envVar: hyperv1.AroHCP,
+ expected: true,
+ },
+ {
+ name: "When Azure spec is nil and env var is not set it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ expected: false,
+ },
+ }
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ g := NewGomegaWithT(t)
+ if tc.envVar != "" {
+ t.Setenv("MANAGED_SERVICE", tc.envVar)
+ }
+ g.Expect(IsAroHCPByHC(tc.hc)).To(Equal(tc.expected))
+ })
+ }
+}
+
func TestIsPrivateKeyVault(t *testing.T) {
tests := []struct {
name string
diff --git a/support/netutil/visibility_test.go b/support/netutil/visibility_test.go
index 1ae90a60d70..32cfc020a07 100644
--- a/support/netutil/visibility_test.go
+++ b/support/netutil/visibility_test.go
@@ -3,6 +3,8 @@ package netutil
import (
"testing"
+ . "github.com/onsi/gomega"
+
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -103,8 +105,22 @@ func baseVisibilityCases() []visibilityCase {
wantPublic: true,
},
{
- name: "When is ARO with Swift it should be public and private",
- platformType: hyperv1.NonePlatform,
+ name: "When Azure topology is PublicAndPrivate it should be public and private",
+ platformType: hyperv1.AzurePlatform,
+ azureTopology: hyperv1.AzureTopologyPublicAndPrivate,
+ wantPrivate: true,
+ wantPublic: true,
+ },
+ {
+ name: "When Azure topology is Private it should be private and not public",
+ platformType: hyperv1.AzurePlatform,
+ azureTopology: hyperv1.AzureTopologyPrivate,
+ wantPrivate: true,
+ wantPublic: false,
+ },
+ {
+ name: "When Azure topology is empty with Swift annotation fallback it should be private and public",
+ platformType: hyperv1.AzurePlatform,
setupEnv: func(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
@@ -222,8 +238,41 @@ func TestLabelHCPRoutes(t *testing.T) {
}{
// Shared Ingress Tests
{
- name: "When shared ingress is active (ARO HCP), it should always label routes regardless of platform",
+ name: "When Swift networking is active via API field, it should always label routes",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-swift-instance",
+ },
+ },
+ },
+ },
+ Services: []hyperv1.ServicePublishingStrategyMapping{
+ {
+ Service: hyperv1.APIServer,
+ ServicePublishingStrategy: hyperv1.ServicePublishingStrategy{
+ Type: hyperv1.LoadBalancer,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When Swift networking is active via annotation fallback, it should always label routes",
hcp: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Annotations: map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "test-swift-instance",
+ },
+ },
Spec: hyperv1.HostedControlPlaneSpec{
Platform: hyperv1.PlatformSpec{
Type: hyperv1.AzurePlatform,
@@ -996,3 +1045,509 @@ func TestLabelHCPRoutes(t *testing.T) {
})
}
}
+
+func TestUseSwiftNetworkingHCP(t *testing.T) {
+ tests := []struct {
+ name string
+ hcp *hyperv1.HostedControlPlane
+ setupEnv func(t *testing.T)
+ want bool
+ }{
+ {
+ name: "When Azure platform with Private.Type=Swift it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When Azure platform with annotation fallback it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Annotations: map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "test-pni",
+ },
+ },
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ setupEnv: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ want: true,
+ },
+ {
+ name: "When Azure platform with neither API field nor annotation it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{},
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When AWS platform it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ AWS: &hyperv1.AWSPlatformSpec{},
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When Azure platform with Private.Type=PrivateLink it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypePrivateLink,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ if tt.setupEnv != nil {
+ tt.setupEnv(t)
+ }
+ g.Expect(UseSwiftNetworkingHCP(tt.hcp)).To(Equal(tt.want))
+ })
+ }
+}
+
+func TestUseSwiftNetworkingHC(t *testing.T) {
+ tests := []struct {
+ name string
+ hc *hyperv1.HostedCluster
+ setupEnv func(t *testing.T)
+ want bool
+ }{
+ {
+ name: "When Azure platform with Private.Type=Swift it should return true",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When Azure platform with annotation fallback it should return true",
+ hc: &hyperv1.HostedCluster{
+ ObjectMeta: metav1.ObjectMeta{
+ Annotations: map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "test-pni",
+ },
+ },
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ },
+ },
+ },
+ setupEnv: func(t *testing.T) {
+ t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
+ },
+ want: true,
+ },
+ {
+ name: "When Azure platform with neither API field nor annotation it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{},
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When AWS platform it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ AWS: &hyperv1.AWSPlatformSpec{},
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When Azure platform with Private.Type=PrivateLink it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypePrivateLink,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ if tt.setupEnv != nil {
+ tt.setupEnv(t)
+ }
+ g.Expect(UseSwiftNetworkingHC(tt.hc)).To(Equal(tt.want))
+ })
+ }
+}
+
+func TestUseSharedIngressHCP(t *testing.T) {
+ tests := []struct {
+ name string
+ hcp *hyperv1.HostedControlPlane
+ want bool
+ }{
+ {
+ name: "When Swift with PublicAndPrivate topology it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When Swift with Private topology it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When Swift with empty topology it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When ManagedIdentities without Swift and empty topology it should return true",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When non-Swift it should return false",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypePrivateLink,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(UseSharedIngressHCP(tt.hcp)).To(Equal(tt.want))
+ })
+ }
+}
+
+func TestUseSharedIngressHC(t *testing.T) {
+ tests := []struct {
+ name string
+ hc *hyperv1.HostedCluster
+ want bool
+ }{
+ {
+ name: "When Swift with PublicAndPrivate topology it should return true",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When Swift with Private topology it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ {
+ name: "When Swift with empty topology it should return true",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When ManagedIdentities without Swift and empty topology it should return true",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ AzureAuthenticationConfig: hyperv1.AzureAuthenticationConfiguration{
+ AzureAuthenticationConfigType: hyperv1.AzureAuthenticationTypeManagedIdentities,
+ },
+ },
+ },
+ },
+ },
+ want: true,
+ },
+ {
+ name: "When non-Swift it should return false",
+ hc: &hyperv1.HostedCluster{
+ Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Topology: hyperv1.AzureTopologyPublicAndPrivate,
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypePrivateLink,
+ },
+ },
+ },
+ },
+ },
+ want: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(UseSharedIngressHC(tt.hc)).To(Equal(tt.want))
+ })
+ }
+}
+
+func TestSwiftPodNetworkInstanceHCP(t *testing.T) {
+ tests := []struct {
+ name string
+ hcp *hyperv1.HostedControlPlane
+ want string
+ }{
+ {
+ name: "When Azure with Private.Type=Swift it should return PodNetworkInstance from API field",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{
+ Private: hyperv1.AzurePrivateSpec{
+ Type: hyperv1.AzurePrivateTypeSwift,
+ Swift: hyperv1.AzureSwiftSpec{
+ PodNetworkInstance: "test-pni",
+ },
+ },
+ },
+ },
+ },
+ },
+ want: "test-pni",
+ },
+ {
+ name: "When Azure with annotation fallback it should return value from annotation",
+ hcp: &hyperv1.HostedControlPlane{
+ ObjectMeta: metav1.ObjectMeta{
+ Annotations: map[string]string{
+ hyperv1.SwiftPodNetworkInstanceAnnotation: "annotation-pni",
+ },
+ },
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{},
+ },
+ },
+ },
+ want: "annotation-pni",
+ },
+ {
+ name: "When Azure with neither API field nor annotation it should return empty string",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AzurePlatform,
+ Azure: &hyperv1.AzurePlatformSpec{},
+ },
+ },
+ },
+ want: "",
+ },
+ {
+ name: "When non-Azure platform it should return empty string",
+ hcp: &hyperv1.HostedControlPlane{
+ Spec: hyperv1.HostedControlPlaneSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: hyperv1.AWSPlatform,
+ AWS: &hyperv1.AWSPlatformSpec{},
+ },
+ },
+ },
+ want: "",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ g := NewWithT(t)
+ g.Expect(SwiftPodNetworkInstanceHCP(tt.hcp)).To(Equal(tt.want))
+ })
+ }
+}
From e2aa9ffd86766a30106567143c758c34e3ac6591 Mon Sep 17 00:00:00 2001
From: Mulham Raee
Date: Mon, 8 Jun 2026 14:10:30 +0200
Subject: [PATCH 8/8] fix(cpo): handle Swift private topology in infra
reconciliation
Add UseSwiftNetworkingHCP to reconcileAPIServerServiceStatus so Swift
clusters resolve the KAS hostname from the Route strategy (via
KasRouteHostname helper) instead of falling through to LB service
lookup. Update infra tests to cover Swift Private and PublicAndPrivate
topologies separately, and fix test helper to skip simulating LB
provisioning for router services that are ClusterIP under Swift/shared
ingress.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../hostedcontrolplane/infra/infra.go | 2 +-
.../hostedcontrolplane/infra/infra_test.go | 48 ++++++++++---------
...frastructure_ARO_Route_Swift_Private.yaml} | 20 ++++----
...ure_ARO_Route_Swift_PublicAndPrivate.yaml} | 0
4 files changed, 38 insertions(+), 32 deletions(-)
rename control-plane-operator/controllers/hostedcontrolplane/infra/testdata/{zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml => zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_Private.yaml} (96%)
rename control-plane-operator/controllers/hostedcontrolplane/infra/testdata/{zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml => zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_PublicAndPrivate.yaml} (100%)
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
index 4e04c187d53..e299d9e5680 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go
@@ -526,7 +526,7 @@ func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *h
return "", 0, "", errors.New("APIServer service strategy not specified")
}
- if netutil.UseSharedIngressHCP(hcp) || (hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform && serviceStrategy.Type == hyperv1.Route) {
+ if netutil.UseSharedIngressHCP(hcp) || netutil.UseSwiftNetworkingHCP(hcp) || (hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform && serviceStrategy.Type == hyperv1.Route) {
return sharedingress.KasRouteHostname(hcp), sharedingress.ExternalDNSLBPort, "", nil
}
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
index 21ad694605b..76b6e254119 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go
@@ -535,10 +535,6 @@ func TestReconcileInfrastructure(t *testing.T) {
},
},
// ARO HCP test cases - use shared ingress
- // Three variants cover each Swift detection path independently:
- // 1. Annotation-only (legacy fallback: env var + annotation, no API fields)
- // 2. API-only (Private.Type=Swift, no annotation)
- // 3. Both annotation AND API fields (coexistence during migration)
{
name: "ARO_Route_SharedIngress_AnnotationFallback",
hcp: func() *hyperv1.HostedControlPlane {
@@ -555,8 +551,10 @@ func TestReconcileInfrastructure(t *testing.T) {
t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
},
expectError: false,
- // Legacy fallback: Swift detected via env var + annotation.
- // Same behavior as API field path: shared ingress, no routers.
+ // For ARO with shared ingress:
+ // - APIHost comes directly from strategy.Route.Hostname
+ // - Port is 443 (ExternalDNSLBPort)
+ // - No internal/external routers needed (shared ingress handles it)
expectedStatus: &InfrastructureStatus{
APIHost: testKASHostname,
APIPort: 443,
@@ -570,9 +568,10 @@ func TestReconcileInfrastructure(t *testing.T) {
},
},
{
- name: "ARO_Route_SharedIngress_APIField",
+ name: "ARO_Route_Swift_PublicAndPrivate",
hcp: func() *hyperv1.HostedControlPlane {
hcp := withServices(baseAzureHCP(), allServicesRouteWithHostnames())
+ hcp.Spec.Platform.Azure.Topology = hyperv1.AzureTopologyPublicAndPrivate
hcp.Spec.Platform.Azure.Private = hyperv1.AzurePrivateSpec{
Type: hyperv1.AzurePrivateTypeSwift,
Swift: hyperv1.AzureSwiftSpec{
@@ -584,12 +583,9 @@ func TestReconcileInfrastructure(t *testing.T) {
}
return hcp
}(),
- setupEnv: func(t *testing.T) {
- t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
- },
expectError: false,
- // New path: Swift detected via Private.Type=Swift API field.
- // Same behavior: shared ingress, no routers.
+ // New path: Swift detected via Private.Type=Swift API field with PublicAndPrivate topology.
+ // shared ingress for public access, internal router for private access.
expectedStatus: &InfrastructureStatus{
APIHost: testKASHostname,
APIPort: 443,
@@ -603,12 +599,13 @@ func TestReconcileInfrastructure(t *testing.T) {
},
},
{
- name: "ARO_Route_SharedIngress_Both",
+ name: "ARO_Route_Swift_Private",
hcp: func() *hyperv1.HostedControlPlane {
hcp := withServices(baseAzureHCP(), allServicesRouteWithHostnames())
hcp.Annotations = map[string]string{
hyperv1.SwiftPodNetworkInstanceAnnotation: "swift-network-instance",
}
+ hcp.Spec.Platform.Azure.Topology = hyperv1.AzureTopologyPrivate
hcp.Spec.Platform.Azure.Private = hyperv1.AzurePrivateSpec{
Type: hyperv1.AzurePrivateTypeSwift,
Swift: hyperv1.AzureSwiftSpec{
@@ -620,12 +617,9 @@ func TestReconcileInfrastructure(t *testing.T) {
}
return hcp
}(),
- setupEnv: func(t *testing.T) {
- t.Setenv("MANAGED_SERVICE", hyperv1.AroHCP)
- },
expectError: false,
- // Coexistence: both annotation and API field set during migration.
- // API field takes precedence; same behavior as API-only path.
+ // Swift detected via Private.Type=Swift API field with Private topology.
+ // No shared ingress needed, internal router needed.
expectedStatus: &InfrastructureStatus{
APIHost: testKASHostname,
APIPort: 443,
@@ -643,7 +637,7 @@ func TestReconcileInfrastructure(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewGomegaWithT(t)
- ctx := context.Background()
+ ctx := t.Context()
// Run optional environment setup
if tc.setupEnv != nil {
@@ -723,18 +717,26 @@ func TestReconcileInfrastructure(t *testing.T) {
// It unconditionally tries to provision all possible services/routes, ignoring "not found" errors.
func simulateInfraProvisioning(ctx context.Context, c client.Client, hcp *hyperv1.HostedControlPlane, externalRouterLBHost, internalRouterLBHost, kasLBHost string) error {
// List of all LoadBalancer services that might need provisioning
- lbServices := []struct {
+ type lbService struct {
svc *corev1.Service
hostname string
- }{
- {manifests.RouterPublicService(hcp.Namespace), externalRouterLBHost},
- {manifests.PrivateRouterService(hcp.Namespace), internalRouterLBHost},
+ }
+ lbServices := []lbService{
{manifests.KubeAPIServerService(hcp.Namespace), kasLBHost},
{manifests.KubeAPIServerPrivateService(hcp.Namespace), kasLBHost},
{manifests.KubeAPIServerServiceAzureLB(hcp.Namespace), kasLBHost},
{manifests.OauthServerService(hcp.Namespace), testOAuthLBHostname},
}
+ // If not using Swift or shared ingress, provision the public and private router services as LB services
+ // Otherwise, only private-router service is created as ClusterIP service.
+ if !netutil.UseSwiftNetworkingHCP(hcp) && !netutil.UseSharedIngressHCP(hcp) {
+ lbServices = append(lbServices, []lbService{
+ {manifests.RouterPublicService(hcp.Namespace), externalRouterLBHost},
+ {manifests.PrivateRouterService(hcp.Namespace), internalRouterLBHost},
+ }...)
+ }
+
for _, lb := range lbServices {
if err := simulateLBServiceProvisioned(ctx, c, lb.svc, lb.hostname); err != nil {
if !apierrors.IsNotFound(err) {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_Private.yaml
similarity index 96%
rename from control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml
rename to control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_Private.yaml
index b343e2bfb91..77f150075ce 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_Both.yaml
+++ b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_Private.yaml
@@ -28,7 +28,8 @@ routes:
- metadata:
labels:
hypershift.openshift.io/hosted-control-plane: test-namespace
- name: kube-apiserver
+ hypershift.openshift.io/internal-route: "true"
+ name: kube-apiserver-internal
namespace: test-namespace
ownerReferences:
- apiVersion: hypershift.openshift.io/v1beta1
@@ -38,7 +39,7 @@ routes:
name: test-cluster
uid: ""
spec:
- host: api.test.example.com
+ host: api.test-cluster.hypershift.local
tls:
insecureEdgeTerminationPolicy: None
termination: passthrough
@@ -51,7 +52,8 @@ routes:
labels:
hypershift.openshift.io/hosted-control-plane: test-namespace
hypershift.openshift.io/internal-route: "true"
- name: kube-apiserver-internal
+ hypershift.openshift.io/route-visibility: private
+ name: kube-apiserver-private
namespace: test-namespace
ownerReferences:
- apiVersion: hypershift.openshift.io/v1beta1
@@ -61,7 +63,7 @@ routes:
name: test-cluster
uid: ""
spec:
- host: api.test-cluster.hypershift.local
+ host: api.test.example.com
tls:
insecureEdgeTerminationPolicy: None
termination: passthrough
@@ -73,7 +75,8 @@ routes:
- metadata:
labels:
hypershift.openshift.io/hosted-control-plane: test-namespace
- name: oauth
+ hypershift.openshift.io/internal-route: "true"
+ name: oauth-internal
namespace: test-namespace
ownerReferences:
- apiVersion: hypershift.openshift.io/v1beta1
@@ -83,7 +86,7 @@ routes:
name: test-cluster
uid: ""
spec:
- host: oauth.test.example.com
+ host: oauth.apps.test-cluster.hypershift.local
tls:
insecureEdgeTerminationPolicy: None
termination: passthrough
@@ -96,7 +99,8 @@ routes:
labels:
hypershift.openshift.io/hosted-control-plane: test-namespace
hypershift.openshift.io/internal-route: "true"
- name: oauth-internal
+ hypershift.openshift.io/route-visibility: private
+ name: oauth-private
namespace: test-namespace
ownerReferences:
- apiVersion: hypershift.openshift.io/v1beta1
@@ -106,7 +110,7 @@ routes:
name: test-cluster
uid: ""
spec:
- host: oauth.apps.test-cluster.hypershift.local
+ host: oauth.test.example.com
tls:
insecureEdgeTerminationPolicy: None
termination: passthrough
diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml b/control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_PublicAndPrivate.yaml
similarity index 100%
rename from control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_SharedIngress_APIField.yaml
rename to control-plane-operator/controllers/hostedcontrolplane/infra/testdata/zz_fixture_TestReconcileInfrastructure_ARO_Route_Swift_PublicAndPrivate.yaml
|