diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index ca03cb5450f..769bed4ddab 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -922,6 +922,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/operator/v1.AuthenticationStatus": schema_openshift_api_operator_v1_AuthenticationStatus(ref), "github.com/openshift/api/operator/v1.AzureCSIDriverConfigSpec": schema_openshift_api_operator_v1_AzureCSIDriverConfigSpec(ref), "github.com/openshift/api/operator/v1.AzureDiskEncryptionSet": schema_openshift_api_operator_v1_AzureDiskEncryptionSet(ref), + "github.com/openshift/api/operator/v1.BootImageSkewEnforcementConfig": schema_openshift_api_operator_v1_BootImageSkewEnforcementConfig(ref), + "github.com/openshift/api/operator/v1.BootImageSkewEnforcementStatus": schema_openshift_api_operator_v1_BootImageSkewEnforcementStatus(ref), "github.com/openshift/api/operator/v1.CSIDriverConfigSpec": schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref), "github.com/openshift/api/operator/v1.CSISnapshotController": schema_openshift_api_operator_v1_CSISnapshotController(ref), "github.com/openshift/api/operator/v1.CSISnapshotControllerList": schema_openshift_api_operator_v1_CSISnapshotControllerList(ref), @@ -934,6 +936,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/operator/v1.CloudCredentialList": schema_openshift_api_operator_v1_CloudCredentialList(ref), "github.com/openshift/api/operator/v1.CloudCredentialSpec": schema_openshift_api_operator_v1_CloudCredentialSpec(ref), "github.com/openshift/api/operator/v1.CloudCredentialStatus": schema_openshift_api_operator_v1_CloudCredentialStatus(ref), + "github.com/openshift/api/operator/v1.ClusterBootImage": schema_openshift_api_operator_v1_ClusterBootImage(ref), "github.com/openshift/api/operator/v1.ClusterCSIDriver": schema_openshift_api_operator_v1_ClusterCSIDriver(ref), "github.com/openshift/api/operator/v1.ClusterCSIDriverList": schema_openshift_api_operator_v1_ClusterCSIDriverList(ref), "github.com/openshift/api/operator/v1.ClusterCSIDriverSpec": schema_openshift_api_operator_v1_ClusterCSIDriverSpec(ref), @@ -46927,6 +46930,95 @@ func schema_openshift_api_operator_v1_AzureDiskEncryptionSet(ref common.Referenc } } +func schema_openshift_api_operator_v1_BootImageSkewEnforcementConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "BootImageSkewEnforcementConfig is used to configure how boot image version skew is enforced on the cluster.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Description: "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Manual and None. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + Type: []string{"string"}, + Format: "", + }, + }, + "manual": { + SchemaProps: spec.SchemaProps{ + Description: "manual describes the current boot image of the cluster. This should be set to the oldest boot image used amongst all machine resources in the cluster. This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", + Ref: ref("github.com/openshift/api/operator/v1.ClusterBootImage"), + }, + }, + }, + Required: []string{"mode"}, + }, + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-unions": []interface{}{ + map[string]interface{}{ + "discriminator": "mode", + "fields-to-discriminateBy": map[string]interface{}{ + "manual": "Manual", + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.ClusterBootImage"}, + } +} + +func schema_openshift_api_operator_v1_BootImageSkewEnforcementStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "BootImageSkewEnforcementStatus is the type for the status object. It represents the cluster defaults when the boot image skew enforcement configuration is undefined and reflects the actual configuration when it is defined.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Description: "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Automatic, Manual and None. Automatic means that the MCO will perform boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + Type: []string{"string"}, + Format: "", + }, + }, + "automatic": { + SchemaProps: spec.SchemaProps{ + Description: "automatic describes the current boot image of the cluster. This will be populated by the MCO when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Automatic\" and forbidden otherwise.", + Ref: ref("github.com/openshift/api/operator/v1.ClusterBootImage"), + }, + }, + "manual": { + SchemaProps: spec.SchemaProps{ + Description: "manual describes the current boot image of the cluster. This will be populated by the cluster admin when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", + Ref: ref("github.com/openshift/api/operator/v1.ClusterBootImage"), + }, + }, + }, + Required: []string{"mode"}, + }, + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-unions": []interface{}{ + map[string]interface{}{ + "discriminator": "mode", + "fields-to-discriminateBy": map[string]interface{}{ + "automatic": "Automatic", + "manual": "Manual", + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/openshift/api/operator/v1.ClusterBootImage"}, + } +} + func schema_openshift_api_operator_v1_CSIDriverConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -47600,6 +47692,33 @@ func schema_openshift_api_operator_v1_CloudCredentialStatus(ref common.Reference } } +func schema_openshift_api_operator_v1_ClusterBootImage(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. At least one of these values are required. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ocpVersion": { + SchemaProps: spec.SchemaProps{ + Description: "ocpVersion provides a string which represents the OCP version of the boot image. This field must match the OCP semver compatible format of x.y.z. This field must be between 5 and 10 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + "rhcosVersion": { + SchemaProps: spec.SchemaProps{ + Description: "rhcosVersion provides a string which represents the RHCOS version of the boot image This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between 14 and 21 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_openshift_api_operator_v1_ClusterCSIDriver(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -53274,12 +53393,19 @@ func schema_openshift_api_operator_v1_MachineConfigurationSpec(ref common.Refere Ref: ref("github.com/openshift/api/operator/v1.IrreconcilableValidationOverrides"), }, }, + "bootImageSkewEnforcement": { + SchemaProps: spec.SchemaProps{ + Description: "bootImageSkewEnforcement allows an admin to configure how boot image version skew is enforced on the cluster. When omitted, this will default to Automatic for clusters that support automatic boot image updates. For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until a skew enforcement mode has been specified. When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed acceptable for the current release payload.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/operator/v1.BootImageSkewEnforcementConfig"), + }, + }, }, Required: []string{"managementState", "forceRedeploymentReason"}, }, }, Dependencies: []string{ - "github.com/openshift/api/operator/v1.IrreconcilableValidationOverrides", "github.com/openshift/api/operator/v1.ManagedBootImages", "github.com/openshift/api/operator/v1.NodeDisruptionPolicyConfig", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + "github.com/openshift/api/operator/v1.BootImageSkewEnforcementConfig", "github.com/openshift/api/operator/v1.IrreconcilableValidationOverrides", "github.com/openshift/api/operator/v1.ManagedBootImages", "github.com/openshift/api/operator/v1.NodeDisruptionPolicyConfig", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } @@ -53332,11 +53458,18 @@ func schema_openshift_api_operator_v1_MachineConfigurationStatus(ref common.Refe Ref: ref("github.com/openshift/api/operator/v1.ManagedBootImages"), }, }, + "bootImageSkewEnforcementStatus": { + SchemaProps: spec.SchemaProps{ + Description: "bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement configuration is and will be used by Machine Config Controller while performing boot image skew enforcement.", + Default: map[string]interface{}{}, + Ref: ref("github.com/openshift/api/operator/v1.BootImageSkewEnforcementStatus"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/openshift/api/operator/v1.ManagedBootImages", "github.com/openshift/api/operator/v1.NodeDisruptionPolicyStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + "github.com/openshift/api/operator/v1.BootImageSkewEnforcementStatus", "github.com/openshift/api/operator/v1.ManagedBootImages", "github.com/openshift/api/operator/v1.NodeDisruptionPolicyStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 42ee6c97da5..5cbb0a60192 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -27198,6 +27198,61 @@ } } }, + "com.github.openshift.api.operator.v1.BootImageSkewEnforcementConfig": { + "description": "BootImageSkewEnforcementConfig is used to configure how boot image version skew is enforced on the cluster.", + "type": "object", + "required": [ + "mode" + ], + "properties": { + "manual": { + "description": "manual describes the current boot image of the cluster. This should be set to the oldest boot image used amongst all machine resources in the cluster. This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", + "$ref": "#/definitions/com.github.openshift.api.operator.v1.ClusterBootImage" + }, + "mode": { + "description": "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Manual and None. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + "type": "string" + } + }, + "x-kubernetes-unions": [ + { + "discriminator": "mode", + "fields-to-discriminateBy": { + "manual": "Manual" + } + } + ] + }, + "com.github.openshift.api.operator.v1.BootImageSkewEnforcementStatus": { + "description": "BootImageSkewEnforcementStatus is the type for the status object. It represents the cluster defaults when the boot image skew enforcement configuration is undefined and reflects the actual configuration when it is defined.", + "type": "object", + "required": [ + "mode" + ], + "properties": { + "automatic": { + "description": "automatic describes the current boot image of the cluster. This will be populated by the MCO when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Automatic\" and forbidden otherwise.", + "$ref": "#/definitions/com.github.openshift.api.operator.v1.ClusterBootImage" + }, + "manual": { + "description": "manual describes the current boot image of the cluster. This will be populated by the cluster admin when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", + "$ref": "#/definitions/com.github.openshift.api.operator.v1.ClusterBootImage" + }, + "mode": { + "description": "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Automatic, Manual and None. Automatic means that the MCO will perform boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + "type": "string" + } + }, + "x-kubernetes-unions": [ + { + "discriminator": "mode", + "fields-to-discriminateBy": { + "automatic": "Automatic", + "manual": "Manual" + } + } + ] + }, "com.github.openshift.api.operator.v1.CSIDriverConfigSpec": { "description": "CSIDriverConfigSpec defines configuration spec that can be used to optionally configure a specific CSI Driver.", "type": "object", @@ -27604,6 +27659,20 @@ } } }, + "com.github.openshift.api.operator.v1.ClusterBootImage": { + "description": "ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. At least one of these values are required. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance.", + "type": "object", + "properties": { + "ocpVersion": { + "description": "ocpVersion provides a string which represents the OCP version of the boot image. This field must match the OCP semver compatible format of x.y.z. This field must be between 5 and 10 characters long.", + "type": "string" + }, + "rhcosVersion": { + "description": "rhcosVersion provides a string which represents the RHCOS version of the boot image This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between 14 and 21 characters long.", + "type": "string" + } + } + }, "com.github.openshift.api.operator.v1.ClusterCSIDriver": { "description": "ClusterCSIDriver object allows management and configuration of a CSI driver operator installed by default in OpenShift. Name of the object must be name of the CSI driver it operates. See CSIDriverName type for list of allowed values.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "type": "object", @@ -30929,6 +30998,11 @@ "forceRedeploymentReason" ], "properties": { + "bootImageSkewEnforcement": { + "description": "bootImageSkewEnforcement allows an admin to configure how boot image version skew is enforced on the cluster. When omitted, this will default to Automatic for clusters that support automatic boot image updates. For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until a skew enforcement mode has been specified. When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed acceptable for the current release payload.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.BootImageSkewEnforcementConfig" + }, "failedRevisionLimit": { "description": "failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api -1 = unlimited, 0 or unset = 5 (default)", "type": "integer", @@ -30985,6 +31059,11 @@ "com.github.openshift.api.operator.v1.MachineConfigurationStatus": { "type": "object", "properties": { + "bootImageSkewEnforcementStatus": { + "description": "bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement configuration is and will be used by Machine Config Controller while performing boot image skew enforcement.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.operator.v1.BootImageSkewEnforcementStatus" + }, "conditions": { "description": "conditions is a list of conditions and their status", "type": "array", diff --git a/operator/v1/tests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml b/operator/v1/tests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml new file mode 100644 index 00000000000..b47641a93b3 --- /dev/null +++ b/operator/v1/tests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml @@ -0,0 +1,239 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "MachineConfiguration" +crdName: machineconfigurations.operator.openshift.io +featureGates: +- BootImageSkewEnforcement +tests: + onCreate: + - name: Should be able to create a minimal MachineConfiguration + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} # No spec is required for a MachineConfiguration + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + - name: Should be able to create a manual BootImageSkewEnforcement configuration knob + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + - name: Should not be able to create an automatic BootImageSkewEnforcement configuration knob + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Automatic + expectedError: "Unsupported value: \"Automatic\": supported values: \"Manual\", \"None\"" + - name: Should be able to create a manual BootImageSkewEnforcement configuration knob with a legacy cluster boot image + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "416.94.202411201433-0" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "416.94.202411201433-0" + - name: Should be able to create a manual BootImageSkewEnforcement configuration knob with only ocpVersion defined + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + bootImageSkewEnforcement: + mode: Manual + manual: + ocpVersion: "4.18.2" + - name: Should be able to create a manual BootImageSkewEnforcement configuration knob with only rhcosVersion defined + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Manual + manual: + rhcosVersion: "416.94.202411201433-0" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + bootImageSkewEnforcement: + mode: Manual + manual: + rhcosVersion: "416.94.202411201433-0" + - name: Should be able to create a None BootImageSkewEnforcement configuration knob + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: None + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + bootImageSkewEnforcement: + mode: None + - name: Should not be able to add manual field if bootImageSkewEnforcement.mode is set to None + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: None + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + expectedError: "manual is required when mode is Manual, and forbidden otherwise" + - name: manual field should be set if bootImageSkewEnforcement.mode is set to Manual + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + bootImageSkewEnforcement: + mode: Manual + expectedError: "manual is required when mode is Manual, and forbidden otherwise" + onUpdate: + - name: Should not be able to add manual field in status if bootImageSkewEnforcementStatus.mode is set to None + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + updated: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + expectedStatusError: "manual is required when mode is Manual, and forbidden otherwise" + - name: Should not able to add automatic field in status if bootImageSkewEnforcementStatus.mode is set to None + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + updated: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + automatic: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + expectedStatusError: "automatic is required when mode is Automatic, and forbidden otherwise" + - name: Should be able to add manual field in status if bootImageSkewEnforcementStatus.mode is set to manual + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + updated: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + status: + bootImageSkewEnforcementStatus: + mode: Manual + manual: + ocpVersion: "4.18.2" + rhcosVersion: "9.6.20250523-1" + - name: Should be able to add automatic field in status if bootImageSkewEnforcementStatus.mode is set to automatic + initial: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: None + updated: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: {} + status: + bootImageSkewEnforcementStatus: + mode: Automatic + automatic: + ocpVersion: "4.18.2" + rhcosVersion: "416.94.202411201433-0" + expected: | + apiVersion: operator.openshift.io/v1 + kind: MachineConfiguration + spec: + logLevel: Normal + operatorLogLevel: Normal + status: + bootImageSkewEnforcementStatus: + mode: Automatic + automatic: + ocpVersion: "4.18.2" + rhcosVersion: "416.94.202411201433-0" diff --git a/operator/v1/types_machineconfiguration.go b/operator/v1/types_machineconfiguration.go index 8f779db2a6e..708fcbb4ca8 100644 --- a/operator/v1/types_machineconfiguration.go +++ b/operator/v1/types_machineconfiguration.go @@ -36,8 +36,6 @@ type MachineConfiguration struct { type MachineConfigurationSpec struct { StaticPodOperatorSpec `json:",inline"` - // TODO(jkyros): This is where we put our knobs and dials - // managedBootImages allows configuration for the management of boot images for machine // resources within the cluster. This configuration allows users to select resources that should // be updated to the latest boot images during cluster upgrades, ensuring that new machines @@ -65,8 +63,138 @@ type MachineConfigurationSpec struct { // +openshift:enable:FeatureGate=IrreconcilableMachineConfig // +optional IrreconcilableValidationOverrides IrreconcilableValidationOverrides `json:"irreconcilableValidationOverrides,omitempty,omitzero"` + + // bootImageSkewEnforcement allows an admin to configure how boot image version skew is + // enforced on the cluster. + // When omitted, this will default to Automatic for clusters that support automatic boot image updates. + // For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + // a skew enforcement mode has been specified. + // When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + // acceptable for the current release payload. + // +openshift:enable:FeatureGate=BootImageSkewEnforcement + // +optional + BootImageSkewEnforcement BootImageSkewEnforcementConfig `json:"bootImageSkewEnforcement,omitempty,omitzero"` +} + +// BootImageSkewEnforcementConfig is used to configure how boot image version skew is enforced on the cluster. +// +kubebuilder:validation:XValidation:rule="has(self.mode) && (self.mode =='Manual') ? has(self.manual) : !has(self.manual)",message="manual is required when mode is Manual, and forbidden otherwise" +// +union +type BootImageSkewEnforcementConfig struct { + // mode determines the underlying behavior of skew enforcement mechanism. + // Valid values are Manual and None. + // Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + // & RHCOS version associated with the last boot image update in the clusterBootImage field. + // In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + // skew limit described by the release image. + // None means that the MCO will no longer monitor the boot image skew. This may affect + // the cluster's ability to scale. + // This field is required. + // +unionDiscriminator + // +required + Mode BootImageSkewEnforcementConfigMode `json:"mode,omitempty"` + + // manual describes the current boot image of the cluster. + // This should be set to the oldest boot image used amongst all machine resources in the cluster. + // This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + // If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + // If only ocpVersion is defined, only that value will be used for checking skew compliance. + // If only rhcosVersion is defined, only that value will be used for checking skew compliance. + // Required when mode is set to "Manual" and forbidden otherwise. + // +optional + Manual *ClusterBootImage `json:"manual,omitempty"` +} + +// BootImageSkewEnforcementStatus is the type for the status object. It represents the cluster defaults when +// the boot image skew enforcement configuration is undefined and reflects the actual configuration when it is defined. +// +kubebuilder:validation:XValidation:rule="has(self.mode) && (self.mode == 'Automatic') ? has(self.automatic) : !has(self.automatic)",message="automatic is required when mode is Automatic, and forbidden otherwise" +// +kubebuilder:validation:XValidation:rule="has(self.mode) && (self.mode == 'Manual') ? has(self.manual) : !has(self.manual)",message="manual is required when mode is Manual, and forbidden otherwise" +// +union +type BootImageSkewEnforcementStatus struct { + // mode determines the underlying behavior of skew enforcement mechanism. + // Valid values are Automatic, Manual and None. + // Automatic means that the MCO will perform boot image updates and store the + // OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + // Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + // & RHCOS version associated with the last boot image update in the clusterBootImage field. + // In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + // skew limit described by the release image. + // None means that the MCO will no longer monitor the boot image skew. This may affect + // the cluster's ability to scale. + // This field is required. + // +unionDiscriminator + // +required + Mode BootImageSkewEnforcementModeStatus `json:"mode,omitempty"` + + // automatic describes the current boot image of the cluster. + // This will be populated by the MCO when performing boot image updates. This value will be compared against + // the cluster's skew limit to determine skew compliance. + // Required when mode is set to "Automatic" and forbidden otherwise. + // +optional + Automatic *ClusterBootImage `json:"automatic,omitempty"` + + // manual describes the current boot image of the cluster. + // This will be populated by the cluster admin when performing boot image updates. This value will be compared against + // the cluster's skew limit to determine skew compliance. + // Required when mode is set to "Manual" and forbidden otherwise. + // +optional + Manual *ClusterBootImage `json:"manual,omitempty"` } +// ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and +// the OCP release version which shipped with that RHCOS boot image. At least one of these values are required. +// If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. +// If only ocpVersion is defined, only that value will be used for checking skew compliance. +// If only rhcosVersion is defined, only that value will be used for checking skew compliance. +// +kubebuilder:validation:XValidation:rule="has(self.ocpVersion) || has(self.rhcosVersion)",message="at least one of ocpVersion or rhcosVersion is required" +// +kubebuilder:validation:MinProperties=1 +type ClusterBootImage struct { + // ocpVersion provides a string which represents the OCP version of the boot image. + // This field must match the OCP semver compatible format of x.y.z. This field must be between + // 5 and 10 characters long. + // +kubebuilder:validation:XValidation:rule="self.matches('^[0-9]+\\\\.[0-9]+\\\\.[0-9]+$')",message="bootImageOCPVersion must match the OCP semver compatible format of x.y.z" + // +kubebuilder:validation:MaxLength:=10 + // +kubebuilder:validation:MinLength:=5 + // +optional + OCPVersion string `json:"ocpVersion,omitempty"` + + // rhcosVersion provides a string which represents the RHCOS version of the boot image + // This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + // format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + // 14 and 21 characters long. + // +kubebuilder:validation:XValidation:rule="self.matches('^[0-9]+\\\\.[0-9]+\\\\.([0-9]{8}|[0-9]{12})-[0-9]+$')",message="rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]" + // +kubebuilder:validation:MaxLength:=21 + // +kubebuilder:validation:MinLength:=14 + // +optional + RHCOSVersion string `json:"rhcosVersion,omitempty"` +} + +// BootImageSkewEnforcementConfigMode is a string enum used to configure the cluster's boot image skew enforcement mode. +// +kubebuilder:validation:Enum:="Manual";"None" +type BootImageSkewEnforcementConfigMode string + +const ( + // Manual represents a configuration mode that allows manual skew enforcement. + BootImageSkewEnforcementModeManual BootImageSkewEnforcementConfigMode = "Manual" + + // None represents a configuration mode that disables boot image skew enforcement. + BootImageSkewEnforcementModeNone BootImageSkewEnforcementConfigMode = "None" +) + +// BootImageSkewEnforcementModeStatus is a string enum used to indicate the cluster's boot image skew enforcement mode. +// +kubebuilder:validation:Enum:="Automatic";"Manual";"None" +type BootImageSkewEnforcementModeStatus string + +const ( + // Automatic represents a configuration mode that allows automatic skew enforcement. + BootImageSkewEnforcementModeStatusAutomatic BootImageSkewEnforcementModeStatus = "Automatic" + + // Manual represents a configuration mode that allows manual skew enforcement. + BootImageSkewEnforcementModeStatusManual BootImageSkewEnforcementModeStatus = "Manual" + + // None represents a configuration mode that disables boot image skew enforcement. + BootImageSkewEnforcementModeStatusNone BootImageSkewEnforcementModeStatus = "None" +) + type MachineConfigurationStatus struct { // observedGeneration is the last generation change you've dealt with // +optional @@ -111,6 +239,12 @@ type MachineConfigurationStatus struct { // +openshift:enable:FeatureGate=ManagedBootImages // +optional ManagedBootImagesStatus ManagedBootImages `json:"managedBootImagesStatus"` + + // bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + // configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + // +openshift:enable:FeatureGate=BootImageSkewEnforcement + // +optional + BootImageSkewEnforcementStatus BootImageSkewEnforcementStatus `json:"bootImageSkewEnforcementStatus,omitempty,omitzero"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml index da62cb7eec1..6b5d1172453 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml @@ -46,6 +46,78 @@ spec: description: spec is the specification of the desired behavior of the Machine Config Operator properties: + bootImageSkewEnforcement: + description: |- + bootImageSkewEnforcement allows an admin to configure how boot image version skew is + enforced on the cluster. + When omitted, this will default to Automatic for clusters that support automatic boot image updates. + For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + a skew enforcement mode has been specified. + When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + acceptable for the current release payload. + properties: + manual: + description: |- + manual describes the current boot image of the cluster. + This should be set to the oldest boot image used amongst all machine resources in the cluster. + This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + If only ocpVersion is defined, only that value will be used for checking skew compliance. + If only rhcosVersion is defined, only that value will be used for checking skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Manual and None. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode ==''Manual'') ? has(self.manual) + : !has(self.manual)' failedRevisionLimit: description: |- failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api @@ -682,6 +754,114 @@ spec: description: status is the most recently observed status of the Machine Config Operator properties: + bootImageSkewEnforcementStatus: + description: |- + bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + properties: + automatic: + description: |- + automatic describes the current boot image of the cluster. + This will be populated by the MCO when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Automatic" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + manual: + description: |- + manual describes the current boot image of the cluster. + This will be populated by the cluster admin when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Automatic, Manual and None. + Automatic means that the MCO will perform boot image updates and store the + OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Automatic + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: automatic is required when mode is Automatic, and forbidden + otherwise + rule: 'has(self.mode) && (self.mode == ''Automatic'') ? has(self.automatic) + : !has(self.automatic)' + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode == ''Manual'') ? has(self.manual) + : !has(self.manual)' conditions: description: conditions is a list of conditions and their status items: diff --git a/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml b/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml index 9062795e78d..ffb06058461 100644 --- a/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml +++ b/operator/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml @@ -46,6 +46,78 @@ spec: description: spec is the specification of the desired behavior of the Machine Config Operator properties: + bootImageSkewEnforcement: + description: |- + bootImageSkewEnforcement allows an admin to configure how boot image version skew is + enforced on the cluster. + When omitted, this will default to Automatic for clusters that support automatic boot image updates. + For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + a skew enforcement mode has been specified. + When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + acceptable for the current release payload. + properties: + manual: + description: |- + manual describes the current boot image of the cluster. + This should be set to the oldest boot image used amongst all machine resources in the cluster. + This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + If only ocpVersion is defined, only that value will be used for checking skew compliance. + If only rhcosVersion is defined, only that value will be used for checking skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Manual and None. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode ==''Manual'') ? has(self.manual) + : !has(self.manual)' failedRevisionLimit: description: |- failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api @@ -682,6 +754,114 @@ spec: description: status is the most recently observed status of the Machine Config Operator properties: + bootImageSkewEnforcementStatus: + description: |- + bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + properties: + automatic: + description: |- + automatic describes the current boot image of the cluster. + This will be populated by the MCO when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Automatic" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + manual: + description: |- + manual describes the current boot image of the cluster. + This will be populated by the cluster admin when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Automatic, Manual and None. + Automatic means that the MCO will perform boot image updates and store the + OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Automatic + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: automatic is required when mode is Automatic, and forbidden + otherwise + rule: 'has(self.mode) && (self.mode == ''Automatic'') ? has(self.automatic) + : !has(self.automatic)' + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode == ''Manual'') ? has(self.manual) + : !has(self.manual)' conditions: description: conditions is a list of conditions and their status items: diff --git a/operator/v1/zz_generated.deepcopy.go b/operator/v1/zz_generated.deepcopy.go index d2e74e68387..b25565ed7ed 100644 --- a/operator/v1/zz_generated.deepcopy.go +++ b/operator/v1/zz_generated.deepcopy.go @@ -390,6 +390,53 @@ func (in *AzureDiskEncryptionSet) DeepCopy() *AzureDiskEncryptionSet { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BootImageSkewEnforcementConfig) DeepCopyInto(out *BootImageSkewEnforcementConfig) { + *out = *in + if in.Manual != nil { + in, out := &in.Manual, &out.Manual + *out = new(ClusterBootImage) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootImageSkewEnforcementConfig. +func (in *BootImageSkewEnforcementConfig) DeepCopy() *BootImageSkewEnforcementConfig { + if in == nil { + return nil + } + out := new(BootImageSkewEnforcementConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BootImageSkewEnforcementStatus) DeepCopyInto(out *BootImageSkewEnforcementStatus) { + *out = *in + if in.Automatic != nil { + in, out := &in.Automatic, &out.Automatic + *out = new(ClusterBootImage) + **out = **in + } + if in.Manual != nil { + in, out := &in.Manual, &out.Manual + *out = new(ClusterBootImage) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootImageSkewEnforcementStatus. +func (in *BootImageSkewEnforcementStatus) DeepCopy() *BootImageSkewEnforcementStatus { + if in == nil { + return nil + } + out := new(BootImageSkewEnforcementStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CSIDriverConfigSpec) DeepCopyInto(out *CSIDriverConfigSpec) { *out = *in @@ -676,6 +723,22 @@ func (in *CloudCredentialStatus) DeepCopy() *CloudCredentialStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBootImage) DeepCopyInto(out *ClusterBootImage) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBootImage. +func (in *ClusterBootImage) DeepCopy() *ClusterBootImage { + if in == nil { + return nil + } + out := new(ClusterBootImage) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterCSIDriver) DeepCopyInto(out *ClusterCSIDriver) { *out = *in @@ -3243,6 +3306,7 @@ func (in *MachineConfigurationSpec) DeepCopyInto(out *MachineConfigurationSpec) in.ManagedBootImages.DeepCopyInto(&out.ManagedBootImages) in.NodeDisruptionPolicy.DeepCopyInto(&out.NodeDisruptionPolicy) in.IrreconcilableValidationOverrides.DeepCopyInto(&out.IrreconcilableValidationOverrides) + in.BootImageSkewEnforcement.DeepCopyInto(&out.BootImageSkewEnforcement) return } @@ -3268,6 +3332,7 @@ func (in *MachineConfigurationStatus) DeepCopyInto(out *MachineConfigurationStat } in.NodeDisruptionPolicyStatus.DeepCopyInto(&out.NodeDisruptionPolicyStatus) in.ManagedBootImagesStatus.DeepCopyInto(&out.ManagedBootImagesStatus) + in.BootImageSkewEnforcementStatus.DeepCopyInto(&out.BootImageSkewEnforcementStatus) return } diff --git a/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/operator/v1/zz_generated.featuregated-crd-manifests.yaml index a893b0e0f37..bfdce9cf5b0 100644 --- a/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -305,6 +305,7 @@ machineconfigurations.operator.openshift.io: Capability: "" Category: "" FeatureGates: + - BootImageSkewEnforcement - IrreconcilableMachineConfig - ManagedBootImages FilenameOperatorName: machine-config diff --git a/operator/v1/zz_generated.featuregated-crd-manifests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml b/operator/v1/zz_generated.featuregated-crd-manifests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml new file mode 100644 index 00000000000..2fb52a32e7d --- /dev/null +++ b/operator/v1/zz_generated.featuregated-crd-manifests/machineconfigurations.operator.openshift.io/BootImageSkewEnforcement.yaml @@ -0,0 +1,1176 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/1453 + api.openshift.io/filename-cvo-runlevel: "0000_80" + api.openshift.io/filename-operator: machine-config + api.openshift.io/filename-ordering: "01" + feature-gate.release.openshift.io/BootImageSkewEnforcement: "true" + name: machineconfigurations.operator.openshift.io +spec: + group: operator.openshift.io + names: + kind: MachineConfiguration + listKind: MachineConfigurationList + plural: machineconfigurations + singular: machineconfiguration + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfiguration provides information to configure an operator to manage Machine Configuration. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec is the specification of the desired behavior of the + Machine Config Operator + properties: + bootImageSkewEnforcement: + description: |- + bootImageSkewEnforcement allows an admin to configure how boot image version skew is + enforced on the cluster. + When omitted, this will default to Automatic for clusters that support automatic boot image updates. + For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + a skew enforcement mode has been specified. + When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + acceptable for the current release payload. + properties: + manual: + description: |- + manual describes the current boot image of the cluster. + This should be set to the oldest boot image used amongst all machine resources in the cluster. + This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + If only ocpVersion is defined, only that value will be used for checking skew compliance. + If only rhcosVersion is defined, only that value will be used for checking skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Manual and None. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode ==''Manual'') ? has(self.manual) + : !has(self.manual)' + failedRevisionLimit: + description: |- + failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api + -1 = unlimited, 0 or unset = 5 (default) + format: int32 + type: integer + forceRedeploymentReason: + description: |- + forceRedeploymentReason can be used to force the redeployment of the operand by providing a unique string. + This provides a mechanism to kick a previously failed deployment and provide a reason why you think it will work + this time instead of failing again on the same config. + type: string + logLevel: + default: Normal + description: |- + logLevel is an intent based logging for an overall component. It does not give fine grained control, but it is a + simple way to manage coarse grained logging choices that operators have to interpret for their operands. + + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string + managementState: + description: managementState indicates whether and how the operator + should manage the component + pattern: ^(Managed|Unmanaged|Force|Removed)$ + type: string + nodeDisruptionPolicy: + description: |- + nodeDisruptionPolicy allows an admin to set granular node disruption actions for + MachineConfig-based updates, such as drains, service reloads, etc. Specifying this will allow + for less downtime when doing small configuration updates to the cluster. This configuration + has no effect on cluster upgrades which will still incur node disruption where required. + properties: + files: + description: |- + files is a list of MachineConfig file definitions and actions to take to changes on those paths + This list supports a maximum of 50 entries. + items: + description: NodeDisruptionPolicySpecFile is a file entry and + corresponding actions to take and is used in the NodeDisruptionPolicyConfig + object + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to restart, + only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicySpecActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload and None. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Reload'' ? has(self.reload) + : !has(self.reload)' + - message: restart is required when type is Restart, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' ? + has(self.restart) : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) + == 1 : true' + - message: None action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) == + 1 : true' + path: + description: |- + path is the location of a file being managed through a MachineConfig. + The Actions in the policy will apply to changes to the file at this path. + type: string + required: + - actions + - path + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - path + x-kubernetes-list-type: map + sshkey: + description: |- + sshkey maps to the ignition.sshkeys field in the MachineConfig object, definition an action for this + will apply to all sshkey changes in the cluster + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, where + ${SERVICETYPE} must be one of ".service", ".socket", + ".device", ".mount", ".automount", ".swap", + ".target", ".path", ".timer",".snapshot", ".slice" + or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to restart, + only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, where + ${SERVICETYPE} must be one of ".service", ".socket", + ".device", ".mount", ".automount", ".swap", + ".target", ".path", ".timer",".snapshot", ".slice" + or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicySpecActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload and None. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Reload'' ? has(self.reload) + : !has(self.reload)' + - message: restart is required when type is Restart, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' ? has(self.restart) + : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) == + 1 : true' + - message: None action can only be specified standalone, as + it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) == + 1 : true' + required: + - actions + type: object + units: + description: |- + units is a list MachineConfig unit definitions and actions to take on changes to those services + This list supports a maximum of 50 entries. + items: + description: NodeDisruptionPolicySpecUnit is a systemd unit + name and corresponding actions to take and is used in the + NodeDisruptionPolicyConfig object + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to restart, + only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} + must be atleast 1 character long and can only + consist of alphabets, digits, ":", "-", "_", + ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicySpecActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload and None. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Reload'' ? has(self.reload) + : !has(self.reload)' + - message: restart is required when type is Restart, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' ? + has(self.restart) : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) + == 1 : true' + - message: None action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) == + 1 : true' + name: + description: |- + name represents the service name of a systemd service managed through a MachineConfig + Actions specified will be applied for changes to the named service. + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. Expected + format is ${NAME}${SERVICETYPE}, where ${SERVICETYPE} + must be one of ".service", ".socket", ".device", ".mount", + ".automount", ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected format + is ${NAME}${SERVICETYPE}, where {NAME} must be atleast + 1 character long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - actions + - name + type: object + maxItems: 50 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + observedConfig: + description: |- + observedConfig holds a sparse config that controller has observed from the cluster state. It exists in spec because + it is an input to the level for the operator + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + operatorLogLevel: + default: Normal + description: |- + operatorLogLevel is an intent based logging for the operator itself. It does not give fine grained control, but it is a + simple way to manage coarse grained logging choices that operators have to interpret for themselves. + + Valid values are: "Normal", "Debug", "Trace", "TraceAll". + Defaults to "Normal". + enum: + - "" + - Normal + - Debug + - Trace + - TraceAll + type: string + succeededRevisionLimit: + description: |- + succeededRevisionLimit is the number of successful static pod installer revisions to keep on disk and in the api + -1 = unlimited, 0 or unset = 5 (default) + format: int32 + type: integer + unsupportedConfigOverrides: + description: |- + unsupportedConfigOverrides overrides the final configuration that was computed by the operator. + Red Hat does not support the use of this field. + Misuse of this field could lead to unexpected behavior or conflict with other configuration options. + Seek guidance from the Red Hat support before using this field. + Use of this property blocks cluster upgrades, it must be removed before upgrading your cluster. + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + status: + description: status is the most recently observed status of the Machine + Config Operator + properties: + bootImageSkewEnforcementStatus: + description: |- + bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + properties: + automatic: + description: |- + automatic describes the current boot image of the cluster. + This will be populated by the MCO when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Automatic" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + manual: + description: |- + manual describes the current boot image of the cluster. + This will be populated by the cluster admin when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Automatic, Manual and None. + Automatic means that the MCO will perform boot image updates and store the + OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Automatic + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: automatic is required when mode is Automatic, and forbidden + otherwise + rule: 'has(self.mode) && (self.mode == ''Automatic'') ? has(self.automatic) + : !has(self.automatic)' + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode == ''Manual'') ? has(self.manual) + : !has(self.manual)' + conditions: + description: conditions is a list of conditions and their status + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + nodeDisruptionPolicyStatus: + description: |- + nodeDisruptionPolicyStatus status reflects what the latest cluster-validated policies are, + and will be used by the Machine Config Daemon during future node updates. + properties: + clusterPolicies: + description: clusterPolicies is a merge of cluster default and + user provided node disruption policies. + properties: + files: + description: files is a list of MachineConfig file definitions + and actions to take to changes on those paths + items: + description: NodeDisruptionPolicyStatusFile is a file entry + and corresponding actions to take and is used in the NodeDisruptionPolicyClusterStatus + object + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to + restart, only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicyStatusActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload, None and Special. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + - Special + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, + and forbidden otherwise + rule: 'has(self.type) && self.type == ''Reload'' + ? has(self.reload) : !has(self.reload)' + - message: restart is required when type is Restart, + and forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' + ? has(self.restart) : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) + == 1 : true' + - message: None action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) + == 1 : true' + path: + description: |- + path is the location of a file being managed through a MachineConfig. + The Actions in the policy will apply to changes to the file at this path. + type: string + required: + - actions + - path + type: object + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - path + x-kubernetes-list-type: map + sshkey: + description: sshkey is the overall sshkey MachineConfig definition + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to restart, + only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicyStatusActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload, None and Special. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + - Special + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''Reload'' ? + has(self.reload) : !has(self.reload)' + - message: restart is required when type is Restart, + and forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' + ? has(self.restart) : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) + == 1 : true' + - message: None action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) + == 1 : true' + required: + - actions + type: object + units: + description: units is a list MachineConfig unit definitions + and actions to take on changes to those services + items: + description: NodeDisruptionPolicyStatusUnit is a systemd + unit name and corresponding actions to take and is used + in the NodeDisruptionPolicyClusterStatus object + properties: + actions: + description: |- + actions represents the series of commands to be executed on changes to the file at + the corresponding file path. Actions will be applied in the order that + they are set in this list. If there are other incoming changes to other MachineConfig + entries in the same update that require a reboot, the reboot will supercede these actions. + Valid actions are Reboot, Drain, Reload, DaemonReload and None. + The Reboot action and the None action cannot be used in conjunction with any of the other actions. + This list supports a maximum of 10 entries. + items: + properties: + reload: + description: reload specifies the service to reload, + only valid if type is reload + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be reloaded + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + restart: + description: restart specifies the service to + restart, only valid if type is restart + properties: + serviceName: + description: |- + serviceName is the full name (e.g. crio.service) of the service to be restarted + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service + name. Expected format is ${NAME}${SERVICETYPE}, + where ${SERVICETYPE} must be one of ".service", + ".socket", ".device", ".mount", ".automount", + ".swap", ".target", ".path", ".timer",".snapshot", + ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. + Expected format is ${NAME}${SERVICETYPE}, + where {NAME} must be atleast 1 character + long and can only consist of alphabets, + digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - serviceName + type: object + type: + description: |- + type represents the commands that will be carried out if this NodeDisruptionPolicyStatusActionType is executed + Valid values are Reboot, Drain, Reload, Restart, DaemonReload, None and Special. + reload/restart requires a corresponding service target specified in the reload/restart field. + Other values require no further configuration + enum: + - Reboot + - Drain + - Reload + - Restart + - DaemonReload + - None + - Special + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: reload is required when type is Reload, + and forbidden otherwise + rule: 'has(self.type) && self.type == ''Reload'' + ? has(self.reload) : !has(self.reload)' + - message: restart is required when type is Restart, + and forbidden otherwise + rule: 'has(self.type) && self.type == ''Restart'' + ? has(self.restart) : !has(self.restart)' + maxItems: 10 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: Reboot action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''Reboot'') ? size(self) + == 1 : true' + - message: None action can only be specified standalone, + as it will override any other actions + rule: 'self.exists(x, x.type==''None'') ? size(self) + == 1 : true' + name: + description: |- + name represents the service name of a systemd service managed through a MachineConfig + Actions specified will be applied for changes to the named service. + Service names should be of the format ${NAME}${SERVICETYPE} and can up to 255 characters long. + ${NAME} must be atleast 1 character long and can only consist of alphabets, digits, ":", "-", "_", ".", and "\". + ${SERVICETYPE} must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice" or ".scope". + maxLength: 255 + type: string + x-kubernetes-validations: + - message: Invalid ${SERVICETYPE} in service name. Expected + format is ${NAME}${SERVICETYPE}, where ${SERVICETYPE} + must be one of ".service", ".socket", ".device", + ".mount", ".automount", ".swap", ".target", ".path", + ".timer",".snapshot", ".slice" or ".scope". + rule: self.matches('\\.(service|socket|device|mount|automount|swap|target|path|timer|snapshot|slice|scope)$') + - message: Invalid ${NAME} in service name. Expected + format is ${NAME}${SERVICETYPE}, where {NAME} must + be atleast 1 character long and can only consist + of alphabets, digits, ":", "-", "_", ".", and "\" + rule: self.matches('^[a-zA-Z0-9:._\\\\-]+\\..') + required: + - actions + - name + type: object + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + observedGeneration: + description: observedGeneration is the last generation change you've + dealt with + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/operator/v1/zz_generated.swagger_doc_generated.go b/operator/v1/zz_generated.swagger_doc_generated.go index 206dd98c43b..7186a139e54 100644 --- a/operator/v1/zz_generated.swagger_doc_generated.go +++ b/operator/v1/zz_generated.swagger_doc_generated.go @@ -1379,6 +1379,37 @@ func (KubeStorageVersionMigratorList) SwaggerDoc() map[string]string { return map_KubeStorageVersionMigratorList } +var map_BootImageSkewEnforcementConfig = map[string]string{ + "": "BootImageSkewEnforcementConfig is used to configure how boot image version skew is enforced on the cluster.", + "mode": "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Manual and None. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + "manual": "manual describes the current boot image of the cluster. This should be set to the oldest boot image used amongst all machine resources in the cluster. This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", +} + +func (BootImageSkewEnforcementConfig) SwaggerDoc() map[string]string { + return map_BootImageSkewEnforcementConfig +} + +var map_BootImageSkewEnforcementStatus = map[string]string{ + "": "BootImageSkewEnforcementStatus is the type for the status object. It represents the cluster defaults when the boot image skew enforcement configuration is undefined and reflects the actual configuration when it is defined.", + "mode": "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Automatic, Manual and None. Automatic means that the MCO will perform boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. None means that the MCO will no longer monitor the boot image skew. This may affect the cluster's ability to scale. This field is required.", + "automatic": "automatic describes the current boot image of the cluster. This will be populated by the MCO when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Automatic\" and forbidden otherwise.", + "manual": "manual describes the current boot image of the cluster. This will be populated by the cluster admin when performing boot image updates. This value will be compared against the cluster's skew limit to determine skew compliance. Required when mode is set to \"Manual\" and forbidden otherwise.", +} + +func (BootImageSkewEnforcementStatus) SwaggerDoc() map[string]string { + return map_BootImageSkewEnforcementStatus +} + +var map_ClusterBootImage = map[string]string{ + "": "ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. At least one of these values are required. If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. If only ocpVersion is defined, only that value will be used for checking skew compliance. If only rhcosVersion is defined, only that value will be used for checking skew compliance.", + "ocpVersion": "ocpVersion provides a string which represents the OCP version of the boot image. This field must match the OCP semver compatible format of x.y.z. This field must be between 5 and 10 characters long.", + "rhcosVersion": "rhcosVersion provides a string which represents the RHCOS version of the boot image This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between 14 and 21 characters long.", +} + +func (ClusterBootImage) SwaggerDoc() map[string]string { + return map_ClusterBootImage +} + var map_IrreconcilableValidationOverrides = map[string]string{ "": "IrreconcilableValidationOverrides holds the irreconcilable validations overrides to be applied on each rendered MachineConfig generation.", "storage": "storage can be used to allow making irreconcilable changes to the selected sections under the `spec.config.storage` field of MachineConfig CRs It must have at least one item, may not exceed 3 items and must not contain duplicates. Allowed element values are \"Disks\", \"FileSystems\", \"Raid\" and omitted. When contains \"Disks\" changes to the `spec.config.storage.disks` section of MachineConfig CRs are allowed. When contains \"FileSystems\" changes to the `spec.config.storage.filesystems` section of MachineConfig CRs are allowed. When contains \"Raid\" changes to the `spec.config.storage.raid` section of MachineConfig CRs are allowed. When omitted changes to the `spec.config.storage` section are forbidden.", @@ -1413,6 +1444,7 @@ var map_MachineConfigurationSpec = map[string]string{ "managedBootImages": "managedBootImages allows configuration for the management of boot images for machine resources within the cluster. This configuration allows users to select resources that should be updated to the latest boot images during cluster upgrades, ensuring that new machines always boot with the current cluster version's boot image. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The default for each machine manager mode is All for GCP and AWS platforms, and None for all other platforms.", "nodeDisruptionPolicy": "nodeDisruptionPolicy allows an admin to set granular node disruption actions for MachineConfig-based updates, such as drains, service reloads, etc. Specifying this will allow for less downtime when doing small configuration updates to the cluster. This configuration has no effect on cluster upgrades which will still incur node disruption where required.", "irreconcilableValidationOverrides": "irreconcilableValidationOverrides is an optional field that can used to make changes to a MachineConfig that cannot be applied to existing nodes. When specified, the fields configured with validation overrides will no longer reject changes to those respective fields due to them not being able to be applied to existing nodes. Only newly provisioned nodes will have these configurations applied. Existing nodes will report observed configuration differences in their MachineConfigNode status.", + "bootImageSkewEnforcement": "bootImageSkewEnforcement allows an admin to configure how boot image version skew is enforced on the cluster. When omitted, this will default to Automatic for clusters that support automatic boot image updates. For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until a skew enforcement mode has been specified. When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed acceptable for the current release payload.", } func (MachineConfigurationSpec) SwaggerDoc() map[string]string { @@ -1420,10 +1452,11 @@ func (MachineConfigurationSpec) SwaggerDoc() map[string]string { } var map_MachineConfigurationStatus = map[string]string{ - "observedGeneration": "observedGeneration is the last generation change you've dealt with", - "conditions": "conditions is a list of conditions and their status", - "nodeDisruptionPolicyStatus": "nodeDisruptionPolicyStatus status reflects what the latest cluster-validated policies are, and will be used by the Machine Config Daemon during future node updates.", - "managedBootImagesStatus": "managedBootImagesStatus reflects what the latest cluster-validated boot image configuration is and will be used by Machine Config Controller while performing boot image updates.", + "observedGeneration": "observedGeneration is the last generation change you've dealt with", + "conditions": "conditions is a list of conditions and their status", + "nodeDisruptionPolicyStatus": "nodeDisruptionPolicyStatus status reflects what the latest cluster-validated policies are, and will be used by the Machine Config Daemon during future node updates.", + "managedBootImagesStatus": "managedBootImagesStatus reflects what the latest cluster-validated boot image configuration is and will be used by Machine Config Controller while performing boot image updates.", + "bootImageSkewEnforcementStatus": "bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement configuration is and will be used by Machine Config Controller while performing boot image skew enforcement.", } func (MachineConfigurationStatus) SwaggerDoc() map[string]string { diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml index da62cb7eec1..6b5d1172453 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-CustomNoUpgrade.crd.yaml @@ -46,6 +46,78 @@ spec: description: spec is the specification of the desired behavior of the Machine Config Operator properties: + bootImageSkewEnforcement: + description: |- + bootImageSkewEnforcement allows an admin to configure how boot image version skew is + enforced on the cluster. + When omitted, this will default to Automatic for clusters that support automatic boot image updates. + For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + a skew enforcement mode has been specified. + When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + acceptable for the current release payload. + properties: + manual: + description: |- + manual describes the current boot image of the cluster. + This should be set to the oldest boot image used amongst all machine resources in the cluster. + This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + If only ocpVersion is defined, only that value will be used for checking skew compliance. + If only rhcosVersion is defined, only that value will be used for checking skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Manual and None. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode ==''Manual'') ? has(self.manual) + : !has(self.manual)' failedRevisionLimit: description: |- failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api @@ -682,6 +754,114 @@ spec: description: status is the most recently observed status of the Machine Config Operator properties: + bootImageSkewEnforcementStatus: + description: |- + bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + properties: + automatic: + description: |- + automatic describes the current boot image of the cluster. + This will be populated by the MCO when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Automatic" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + manual: + description: |- + manual describes the current boot image of the cluster. + This will be populated by the cluster admin when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Automatic, Manual and None. + Automatic means that the MCO will perform boot image updates and store the + OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Automatic + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: automatic is required when mode is Automatic, and forbidden + otherwise + rule: 'has(self.mode) && (self.mode == ''Automatic'') ? has(self.automatic) + : !has(self.automatic)' + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode == ''Manual'') ? has(self.manual) + : !has(self.manual)' conditions: description: conditions is a list of conditions and their status items: diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml index 9062795e78d..ffb06058461 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfigurations-DevPreviewNoUpgrade.crd.yaml @@ -46,6 +46,78 @@ spec: description: spec is the specification of the desired behavior of the Machine Config Operator properties: + bootImageSkewEnforcement: + description: |- + bootImageSkewEnforcement allows an admin to configure how boot image version skew is + enforced on the cluster. + When omitted, this will default to Automatic for clusters that support automatic boot image updates. + For clusters that do not support automatic boot image updates, cluster upgrades will be disabled until + a skew enforcement mode has been specified. + When version skew is being enforced, cluster upgrades will be disabled until the version skew is deemed + acceptable for the current release payload. + properties: + manual: + description: |- + manual describes the current boot image of the cluster. + This should be set to the oldest boot image used amongst all machine resources in the cluster. + This includes the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image. + If ocpVersion and rhcosVersion are defined, both values will be used for checking skew compliance. + If only ocpVersion is defined, only that value will be used for checking skew compliance. + If only rhcosVersion is defined, only that value will be used for checking skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Manual and None. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode ==''Manual'') ? has(self.manual) + : !has(self.manual)' failedRevisionLimit: description: |- failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api @@ -682,6 +754,114 @@ spec: description: status is the most recently observed status of the Machine Config Operator properties: + bootImageSkewEnforcementStatus: + description: |- + bootImageSkewEnforcementStatus reflects what the latest cluster-validated boot image skew enforcement + configuration is and will be used by Machine Config Controller while performing boot image skew enforcement. + properties: + automatic: + description: |- + automatic describes the current boot image of the cluster. + This will be populated by the MCO when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Automatic" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + manual: + description: |- + manual describes the current boot image of the cluster. + This will be populated by the cluster admin when performing boot image updates. This value will be compared against + the cluster's skew limit to determine skew compliance. + Required when mode is set to "Manual" and forbidden otherwise. + minProperties: 1 + properties: + ocpVersion: + description: |- + ocpVersion provides a string which represents the OCP version of the boot image. + This field must match the OCP semver compatible format of x.y.z. This field must be between + 5 and 10 characters long. + maxLength: 10 + minLength: 5 + type: string + x-kubernetes-validations: + - message: bootImageOCPVersion must match the OCP semver compatible + format of x.y.z + rule: self.matches('^[0-9]+\\.[0-9]+\\.[0-9]+$') + rhcosVersion: + description: |- + rhcosVersion provides a string which represents the RHCOS version of the boot image + This field must match rhcosVersion formatting of [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] or the legacy + format of [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber]. This field must be between + 14 and 21 characters long. + maxLength: 21 + minLength: 14 + type: string + x-kubernetes-validations: + - message: rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber] + or must match legacy format [major].[minor].[timestamp(YYYYMMDDHHmm)]-[buildnumber] + rule: self.matches('^[0-9]+\\.[0-9]+\\.([0-9]{8}|[0-9]{12})-[0-9]+$') + type: object + x-kubernetes-validations: + - message: at least one of ocpVersion or rhcosVersion is required + rule: has(self.ocpVersion) || has(self.rhcosVersion) + mode: + description: |- + mode determines the underlying behavior of skew enforcement mechanism. + Valid values are Automatic, Manual and None. + Automatic means that the MCO will perform boot image updates and store the + OCP & RHCOS version associated with the last boot image update in the clusterBootImage field. + Manual means that the cluster admin is expected to perform manual boot image updates and store the OCP + & RHCOS version associated with the last boot image update in the clusterBootImage field. + In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the + skew limit described by the release image. + None means that the MCO will no longer monitor the boot image skew. This may affect + the cluster's ability to scale. + This field is required. + enum: + - Automatic + - Manual + - None + type: string + required: + - mode + type: object + x-kubernetes-validations: + - message: automatic is required when mode is Automatic, and forbidden + otherwise + rule: 'has(self.mode) && (self.mode == ''Automatic'') ? has(self.automatic) + : !has(self.automatic)' + - message: manual is required when mode is Manual, and forbidden otherwise + rule: 'has(self.mode) && (self.mode == ''Manual'') ? has(self.manual) + : !has(self.manual)' conditions: description: conditions is a list of conditions and their status items: