Repository: Azure/ARO-RP
Pull request #1571 (2021-07-01 14:46:45)

Default to OVNKubernetes NetworkType for E2E, enable API access for production
### Which issue this PR addresses:

ADO [9823641](https://msazure.visualstudio.com/AzureRedHatOpenShift/_workitems/edit/9823641/)

### What this PR does / why we need it:

Adds SDNProvider to the API
Sets OVNKubernetes as the default option for E2E
Maintains OpenShiftSDN as the default option for production

### Test plan for issue:

Unit tests exists for API behavior (`make test-go`) 
E2E tests will transition to OVNKubernetes
 
### Is there any documentation that needs to be updated for this PR?

Auto-generated Swagger API client docs are available in PR. 

drewandersonnz: Looks to be blocked by https://github.com/mjudeikis/installer/pull/2 
drewandersonnz:  > Still needs wiring into Installer and maybe E2E tests 
 
 @mjudeikis what do you mean? 
 
 * installer is already updated, this PR builds clusters with `OVNKubernetes` by default, by passing `OVNKubernetes` as the default parameter to the RP API, and passing that through to installer after validation. 
 
 * E2E tests will build an `OVNKubernetes` cluster by default, are you requesting we double the E2E tests to do one set for `OpenShiftSDN` and another E2E for `OVNKubernetes` ? 
mjudeikis: > installer is already updated, this PR builds clusters with OVNKubernetes by default, by passing OVNKubernetes as the default parameter to the RP API, and passing that through to installer after validation. 
Missed that one. Sorry. 
github-actions[bot]: Please rebase pull request.
github-actions[bot]: Please rebase pull request.
drewandersonnz: Rebased.

Patch:
diff --git a/.sha256sum b/.sha256sum
index ff47d50c6..0258c434f 100644
--- a/.sha256sum
+++ b/.sha256sum
@@ -1,2 +1,2 @@
 d2e11a7924d0cbb70672fb0dd6b1a387ccaec8b97a6968adf5a1516d325374eb  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/stable/2020-04-30/redhatopenshift.json
-bbdf867021e306b60677d1d6840e5059fe92f058f09e861a10e7c000d36868f9  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json
+6c79802ca5f49f0ef49d5d12d0bc424657569dd00428db1af51bd82fcc948f70  swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json
diff --git a/pkg/api/admin/openshiftcluster.go b/pkg/api/admin/openshiftcluster.go
index b72bf14d4..cd7a714b9 100644
--- a/pkg/api/admin/openshiftcluster.go
+++ b/pkg/api/admin/openshiftcluster.go
@@ -82,8 +82,19 @@ type ServicePrincipalProfile struct {
 	SPObjectID string `json:"spObjectId,omitempty"`
 }
 
+// SDNProvider constants.
+type SDNProvider string
+
+const (
+	SDNProviderOVNKubernetes SDNProvider = "OVNKubernetes"
+	SDNProviderOpenShiftSDN  SDNProvider = "OpenShiftSDN"
+)
+
 // NetworkProfile represents a network profile.
 type NetworkProfile struct {
+	// The SDNProvider to use when installing the cluster.
+	SDNProvider SDNProvider `json:"sdnProvider,omitempty"`
+
 	PodCIDR     string `json:"podCidr,omitempty"`
 	ServiceCIDR string `json:"serviceCidr,omitempty"`
 
diff --git a/pkg/api/admin/openshiftcluster_convert.go b/pkg/api/admin/openshiftcluster_convert.go
index 30d109029..9972f9142 100644
--- a/pkg/api/admin/openshiftcluster_convert.go
+++ b/pkg/api/admin/openshiftcluster_convert.go
@@ -41,6 +41,7 @@ func (c *openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfa
 				SPObjectID: oc.Properties.ServicePrincipalProfile.SPObjectID,
 			},
 			NetworkProfile: NetworkProfile{
+				SDNProvider:                SDNProvider(oc.Properties.NetworkProfile.SDNProvider),
 				PodCIDR:                    oc.Properties.NetworkProfile.PodCIDR,
 				ServiceCIDR:                oc.Properties.NetworkProfile.ServiceCIDR,
 				APIServerPrivateEndpointIP: oc.Properties.NetworkProfile.APIServerPrivateEndpointIP,
@@ -171,6 +172,7 @@ func (c *openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShi
 	out.Properties.ServicePrincipalProfile.SPObjectID = oc.Properties.ServicePrincipalProfile.SPObjectID
 	out.Properties.NetworkProfile.PodCIDR = oc.Properties.NetworkProfile.PodCIDR
 	out.Properties.NetworkProfile.ServiceCIDR = oc.Properties.NetworkProfile.ServiceCIDR
+	out.Properties.NetworkProfile.SDNProvider = api.SDNProvider(oc.Properties.NetworkProfile.SDNProvider)
 	out.Properties.NetworkProfile.APIServerPrivateEndpointIP = oc.Properties.NetworkProfile.APIServerPrivateEndpointIP
 	out.Properties.MasterProfile.VMSize = api.VMSize(oc.Properties.MasterProfile.VMSize)
 	out.Properties.MasterProfile.SubnetID = oc.Properties.MasterProfile.SubnetID
diff --git a/pkg/api/openshiftcluster.go b/pkg/api/openshiftcluster.go
index bea941228..2df503d31 100644
--- a/pkg/api/openshiftcluster.go
+++ b/pkg/api/openshiftcluster.go
@@ -192,12 +192,21 @@ type ServicePrincipalProfile struct {
 	SPObjectID   string       `json:"spObjectId,omitempty"`
 }
 
+// SDNProvider
+type SDNProvider string
+
+const (
+	SDNProviderOVNKubernetes SDNProvider = "OVNKubernetes"
+	SDNProviderOpenShiftSDN  SDNProvider = "OpenShiftSDN"
+)
+
 // NetworkProfile represents a network profile
 type NetworkProfile struct {
 	MissingFields
 
-	PodCIDR     string `json:"podCidr,omitempty"`
-	ServiceCIDR string `json:"serviceCidr,omitempty"`
+	PodCIDR     string      `json:"podCidr,omitempty"`
+	ServiceCIDR string      `json:"serviceCidr,omitempty"`
+	SDNProvider SDNProvider `json:"sdnProvider,omitempty"`
 
 	APIServerPrivateEndpointIP string `json:"privateEndpointIp,omitempty"`
 }
diff --git a/pkg/api/v20210131preview/openshiftcluster.go b/pkg/api/v20210131preview/openshiftcluster.go
index d471c4550..22e46b0b5 100644
--- a/pkg/api/v20210131preview/openshiftcluster.go
+++ b/pkg/api/v20210131preview/openshiftcluster.go
@@ -114,8 +114,19 @@ type ServicePrincipalProfile struct {
 	ClientSecret string `json:"clientSecret,omitempty" mutable:"true"`
 }
 
+// SDNProvider constants.
+type SDNProvider string
+
+const (
+	SDNProviderOVNKubernetes SDNProvider = "OVNKubernetes"
+	SDNProviderOpenShiftSDN  SDNProvider = "OpenShiftSDN"
+)
+
 // NetworkProfile represents a network profile.
 type NetworkProfile struct {
+	// The SDNProvider to use when installing the cluster.
+	SDNProvider SDNProvider `json:"sdnProvider,omitempty"`
+
 	// The CIDR used for OpenShift/Kubernetes Pods.
 	PodCIDR string `json:"podCidr,omitempty"`
 
diff --git a/pkg/api/v20210131preview/openshiftcluster_convert.go b/pkg/api/v20210131preview/openshiftcluster_convert.go
index c2fdbdc82..bf562c2d0 100644
--- a/pkg/api/v20210131preview/openshiftcluster_convert.go
+++ b/pkg/api/v20210131preview/openshiftcluster_convert.go
@@ -37,6 +37,7 @@ func (c *openShiftClusterConverter) ToExternal(oc *api.OpenShiftCluster) interfa
 			NetworkProfile: NetworkProfile{
 				PodCIDR:     oc.Properties.NetworkProfile.PodCIDR,
 				ServiceCIDR: oc.Properties.NetworkProfile.ServiceCIDR,
+				SDNProvider: SDNProvider(oc.Properties.NetworkProfile.SDNProvider),
 			},
 			MasterProfile: MasterProfile{
 				VMSize:              VMSize(oc.Properties.MasterProfile.VMSize),
@@ -140,6 +141,7 @@ func (c *openShiftClusterConverter) ToInternal(_oc interface{}, out *api.OpenShi
 	out.Properties.ServicePrincipalProfile.ClientSecret = api.SecureString(oc.Properties.ServicePrincipalProfile.ClientSecret)
 	out.Properties.NetworkProfile.PodCIDR = oc.Properties.NetworkProfile.PodCIDR
 	out.Properties.NetworkProfile.ServiceCIDR = oc.Properties.NetworkProfile.ServiceCIDR
+	out.Properties.NetworkProfile.SDNProvider = api.SDNProvider(oc.Properties.NetworkProfile.SDNProvider)
 	out.Properties.MasterProfile.VMSize = api.VMSize(oc.Properties.MasterProfile.VMSize)
 	out.Properties.MasterProfile.SubnetID = oc.Properties.MasterProfile.SubnetID
 	out.Properties.MasterProfile.EncryptionAtHost = oc.Properties.MasterProfile.EncryptionAtHost
diff --git a/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/enums.go b/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/enums.go
index 9b5561027..af701e7ac 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/enums.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/enums.go
@@ -59,6 +59,21 @@ func PossibleProvisioningStateValues() []ProvisioningState {
 	return []ProvisioningState{AdminUpdating, Creating, Deleting, Failed, Succeeded, Updating}
 }
 
+// SDNProvider enumerates the values for sdn provider.
+type SDNProvider string
+
+const (
+	// OpenShiftSDN ...
+	OpenShiftSDN SDNProvider = "OpenShiftSDN"
+	// OVNKubernetes ...
+	OVNKubernetes SDNProvider = "OVNKubernetes"
+)
+
+// PossibleSDNProviderValues returns an array of possible values for the SDNProvider const type.
+func PossibleSDNProviderValues() []SDNProvider {
+	return []SDNProvider{OpenShiftSDN, OVNKubernetes}
+}
+
 // Visibility enumerates the values for visibility.
 type Visibility string
 
diff --git a/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/models.go b/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/models.go
index b1a2b85d9..a8af5879e 100644
--- a/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/models.go
+++ b/pkg/client/services/redhatopenshift/mgmt/2021-01-31-preview/redhatopenshift/models.go
@@ -132,6 +132,8 @@ type MasterProfile struct {
 
 // NetworkProfile networkProfile represents a network profile.
 type NetworkProfile struct {
+	// SdnProvider - The SDNProvider to use when installing the cluster. Possible values include: 'OVNKubernetes', 'OpenShiftSDN'
+	SdnProvider SDNProvider `json:"sdnProvider,omitempty"`
 	// PodCidr - The CIDR used for OpenShift/Kubernetes Pods.
 	PodCidr *string `json:"podCidr,omitempty"`
 	// ServiceCidr - The CIDR used for OpenShift/Kubernetes Services.
diff --git a/pkg/cluster/generateconfig.go b/pkg/cluster/generateconfig.go
index 4ee87714e..bc57d84d5 100644
--- a/pkg/cluster/generateconfig.go
+++ b/pkg/cluster/generateconfig.go
@@ -100,6 +100,11 @@ func (m *manager) generateInstallConfig(ctx context.Context) (*installconfig.Ins
 		workerZones = []string{""}
 	}
 
+	SDNProvider := string(api.SDNProviderOpenShiftSDN)
+	if m.doc.OpenShiftCluster.Properties.NetworkProfile.SDNProvider != "" {
+		SDNProvider = string(m.doc.OpenShiftCluster.Properties.NetworkProfile.SDNProvider)
+	}
+
 	installConfig := &installconfig.InstallConfig{
 		Config: &types.InstallConfig{
 			TypeMeta: metav1.TypeMeta{
@@ -116,7 +121,7 @@ func (m *manager) generateInstallConfig(ctx context.Context) (*installconfig.Ins
 						CIDR: *ipnet.MustParseCIDR("127.0.0.0/8"), // dummy
 					},
 				},
-				NetworkType: "OpenShiftSDN",
+				NetworkType: SDNProvider,
 				ClusterNetwork: []types.ClusterNetworkEntry{
 					{
 						CIDR:       *ipnet.MustParseCIDR(m.doc.OpenShiftCluster.Properties.NetworkProfile.PodCIDR),
diff --git a/pkg/util/cluster/cluster.go b/pkg/util/cluster/cluster.go
index eb0a5b610..4fadfa0a2 100644
--- a/pkg/util/cluster/cluster.go
+++ b/pkg/util/cluster/cluster.go
@@ -353,6 +353,7 @@ func (c *Cluster) createCluster(ctx context.Context, vnetResourceGroup, clusterN
 			NetworkProfile: api.NetworkProfile{
 				PodCIDR:     "10.128.0.0/14",
 				ServiceCIDR: "172.30.0.0/16",
+				SDNProvider: api.SDNProviderOVNKubernetes,
 			},
 			MasterProfile: api.MasterProfile{
 				VMSize:   api.VMSizeStandardD8sV3,
diff --git a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/__init__.py b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/__init__.py
index d9554af81..27c87b161 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/__init__.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/__init__.py
@@ -67,6 +67,7 @@ from ._paged_models import OpenShiftClusterPaged
 from ._paged_models import OperationPaged
 from ._azure_red_hat_open_shift_client_enums import (
     VMSize,
+    SDNProvider,
     CreatedByType,
 )
 
@@ -95,5 +96,6 @@ __all__ = [
     'OperationPaged',
     'OpenShiftClusterPaged',
     'VMSize',
+    'SDNProvider',
     'CreatedByType',
 ]
diff --git a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_azure_red_hat_open_shift_client_enums.py b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_azure_red_hat_open_shift_client_enums.py
index 48d944e03..67ccf382d 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_azure_red_hat_open_shift_client_enums.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_azure_red_hat_open_shift_client_enums.py
@@ -49,6 +49,12 @@ class VMSize(str, Enum):
     standard_m128ms = "Standard_M128ms"
 
 
+class SDNProvider(str, Enum):
+
+    ovn_kubernetes = "OVNKubernetes"
+    open_shift_sdn = "OpenShiftSDN"
+
+
 class CreatedByType(str, Enum):
 
     user = "User"
diff --git a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models.py b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models.py
index d1a9940f6..fa469fd2e 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models.py
@@ -325,6 +325,10 @@ class MasterProfile(Model):
 class NetworkProfile(Model):
     """NetworkProfile represents a network profile.
 
+    :param sdn_provider: The SDNProvider to use when installing the cluster.
+     Possible values include: 'OVNKubernetes', 'OpenShiftSDN'
+    :type sdn_provider: str or
+     ~azure.mgmt.redhatopenshift.v2021_01_31_preview.models.SDNProvider
     :param pod_cidr: The CIDR used for OpenShift/Kubernetes Pods.
     :type pod_cidr: str
     :param service_cidr: The CIDR used for OpenShift/Kubernetes Services.
@@ -332,12 +336,14 @@ class NetworkProfile(Model):
     """
 
     _attribute_map = {
+        'sdn_provider': {'key': 'sdnProvider', 'type': 'str'},
         'pod_cidr': {'key': 'podCidr', 'type': 'str'},
         'service_cidr': {'key': 'serviceCidr', 'type': 'str'},
     }
 
     def __init__(self, **kwargs):
         super(NetworkProfile, self).__init__(**kwargs)
+        self.sdn_provider = kwargs.get('sdn_provider', None)
         self.pod_cidr = kwargs.get('pod_cidr', None)
         self.service_cidr = kwargs.get('service_cidr', None)
 
diff --git a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models_py3.py b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models_py3.py
index 1d68c5993..939c21019 100644
--- a/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models_py3.py
+++ b/python/client/azure/mgmt/redhatopenshift/v2021_01_31_preview/models/_models_py3.py
@@ -325,6 +325,10 @@ class MasterProfile(Model):
 class NetworkProfile(Model):
     """NetworkProfile represents a network profile.
 
+    :param sdn_provider: The SDNProvider to use when installing the cluster.
+     Possible values include: 'OVNKubernetes', 'OpenShiftSDN'
+    :type sdn_provider: str or
+     ~azure.mgmt.redhatopenshift.v2021_01_31_preview.models.SDNProvider
     :param pod_cidr: The CIDR used for OpenShift/Kubernetes Pods.
     :type pod_cidr: str
     :param service_cidr: The CIDR used for OpenShift/Kubernetes Services.
@@ -332,12 +336,14 @@ class NetworkProfile(Model):
     """
 
     _attribute_map = {
+        'sdn_provider': {'key': 'sdnProvider', 'type': 'str'},
         'pod_cidr': {'key': 'podCidr', 'type': 'str'},
         'service_cidr': {'key': 'serviceCidr', 'type': 'str'},
     }
 
-    def __init__(self, *, pod_cidr: str=None, service_cidr: str=None, **kwargs) -> None:
+    def __init__(self, *, sdn_provider=None, pod_cidr: str=None, service_cidr: str=None, **kwargs) -> None:
         super(NetworkProfile, self).__init__(**kwargs)
+        self.sdn_provider = sdn_provider
         self.pod_cidr = pod_cidr
         self.service_cidr = service_cidr
 
diff --git a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json
index 471ef7aed..7e06f028d 100644
--- a/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json
+++ b/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/preview/2021-01-31-preview/redhatopenshift.json
@@ -589,6 +589,10 @@
     "NetworkProfile": {
       "description": "NetworkProfile represents a network profile.",
       "properties": {
+        "sdnProvider": {
+          "$ref": "#/definitions/SDNProvider",
+          "description": "The SDNProvider to use when installing the cluster."
+        },
         "podCidr": {
           "description": "The CIDR used for OpenShift/Kubernetes Pods.",
           "type": "string"
@@ -768,6 +772,18 @@
       ],
       "type": "string"
     },
+    "SDNProvider": {
+      "description": "SDNProvider constants.",
+      "enum": [
+        "OVNKubernetes",
+        "OpenShiftSDN"
+      ],
+      "type": "string",
+      "x-ms-enum": {
+        "name": "SDNProvider",
+        "modelAsString": true
+      }
+    },
     "ServicePrincipalProfile": {
       "description": "ServicePrincipalProfile represents a service principal profile.",
       "properties": {


Test patch:
diff --git a/pkg/api/admin/openshiftcluster_validatestatic_test.go b/pkg/api/admin/openshiftcluster_validatestatic_test.go
index 8f3264c53..479863b04 100644
--- a/pkg/api/admin/openshiftcluster_validatestatic_test.go
+++ b/pkg/api/admin/openshiftcluster_validatestatic_test.go
@@ -312,6 +312,20 @@ func TestOpenShiftClusterStaticValidateDelta(t *testing.T) {
 			},
 			wantErr: "400: PropertyChangeNotAllowed: properties.servicePrincipalProfile.spObjectId: Changing property 'properties.servicePrincipalProfile.spObjectId' is not allowed.",
 		},
+		{
+			name: "sdnProvider change is not allowed",
+			oc: func() *OpenShiftCluster {
+				return &OpenShiftCluster{
+					Properties: OpenShiftClusterProperties{
+						NetworkProfile: NetworkProfile{
+							SDNProvider: SDNProviderOVNKubernetes,
+						},
+					},
+				}
+			},
+			modify:  func(oc *OpenShiftCluster) { oc.Properties.NetworkProfile.SDNProvider = "anything" },
+			wantErr: "400: PropertyChangeNotAllowed: properties.networkProfile.sdnProvider: Changing property 'properties.networkProfile.sdnProvider' is not allowed.",
+		},
 		{
 			name: "podCidr change is not allowed",
 			oc: func() *OpenShiftCluster {
diff --git a/pkg/api/v20210131preview/openshiftcluster_validatestatic.go b/pkg/api/v20210131preview/openshiftcluster_validatestatic.go
index 0506454b5..85e5fd78c 100644
--- a/pkg/api/v20210131preview/openshiftcluster_validatestatic.go
+++ b/pkg/api/v20210131preview/openshiftcluster_validatestatic.go
@@ -210,6 +210,12 @@ func (sv *openShiftClusterStaticValidator) validateNetworkProfile(path string, n
 		}
 	}
 
+	switch np.SDNProvider {
+	case SDNProviderOVNKubernetes, SDNProviderOpenShiftSDN:
+	default:
+		return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidParameter, path+".sdnProvider", "The provided SDNProvider '%s' is invalid.", np.SDNProvider)
+	}
+
 	return nil
 }
 
diff --git a/pkg/api/v20210131preview/openshiftcluster_validatestatic_test.go b/pkg/api/v20210131preview/openshiftcluster_validatestatic_test.go
index d10b8497e..b9a7823fe 100644
--- a/pkg/api/v20210131preview/openshiftcluster_validatestatic_test.go
+++ b/pkg/api/v20210131preview/openshiftcluster_validatestatic_test.go
@@ -78,6 +78,7 @@ func validOpenShiftCluster() *OpenShiftCluster {
 			NetworkProfile: NetworkProfile{
 				PodCIDR:     "10.128.0.0/14",
 				ServiceCIDR: "172.30.0.0/16",
+				SDNProvider: SDNProviderOVNKubernetes,
 			},
 			MasterProfile: MasterProfile{
 				VMSize:   VMSizeStandardD8sV3,
@@ -410,7 +411,16 @@ func TestOpenShiftClusterStaticValidateServicePrincipalProfile(t *testing.T) {
 }
 
 func TestOpenShiftClusterStaticValidateNetworkProfile(t *testing.T) {
-	tests := []*validateTest{
+	createtests := []*validateTest{
+		{
+			name: "sdnProvider create as OpenShiftSDN",
+			modify: func(oc *OpenShiftCluster) {
+				oc.Properties.NetworkProfile.SDNProvider = SDNProviderOpenShiftSDN
+			},
+		},
+	}
+
+	commontests := []*validateTest{
 		{
 			name: "valid",
 		},
@@ -456,10 +466,25 @@ func TestOpenShiftClusterStaticValidateNetworkProfile(t *testing.T) {
 			},
 			wantErr: "400: InvalidParameter: properties.networkProfile.serviceCidr: The provided vnet CIDR '10.0.0.0/23' is invalid: must be /22 or larger.",
 		},
+		{
+			name: "sdnProvider given as empty",
+			modify: func(oc *OpenShiftCluster) {
+				oc.Properties.NetworkProfile.SDNProvider = ""
+			},
+			wantErr: "400: InvalidParameter: properties.networkProfile.sdnProvider: The provided SDNProvider '' is invalid.",
+		},
+		{
+			name: "sdnProvider given InvalidOption",
+			modify: func(oc *OpenShiftCluster) {
+				oc.Properties.NetworkProfile.SDNProvider = "InvalidOption"
+			},
+			wantErr: "400: InvalidParameter: properties.networkProfile.sdnProvider: The provided SDNProvider 'InvalidOption' is invalid.",
+		},
 	}
 
-	runTests(t, testModeCreate, tests)
-	runTests(t, testModeUpdate, tests)
+	runTests(t, testModeCreate, commontests)
+	runTests(t, testModeUpdate, commontests)
+	runTests(t, testModeCreate, createtests)
 }
 
 func TestOpenShiftClusterStaticValidateMasterProfile(t *testing.T) {
@@ -809,6 +834,11 @@ func TestOpenShiftClusterStaticValidateDelta(t *testing.T) {
 			name:   "clientSecret change",
 			modify: func(oc *OpenShiftCluster) { oc.Properties.ServicePrincipalProfile.ClientSecret = "invalid" },
 		},
+		{
+			name:    "sdnProvider should fail to change from OVNKubernetes to OpenShiftSDN",
+			modify:  func(oc *OpenShiftCluster) { oc.Properties.NetworkProfile.SDNProvider = SDNProviderOpenShiftSDN },
+			wantErr: "400: PropertyChangeNotAllowed: properties.networkProfile.sdnProvider: Changing property 'properties.networkProfile.sdnProvider' is not allowed.",
+		},
 		{
 			name:    "podCidr change",
 			modify:  func(oc *OpenShiftCluster) { oc.Properties.NetworkProfile.PodCIDR = "0.0.0.0/0" },