From 9d5be0cb043841b68f1ab61d5f9a40a895d0c0e3 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Thu, 12 Sep 2024 04:28:03 -0400 Subject: [PATCH] Back port SDN live migration feature to 4.14 Signed-off-by: Peng Liu --- ...000_10_config-operator_01_network.crd.yaml | 47 +++++++++++++++++++ config/v1/feature_gates.go | 10 ++++ config/v1/stable.network.testsuite.yaml | 23 +++++++++ config/v1/types_feature.go | 1 + config/v1/types_network.go | 11 +++++ config/v1/zz_generated.deepcopy.go | 7 +++ .../v1/zz_generated.swagger_doc_generated.go | 1 + .../generated_openapi/zz_generated.openapi.go | 34 +++++++++++++- openapi/openapi.json | 19 ++++++++ ...00_70_cluster-network-operator_01.crd.yaml | 7 +++ operator/v1/types_network.go | 22 +++++++++ .../v1/zz_generated.swagger_doc_generated.go | 1 + 12 files changed, 182 insertions(+), 1 deletion(-) diff --git a/config/v1/0000_10_config-operator_01_network.crd.yaml b/config/v1/0000_10_config-operator_01_network.crd.yaml index c0117850619..13f67808cb6 100644 --- a/config/v1/0000_10_config-operator_01_network.crd.yaml +++ b/config/v1/0000_10_config-operator_01_network.crd.yaml @@ -109,6 +109,53 @@ spec: clusterNetworkMTU: description: ClusterNetworkMTU is the MTU for inter-pod networking. type: integer + conditions: + description: 'conditions represents the observations of a network.config current state. Known .status.conditions.type are: "NetworkTypeMigrationInProgress", "NetworkTypeMigrationMTUReady", "NetworkTypeMigrationTargetCNIAvailable", "NetworkTypeMigrationTargetCNIInUse" and "NetworkTypeMigrationOriginalCNIPurged"' + type: array + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + type: object + required: + - lastTransitionTime + - message + - reason + - status + - type + 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. + type: string + format: date-time + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + type: string + maxLength: 32768 + 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. + type: integer + format: int64 + minimum: 0 + 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. + type: string + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + status: + description: status of the condition, one of True, False, Unknown. + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + 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])$ + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map migration: description: Migration contains the cluster network migration configuration. type: object diff --git a/config/v1/feature_gates.go b/config/v1/feature_gates.go index 1aa6b41ce1f..33c550ada2d 100644 --- a/config/v1/feature_gates.go +++ b/config/v1/feature_gates.go @@ -282,6 +282,16 @@ var ( OwningProduct: ocpSpecific, } + FeatureGateNetworkLiveMigration = FeatureGateName("NetworkLiveMigration") + sdnLiveMigration = FeatureGateDescription{ + FeatureGateAttributes: FeatureGateAttributes{ + Name: FeatureGateNetworkLiveMigration, + }, + OwningJiraComponent: "Networking/ovn-kubernetes", + ResponsiblePerson: "pliu", + OwningProduct: ocpSpecific, + } + FeatureGateAutomatedEtcdBackup = FeatureGateName("AutomatedEtcdBackup") automatedEtcdBackup = FeatureGateDescription{ FeatureGateAttributes: FeatureGateAttributes{ diff --git a/config/v1/stable.network.testsuite.yaml b/config/v1/stable.network.testsuite.yaml index e8a8bcfaf2f..fcfe4b839f7 100644 --- a/config/v1/stable.network.testsuite.yaml +++ b/config/v1/stable.network.testsuite.yaml @@ -12,3 +12,26 @@ tests: apiVersion: config.openshift.io/v1 kind: Network spec: {} + - name: Should be able to set status conditions + initial: | + apiVersion: config.openshift.io/v1 + kind: Network + spec: {} # No spec is required for a Network + status: + conditions: + - type: NetworkTypeMigrationInProgress + status: "False" + reason: "Reason" + message: "Message" + lastTransitionTime: "2023-10-25T12:00:00Z" + expected: | + apiVersion: config.openshift.io/v1 + kind: Network + spec: {} + status: + conditions: + - type: NetworkTypeMigrationInProgress + status: "False" + reason: "Reason" + message: "Message" + lastTransitionTime: "2023-10-25T12:00:00Z" diff --git a/config/v1/types_feature.go b/config/v1/types_feature.go index b5e18f2ee39..f6fd4480ed3 100644 --- a/config/v1/types_feature.go +++ b/config/v1/types_feature.go @@ -198,6 +198,7 @@ var defaultFeatures = &FeatureGateEnabledDisabled{ externalCloudProviderExternal, privateHostedZoneAWS, buildCSIVolumes, + sdnLiveMigration, }, Disabled: []FeatureGateDescription{ retroactiveDefaultStorageClass, diff --git a/config/v1/types_network.go b/config/v1/types_network.go index c79bc8cf02b..794f3db7b71 100644 --- a/config/v1/types_network.go +++ b/config/v1/types_network.go @@ -85,6 +85,17 @@ type NetworkStatus struct { // Migration contains the cluster network migration configuration. Migration *NetworkMigration `json:"migration,omitempty"` + + // conditions represents the observations of a network.config current state. + // Known .status.conditions.type are: "NetworkTypeMigrationInProgress", "NetworkTypeMigrationMTUReady", + // "NetworkTypeMigrationTargetCNIAvailable", "NetworkTypeMigrationTargetCNIInUse" + // and "NetworkTypeMigrationOriginalCNIPurged" + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` } // ClusterNetworkEntry is a contiguous block of IP addresses from which pod IPs diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 44d7428e6c7..6679c68052c 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -3583,6 +3583,13 @@ func (in *NetworkStatus) DeepCopyInto(out *NetworkStatus) { *out = new(NetworkMigration) (*in).DeepCopyInto(*out) } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 33ec9223755..604c4e7b114 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1837,6 +1837,7 @@ var map_NetworkStatus = map[string]string{ "networkType": "NetworkType is the plugin that is deployed (e.g. OpenShiftSDN).", "clusterNetworkMTU": "ClusterNetworkMTU is the MTU for inter-pod networking.", "migration": "Migration contains the cluster network migration configuration.", + "conditions": "conditions represents the observations of a network.config current state. Known .status.conditions.type are: \"NetworkTypeMigrationInProgress\", \"NetworkTypeMigrationMTUReady\", \"NetworkTypeMigrationTargetCNIAvailable\", \"NetworkTypeMigrationTargetCNIInUse\" and \"NetworkTypeMigrationOriginalCNIPurged\"", } func (NetworkStatus) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index e3b09fae8e9..365916caa20 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -14700,11 +14700,35 @@ func schema_openshift_api_config_v1_NetworkStatus(ref common.ReferenceCallback) Ref: ref("github.com/openshift/api/config/v1.NetworkMigration"), }, }, + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "conditions represents the observations of a network.config current state. Known .status.conditions.type are: \"NetworkTypeMigrationInProgress\", \"NetworkTypeMigrationMTUReady\", \"NetworkTypeMigrationTargetCNIAvailable\", \"NetworkTypeMigrationTargetCNIInUse\" and \"NetworkTypeMigrationOriginalCNIPurged\"", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "github.com/openshift/api/config/v1.ClusterNetworkEntry", "github.com/openshift/api/config/v1.NetworkMigration"}, + "github.com/openshift/api/config/v1.ClusterNetworkEntry", "github.com/openshift/api/config/v1.NetworkMigration", "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, } } @@ -46336,6 +46360,14 @@ func schema_openshift_api_operator_v1_NetworkMigration(ref common.ReferenceCallb Ref: ref("github.com/openshift/api/operator/v1.FeaturesMigration"), }, }, + "mode": { + SchemaProps: spec.SchemaProps{ + Description: "mode indicates the mode of network migration. The supported values are \"Live\", \"Offline\" and omitted. A \"Live\" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. An \"Offline\" migration operation will cause service interruption. During an \"Offline\" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default value is \"Offline\".", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/openapi/openapi.json b/openapi/openapi.json index f6a93a44f63..0a0f7f7691b 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -7892,6 +7892,20 @@ "type": "integer", "format": "int32" }, + "conditions": { + "description": "conditions represents the observations of a network.config current state. Known .status.conditions.type are: \"NetworkTypeMigrationInProgress\", \"NetworkTypeMigrationMTUReady\", \"NetworkTypeMigrationTargetCNIAvailable\", \"NetworkTypeMigrationTargetCNIInUse\" and \"NetworkTypeMigrationOriginalCNIPurged\"", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Condition" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge" + }, "migration": { "description": "Migration contains the cluster network migration configuration.", "$ref": "#/definitions/com.github.openshift.api.config.v1.NetworkMigration" @@ -27155,6 +27169,11 @@ "description": "features contains the features migration configuration. Set this to migrate feature configuration when changing the cluster default network provider. if unset, the default operation is to migrate all the configuration of supported features.", "$ref": "#/definitions/com.github.openshift.api.operator.v1.FeaturesMigration" }, + "mode": { + "description": "mode indicates the mode of network migration. The supported values are \"Live\", \"Offline\" and omitted. A \"Live\" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. An \"Offline\" migration operation will cause service interruption. During an \"Offline\" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default value is \"Offline\".", + "type": "string", + "default": "" + }, "mtu": { "description": "mtu contains the MTU migration configuration. Set this to allow changing the MTU values for the default network. If unset, the operation of changing the MTU for the default network will be rejected.", "$ref": "#/definitions/com.github.openshift.api.operator.v1.MTUMigration" diff --git a/operator/v1/0000_70_cluster-network-operator_01.crd.yaml b/operator/v1/0000_70_cluster-network-operator_01.crd.yaml index 73804bfefb9..3afb76dcc03 100644 --- a/operator/v1/0000_70_cluster-network-operator_01.crd.yaml +++ b/operator/v1/0000_70_cluster-network-operator_01.crd.yaml @@ -551,6 +551,13 @@ spec: description: multicast specifies whether or not the multicast configuration is migrated automatically when changing the cluster default network provider. If unset, this property defaults to 'true' and multicast configure is migrated. type: boolean default: true + mode: + description: mode indicates the mode of network migration. The supported values are "Live", "Offline" and omitted. A "Live" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. An "Offline" migration operation will cause service interruption. During an "Offline" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default value is "Offline". + type: string + enum: + - Live + - Offline + - "" mtu: description: mtu contains the MTU migration configuration. Set this to allow changing the MTU values for the default network. If unset, the operation of changing the MTU for the default network will be rejected. type: object diff --git a/operator/v1/types_network.go b/operator/v1/types_network.go index 339323afc3f..d8609539d04 100644 --- a/operator/v1/types_network.go +++ b/operator/v1/types_network.go @@ -116,7 +116,20 @@ type NetworkSpec struct { Migration *NetworkMigration `json:"migration,omitempty"` } +// NetworkMigrationMode is an enumeration of the possible mode of the network migration +// Valid values are "Live", "Offline" and omitted. +// +kubebuilder:validation:Enum:=Live;Offline;"" +type NetworkMigrationMode string + +const ( + // A "Live" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. + LiveNetworkMigrationMode NetworkMigrationMode = "Live" + // An "Offline" migration operation will cause service interruption. During an "Offline" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. + OfflineNetworkMigrationMode NetworkMigrationMode = "Offline" +) + // NetworkMigration represents the cluster network configuration. +// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(self.mtu) || !has(self.networkType) || self.networkType == '' || has(self.mode) && self.mode == 'Live'",message="networkType migration in mode other than 'Live' may not be configured at the same time as mtu migration" type NetworkMigration struct { // networkType is the target type of network migration. Set this to the // target network type to allow changing the default network. If unset, the @@ -137,6 +150,15 @@ type NetworkMigration struct { // supported features. // +optional Features *FeaturesMigration `json:"features,omitempty"` + + // mode indicates the mode of network migration. + // The supported values are "Live", "Offline" and omitted. + // A "Live" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. + // An "Offline" migration operation will cause service interruption. During an "Offline" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. + // When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. + // The current default value is "Offline". + // +optional + Mode NetworkMigrationMode `json:"mode"` } type FeaturesMigration struct { diff --git a/operator/v1/zz_generated.swagger_doc_generated.go b/operator/v1/zz_generated.swagger_doc_generated.go index 2713135f096..a58efcfa6e7 100644 --- a/operator/v1/zz_generated.swagger_doc_generated.go +++ b/operator/v1/zz_generated.swagger_doc_generated.go @@ -1448,6 +1448,7 @@ var map_NetworkMigration = map[string]string{ "networkType": "networkType is the target type of network migration. Set this to the target network type to allow changing the default network. If unset, the operation of changing cluster default network plugin will be rejected. The supported values are OpenShiftSDN, OVNKubernetes", "mtu": "mtu contains the MTU migration configuration. Set this to allow changing the MTU values for the default network. If unset, the operation of changing the MTU for the default network will be rejected.", "features": "features contains the features migration configuration. Set this to migrate feature configuration when changing the cluster default network provider. if unset, the default operation is to migrate all the configuration of supported features.", + "mode": "mode indicates the mode of network migration. The supported values are \"Live\", \"Offline\" and omitted. A \"Live\" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. An \"Offline\" migration operation will cause service interruption. During an \"Offline\" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default value is \"Offline\".", } func (NetworkMigration) SwaggerDoc() map[string]string {