Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions features.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
| GCPCustomAPIEndpoints| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| GCPCustomAPIEndpointsInstall| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| GCPDualStackInstall| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| GatewayAPIManagementMode| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| HyperShiftOnlyDynamicResourceAllocation| <span style="background-color: #519450">Enabled</span> | | <span style="background-color: #519450">Enabled</span> | | <span style="background-color: #519450">Enabled</span> | | <span style="background-color: #519450">Enabled</span> | |
| ImageModeStatusReporting| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| IngressControllerDynamicConfigurationManager| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
Expand Down
8 changes: 8 additions & 0 deletions features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,14 @@ var (
enable(inDefault(), inOKD(), inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()).
mustRegister()

FeatureGateGatewayAPIManagementMode = newFeatureGate("GatewayAPIManagementMode").
reportProblemsToJiraComponent("Routing").
contactPerson("miciah").
productScope(ocpSpecific).
enhancementPR("https://github.com/openshift/enhancements/pull/2023").
enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note that we are now enforcing that before a feature gate can be included in the TPNU feature set that the enhancement must be merged.

Please get the EP merged before we merge this - thanks!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the plan! :D

mustRegister()

FeatureGateTLSAdherence = newFeatureGate("TLSAdherence").
reportProblemsToJiraComponent("HPCASE / TLS Adherence").
contactPerson("joelanford").
Expand Down
276 changes: 276 additions & 0 deletions openapi/generated_openapi/zz_generated.openapi.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions operator/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&ClusterVersionOperatorList{},
&ClusterAPI{},
&ClusterAPIList{},
&Ingress{},
&IngressList{},
)

return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
name: "Ingress"
crdName: ingresses.operator.openshift.io
featureGate: GatewayAPIManagementMode
tests:
onCreate:
- name: Should be able to create a minimal Ingress with default managementMode
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec: {}
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec: {}
- name: Should not be able to create an Ingress with a custom name
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: custom-name
spec: {}
expectedError: "Invalid value: \"object\": ingress is a singleton; the .metadata.name field must be 'cluster'"
- name: Should be able to create an Ingress with managementMode set to Managed
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
- name: Should be able to create an Ingress with managementMode set to Unmanaged
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Unmanaged
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Unmanaged
- name: Should not be able to create an Ingress with an invalid managementMode
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: InvalidMode
expectedError: "spec.gatewayAPI.managementMode: Unsupported value: \"InvalidMode\": supported values: \"Managed\", \"Unmanaged\""
- name: Should default managementMode to Managed when gatewayAPI is specified without it
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI: {}
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
onUpdate:
- name: Should be able to update managementMode from Managed to Unmanaged
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
updated: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Unmanaged
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Unmanaged
- name: Should be able to update managementMode from Unmanaged to Managed
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Unmanaged
updated: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
expected: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
- name: Should not be able to update managementMode to an invalid value
initial: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: Managed
updated: |
apiVersion: operator.openshift.io/v1alpha1
kind: Ingress
metadata:
name: cluster
spec:
gatewayAPI:
managementMode: InvalidMode
expectedError: "spec.gatewayAPI.managementMode: Unsupported value: \"InvalidMode\": supported values: \"Managed\", \"Unmanaged\""
169 changes: 169 additions & 0 deletions operator/v1alpha1/types_ingress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package v1alpha1

import (
v1 "github.com/openshift/api/operator/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Ingress contains configuration options specific to the Ingress Operator itself.
//
// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
// +openshift:compatibility-gen:level=4
// +openshift:api-approved.openshift.io=<TBD>
// +openshift:file-pattern=cvoRunLevel=0000_50,operatorName=ingress,operatorOrdering=02
// +kubebuilder:object:root=true
// +kubebuilder:resource:path=ingresses,scope=Cluster
// +kubebuilder:subresource:status
// +openshift:capability=Ingress
// +openshift:enable:FeatureGate=GatewayAPIManagementMode
// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="ingress is a singleton; the .metadata.name field must be 'cluster'"
type Ingress struct {
metav1.TypeMeta `json:",inline"`

// metadata is the standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

// spec holds user settable values for configuration.
// +required
Spec IngressSpec `json:"spec,omitempty,omitzero"`
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// status holds observed values from the cluster.
// +optional
Status IngressStatus `json:"status,omitempty,omitzero"`
}

// IngressSpec defines the desired configuration of the cluster-ingress-operator
// +kubebuilder:validation:MinProperties=1
type IngressSpec struct {
// Inline OperatorSpec for standard operator fields
// (managementState, logLevel, etc.)
v1.OperatorSpec `json:",inline"`

// gatewayAPI holds configuration for Gateway API
// integration, including how the Cluster Ingress Operator
// manages Gateway API CRDs and the Gateway controller stack.
//
// When omitted, the operator uses the default Gateway API
// configuration, which sets managementMode to "Managed".
//
// +optional
// +openshift:enable:FeatureGate=GatewayAPIManagementMode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole API is gated, so we can drop this marker.

GatewayAPI GatewayAPIIngressConfig `json:"gatewayAPI,omitempty,omitzero"`
}

// IngressStatus describe the current state of cluster-ingress-operator
// +kubebuilder:validation:MinProperties=0
type IngressStatus struct {
// Inline OperatorStatus for standard operator status fields
// (conditions, version, observedGeneration, etc.).
// conditions holds a list of conditions representing the
// operator's current state. Gateway API CRD management
// conditions are reported here with the "GatewayAPI" prefix:
//
// "GatewayAPICRDsManaged" indicates whether CIO is actively
// managing Gateway API CRDs:
// - status: True, reason: "ManagedByCIO" — CIO is
// installing, protecting (via VAP), and upgrading CRDs.
// - status: False, reason: "Unmanaged" — the administrator
// chose Unmanaged mode; CIO does not manage CRDs or the
// Gateway controller stack.
//
// "GatewayAPICRDsPresent" indicates whether Gateway API CRDs
// exist on the cluster:
// - status: True, reason: "CRDsFound" — Gateway API CRDs
// are present on the cluster.
// - status: False, reason: "CRDsNotFound" — Gateway API
// CRDs are not present on the cluster.
//
// "GatewayAPICRDsCompliant" indicates whether the installed
// CRDs match the version expected by this CIO release:
// - status: True, reason: "VersionMatch" — installed CRDs
// match the expected version.
// - status: False, reason: "VersionMismatch" — installed
// CRDs do not match the expected version. The message
// includes expected and actual versions and a pointer
// to where valid manifests can be obtained.
// - status: Unknown, reason: "NotApplicable" — compliance
// check is not applicable (e.g., Unmanaged mode with no
// CRDs present).
v1.OperatorStatus `json:",inline"`
}

// GatewayAPIManagementMode describes how the Cluster Ingress
// Operator manages Gateway API Custom Resource Definitions.
//
// +kubebuilder:validation:Enum=Managed;Unmanaged
type GatewayAPIManagementMode string

const (
// GatewayAPIManagementModeManaged means CIO installs, owns,
// protects (via VAP), and upgrades the Gateway API CRDs.
// CIO also deploys the full Gateway controller stack (the
// Istio instance deployed by CIO, GatewayClass, Gateway).
// This is the default mode and the only fully supported
// configuration.
GatewayAPIManagementModeManaged GatewayAPIManagementMode = "Managed"

// GatewayAPIManagementModeUnmanaged means CIO does NOT
// install or manage Gateway API CRDs and does NOT deploy
// the Gateway controller stack. The customer or a
// third-party product is responsible for bringing their own
// CRDs and Gateway controller. CIO reports observational
// status only. This mode signals to layered products that
// the installed CRDs may not be the ones supported by the
// OpenShift Gateway API implementation.
GatewayAPIManagementModeUnmanaged GatewayAPIManagementMode = "Unmanaged"
)

// GatewayAPIIngressConfig holds configuration for Gateway API
// integration in the Cluster Ingress Operator.
// +kubebuilder:validation:MinProperties=1
type GatewayAPIIngressConfig struct {
// managementMode specifies how the Cluster Ingress
// Operator manages Gateway API Custom Resource Definitions
// (CRDs) and the associated Gateway controller stack.
//

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For enum fields, we generally encourage a sentence here that explicitly states what the set of allowed values are like:

Allowed values are Managed and Unmanaged.

// When set to "Managed" (the default), CIO installs, owns,
// and upgrades the Gateway API CRDs, protects them with a
// Validating Admission Policy, and deploys the full Gateway
// controller stack (the Istio instance deployed by CIO,
// GatewayClass, Gateway resources). This is the only fully
// supported configuration.
Comment on lines +135 to +136

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the current options seem like they would be considered "fully supported", so the final sentence here might be a bit misleading.

//
// When set to "Unmanaged", CIO does not install or manage
// Gateway API CRDs and does not deploy the Gateway controller
// stack. The cluster administrator or a third-party product
// is responsible for providing their own CRDs and Gateway
// controller. CIO reports observational status only. This
// mode also serves as a signal to layered products that the
// installed CRDs may not be the ones supported by the
// OpenShift Gateway API implementation.
//
// When omitted, the field defaults to "Managed".
//
// +default="Managed"
// +optional
Comment on lines +147 to +150

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this default marker does anything if the parent field isn't also specified, only if this field is explicitly omitted.

The minimum properties on this type inherently makes this field required when specifying the parent field.

I'm wondering, should this be a required field regardless? I'm not sure it makes sense to explicitly specify the Gateway API configuration field without explicitly providing the management mode you'd like to be in place.

ManagementMode GatewayAPIManagementMode `json:"managementMode,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// IngressList is a collection of Ingresses.
//
// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
// +openshift:compatibility-gen:level=4
type IngressList struct {
metav1.TypeMeta `json:",inline"`

// metadata is the standard list's metadata.
metav1.ListMeta `json:"metadata"`

// items is a list of Ingresses.
// +optional
Items []Ingress `json:"items,omitempty"`
}
Loading