github.com/openshift/installer@v1.4.17/pkg/types/conversion/installconfig_test.go (about)

     1  package conversion
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  	"k8s.io/apimachinery/pkg/util/validation/field"
     9  	utilsslice "k8s.io/utils/strings/slices"
    10  
    11  	"github.com/openshift/installer/pkg/ipnet"
    12  	"github.com/openshift/installer/pkg/types"
    13  	"github.com/openshift/installer/pkg/types/aws"
    14  	"github.com/openshift/installer/pkg/types/baremetal"
    15  	"github.com/openshift/installer/pkg/types/nutanix"
    16  	"github.com/openshift/installer/pkg/types/openstack"
    17  	"github.com/openshift/installer/pkg/types/ovirt"
    18  	"github.com/openshift/installer/pkg/types/vsphere"
    19  )
    20  
    21  func TestConvertInstallConfig(t *testing.T) {
    22  	cases := []struct {
    23  		name          string
    24  		config        *types.InstallConfig
    25  		expected      *types.InstallConfig
    26  		expectedError string
    27  	}{
    28  		{
    29  			name: "empty",
    30  			config: &types.InstallConfig{
    31  				TypeMeta: metav1.TypeMeta{
    32  					APIVersion: types.InstallConfigVersion,
    33  				},
    34  			},
    35  			expected: &types.InstallConfig{
    36  				TypeMeta: metav1.TypeMeta{
    37  					APIVersion: types.InstallConfigVersion,
    38  				},
    39  			},
    40  		},
    41  		{
    42  			name: "empty networking",
    43  			config: &types.InstallConfig{
    44  				TypeMeta: metav1.TypeMeta{
    45  					APIVersion: types.InstallConfigVersion,
    46  				},
    47  				Networking: &types.Networking{},
    48  			},
    49  			expected: &types.InstallConfig{
    50  				TypeMeta: metav1.TypeMeta{
    51  					APIVersion: types.InstallConfigVersion,
    52  				},
    53  				Networking: &types.Networking{},
    54  			},
    55  		},
    56  		{
    57  			// all deprecated fields
    58  			name: "old networking",
    59  			config: &types.InstallConfig{
    60  				TypeMeta: metav1.TypeMeta{
    61  					APIVersion: "v1beta3",
    62  				},
    63  				Networking: &types.Networking{
    64  					DeprecatedMachineCIDR: ipnet.MustParseCIDR("1.1.1.1/24"),
    65  					DeprecatedType:        "foo",
    66  					DeprecatedServiceCIDR: ipnet.MustParseCIDR("1.2.3.4/32"),
    67  					DeprecatedClusterNetworks: []types.ClusterNetworkEntry{
    68  						{
    69  							CIDR: *ipnet.MustParseCIDR("1.2.3.5/32"),
    70  
    71  							DeprecatedHostSubnetLength: 8,
    72  						},
    73  					},
    74  				},
    75  			},
    76  			expected: &types.InstallConfig{
    77  				TypeMeta: metav1.TypeMeta{
    78  					APIVersion: types.InstallConfigVersion,
    79  				},
    80  				Networking: &types.Networking{
    81  					NetworkType: "foo",
    82  					MachineNetwork: []types.MachineNetworkEntry{
    83  						{CIDR: *ipnet.MustParseCIDR("1.1.1.1/24")},
    84  					},
    85  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("1.2.3.4/32")},
    86  					ClusterNetwork: []types.ClusterNetworkEntry{
    87  						{
    88  							CIDR: *ipnet.MustParseCIDR("1.2.3.5/32"),
    89  
    90  							HostPrefix:                 24,
    91  							DeprecatedHostSubnetLength: 8,
    92  						},
    93  					},
    94  
    95  					// deprecated fields are preserved
    96  					DeprecatedType:        "foo",
    97  					DeprecatedMachineCIDR: ipnet.MustParseCIDR("1.1.1.1/24"),
    98  					DeprecatedServiceCIDR: ipnet.MustParseCIDR("1.2.3.4/32"),
    99  					DeprecatedClusterNetworks: []types.ClusterNetworkEntry{
   100  						{
   101  							CIDR: *ipnet.MustParseCIDR("1.2.3.5/32"),
   102  
   103  							HostPrefix:                 24,
   104  							DeprecatedHostSubnetLength: 8,
   105  						},
   106  					},
   107  				},
   108  			},
   109  		},
   110  		{
   111  			name: "new networking",
   112  			config: &types.InstallConfig{
   113  				TypeMeta: metav1.TypeMeta{
   114  					APIVersion: types.InstallConfigVersion,
   115  				},
   116  				Networking: &types.Networking{
   117  					MachineNetwork: []types.MachineNetworkEntry{
   118  						{CIDR: *ipnet.MustParseCIDR("1.1.1.1/24")},
   119  					},
   120  					NetworkType:    "foo",
   121  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("1.2.3.4/32")},
   122  					ClusterNetwork: []types.ClusterNetworkEntry{
   123  						{
   124  							CIDR:       *ipnet.MustParseCIDR("1.2.3.5/32"),
   125  							HostPrefix: 24,
   126  						},
   127  					},
   128  				},
   129  			},
   130  			expected: &types.InstallConfig{
   131  				TypeMeta: metav1.TypeMeta{
   132  					APIVersion: types.InstallConfigVersion,
   133  				},
   134  				Networking: &types.Networking{
   135  					MachineNetwork: []types.MachineNetworkEntry{
   136  						{CIDR: *ipnet.MustParseCIDR("1.1.1.1/24")},
   137  					},
   138  					NetworkType:    "foo",
   139  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("1.2.3.4/32")},
   140  					ClusterNetwork: []types.ClusterNetworkEntry{
   141  						{
   142  							CIDR:       *ipnet.MustParseCIDR("1.2.3.5/32"),
   143  							HostPrefix: 24,
   144  						},
   145  					},
   146  				},
   147  			},
   148  		},
   149  		{
   150  			name: "empty APIVersion",
   151  			config: &types.InstallConfig{
   152  				TypeMeta: metav1.TypeMeta{
   153  					APIVersion: "",
   154  				},
   155  			},
   156  			expectedError: "no version was provided",
   157  		},
   158  		{
   159  			name: "deprecated OpenShiftSDN spelling",
   160  			config: &types.InstallConfig{
   161  				TypeMeta: metav1.TypeMeta{
   162  					APIVersion: types.InstallConfigVersion,
   163  				},
   164  				Networking: &types.Networking{
   165  					NetworkType: "OpenshiftSDN",
   166  				},
   167  			},
   168  			expected: &types.InstallConfig{
   169  				TypeMeta: metav1.TypeMeta{
   170  					APIVersion: types.InstallConfigVersion,
   171  				},
   172  				Networking: &types.Networking{
   173  					NetworkType: "OpenShiftSDN",
   174  				},
   175  			},
   176  		},
   177  		{
   178  			name: "deprecated OpenStack LbFloatingIP",
   179  			config: &types.InstallConfig{
   180  				TypeMeta: metav1.TypeMeta{
   181  					APIVersion: types.InstallConfigVersion,
   182  				},
   183  				Platform: types.Platform{
   184  					OpenStack: &openstack.Platform{
   185  						DeprecatedLbFloatingIP: "10.0.109.1",
   186  					},
   187  				},
   188  			},
   189  			expected: &types.InstallConfig{
   190  				TypeMeta: metav1.TypeMeta{
   191  					APIVersion: types.InstallConfigVersion,
   192  				},
   193  				Platform: types.Platform{
   194  					OpenStack: &openstack.Platform{
   195  						DeprecatedLbFloatingIP: "10.0.109.1",
   196  						APIFloatingIP:          "10.0.109.1",
   197  					},
   198  				},
   199  			},
   200  		},
   201  		{
   202  			name: "deprecated OpenStack LbFloatingIP is the same as APIFloatingIP",
   203  			config: &types.InstallConfig{
   204  				TypeMeta: metav1.TypeMeta{
   205  					APIVersion: types.InstallConfigVersion,
   206  				},
   207  				Platform: types.Platform{
   208  					OpenStack: &openstack.Platform{
   209  						DeprecatedLbFloatingIP: "10.0.109.1",
   210  						APIFloatingIP:          "10.0.109.1",
   211  					},
   212  				},
   213  			},
   214  			expected: &types.InstallConfig{
   215  				TypeMeta: metav1.TypeMeta{
   216  					APIVersion: types.InstallConfigVersion,
   217  				},
   218  				Platform: types.Platform{
   219  					OpenStack: &openstack.Platform{
   220  						DeprecatedLbFloatingIP: "10.0.109.1",
   221  						APIFloatingIP:          "10.0.109.1",
   222  					},
   223  				},
   224  			},
   225  		},
   226  		{
   227  			name: "deprecated OpenStack LbFloatingIP with APIFloatingIP",
   228  			config: &types.InstallConfig{
   229  				TypeMeta: metav1.TypeMeta{
   230  					APIVersion: types.InstallConfigVersion,
   231  				},
   232  				Platform: types.Platform{
   233  					OpenStack: &openstack.Platform{
   234  						DeprecatedLbFloatingIP: "10.0.109.1",
   235  						APIFloatingIP:          "10.0.109.2",
   236  					},
   237  				},
   238  			},
   239  			expectedError: "cannot specify lbFloatingIP and apiFloatingIP together",
   240  		},
   241  
   242  		// BareMetal platform conversions
   243  		{
   244  			name: "baremetal external DHCP",
   245  			config: &types.InstallConfig{
   246  				TypeMeta: metav1.TypeMeta{
   247  					APIVersion: types.InstallConfigVersion,
   248  				},
   249  				Platform: types.Platform{
   250  					BareMetal: &baremetal.Platform{
   251  						DeprecatedProvisioningDHCPExternal: true,
   252  					},
   253  				},
   254  			},
   255  			expected: &types.InstallConfig{
   256  				TypeMeta: metav1.TypeMeta{
   257  					APIVersion: types.InstallConfigVersion,
   258  				},
   259  				Platform: types.Platform{
   260  					BareMetal: &baremetal.Platform{
   261  						DeprecatedProvisioningDHCPExternal: true,
   262  						ProvisioningNetwork:                "Unmanaged",
   263  					},
   264  				},
   265  			},
   266  		},
   267  		{
   268  			name: "baremetal provisioningHostIP -> clusterProvisioningIP",
   269  			config: &types.InstallConfig{
   270  				TypeMeta: metav1.TypeMeta{
   271  					APIVersion: types.InstallConfigVersion,
   272  				},
   273  				Platform: types.Platform{
   274  					BareMetal: &baremetal.Platform{
   275  						DeprecatedProvisioningHostIP: "172.22.0.3",
   276  					},
   277  				},
   278  			},
   279  			expected: &types.InstallConfig{
   280  				TypeMeta: metav1.TypeMeta{
   281  					APIVersion: types.InstallConfigVersion,
   282  				},
   283  				Platform: types.Platform{
   284  					BareMetal: &baremetal.Platform{
   285  						ClusterProvisioningIP:        "172.22.0.3",
   286  						DeprecatedProvisioningHostIP: "172.22.0.3",
   287  					},
   288  				},
   289  			},
   290  		},
   291  		{
   292  			name: "baremetal provisioningHostIP mismatch clusterProvisioningIP",
   293  			config: &types.InstallConfig{
   294  				TypeMeta: metav1.TypeMeta{
   295  					APIVersion: types.InstallConfigVersion,
   296  				},
   297  				Platform: types.Platform{
   298  					BareMetal: &baremetal.Platform{
   299  						ClusterProvisioningIP:        "172.22.0.4",
   300  						DeprecatedProvisioningHostIP: "172.22.0.3",
   301  					},
   302  				},
   303  			},
   304  			expectedError: "provisioningHostIP is deprecated; only clusterProvisioningIP needs to be specified",
   305  		},
   306  		{
   307  			name: "baremetal deprecated apiVIP",
   308  			config: &types.InstallConfig{
   309  				TypeMeta: metav1.TypeMeta{
   310  					APIVersion: types.InstallConfigVersion,
   311  				},
   312  				Platform: types.Platform{
   313  					BareMetal: &baremetal.Platform{
   314  						DeprecatedAPIVIP: "1.2.3.4",
   315  					},
   316  				},
   317  			},
   318  			expected: &types.InstallConfig{
   319  				TypeMeta: metav1.TypeMeta{
   320  					APIVersion: types.InstallConfigVersion,
   321  				},
   322  				Platform: types.Platform{
   323  					BareMetal: &baremetal.Platform{
   324  						DeprecatedAPIVIP: "1.2.3.4",
   325  						APIVIPs:          []string{"1.2.3.4"},
   326  					},
   327  				},
   328  			},
   329  		},
   330  		{
   331  			name: "baremetal deprecated ingressVIP",
   332  			config: &types.InstallConfig{
   333  				TypeMeta: metav1.TypeMeta{
   334  					APIVersion: types.InstallConfigVersion,
   335  				},
   336  				Platform: types.Platform{
   337  					BareMetal: &baremetal.Platform{
   338  						DeprecatedIngressVIP: "1.2.3.4",
   339  					},
   340  				},
   341  			},
   342  			expected: &types.InstallConfig{
   343  				TypeMeta: metav1.TypeMeta{
   344  					APIVersion: types.InstallConfigVersion,
   345  				},
   346  				Platform: types.Platform{
   347  					BareMetal: &baremetal.Platform{
   348  						DeprecatedIngressVIP: "1.2.3.4",
   349  						IngressVIPs:          []string{"1.2.3.4"},
   350  					},
   351  				},
   352  			},
   353  		},
   354  		{
   355  			name: "empty OpenStack platform for controlPlane",
   356  			config: &types.InstallConfig{
   357  				TypeMeta: metav1.TypeMeta{
   358  					APIVersion: types.InstallConfigVersion,
   359  				},
   360  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   361  				ControlPlane: &types.MachinePool{
   362  					Platform: types.MachinePoolPlatform{},
   363  				},
   364  			},
   365  			expected: &types.InstallConfig{
   366  				TypeMeta: metav1.TypeMeta{
   367  					APIVersion: types.InstallConfigVersion,
   368  				},
   369  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   370  				ControlPlane: &types.MachinePool{
   371  					Platform: types.MachinePoolPlatform{},
   372  				},
   373  			},
   374  		},
   375  		{
   376  			name: "empty OpenStack platform for compute",
   377  			config: &types.InstallConfig{
   378  				TypeMeta: metav1.TypeMeta{
   379  					APIVersion: types.InstallConfigVersion,
   380  				},
   381  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   382  				Compute: []types.MachinePool{
   383  					{
   384  						Platform: types.MachinePoolPlatform{},
   385  					},
   386  				},
   387  			},
   388  			expected: &types.InstallConfig{
   389  				TypeMeta: metav1.TypeMeta{
   390  					APIVersion: types.InstallConfigVersion,
   391  				},
   392  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   393  				Compute: []types.MachinePool{
   394  					{
   395  						Platform: types.MachinePoolPlatform{},
   396  					},
   397  				},
   398  			},
   399  		},
   400  		{
   401  			name: "deprecated OpenStack computeFlavor",
   402  			config: &types.InstallConfig{
   403  				TypeMeta: metav1.TypeMeta{
   404  					APIVersion: types.InstallConfigVersion,
   405  				},
   406  				Platform: types.Platform{
   407  					OpenStack: &openstack.Platform{
   408  						DeprecatedFlavorName: "big-flavor",
   409  					},
   410  				},
   411  			},
   412  			expected: &types.InstallConfig{
   413  				TypeMeta: metav1.TypeMeta{
   414  					APIVersion: types.InstallConfigVersion,
   415  				},
   416  				Platform: types.Platform{
   417  					OpenStack: &openstack.Platform{
   418  						DeprecatedFlavorName: "big-flavor",
   419  						DefaultMachinePlatform: &openstack.MachinePool{
   420  							FlavorName: "big-flavor",
   421  						},
   422  					},
   423  				},
   424  			},
   425  		},
   426  		{
   427  			name: "deprecated OpenStack computeFlavor with type in defaultMachinePlatform",
   428  			config: &types.InstallConfig{
   429  				TypeMeta: metav1.TypeMeta{
   430  					APIVersion: types.InstallConfigVersion,
   431  				},
   432  				Platform: types.Platform{
   433  					OpenStack: &openstack.Platform{
   434  						DeprecatedFlavorName: "flavor1",
   435  						DefaultMachinePlatform: &openstack.MachinePool{
   436  							FlavorName: "flavor2",
   437  						},
   438  					},
   439  				},
   440  			},
   441  			expectedError: "cannot specify computeFlavor and type in defaultMachinePlatform together",
   442  		},
   443  		{
   444  			name: "deprecated OpenStack controlPlane with type in rootVolume",
   445  			config: &types.InstallConfig{
   446  				TypeMeta: metav1.TypeMeta{
   447  					APIVersion: types.InstallConfigVersion,
   448  				},
   449  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   450  				ControlPlane: &types.MachinePool{
   451  					Platform: types.MachinePoolPlatform{
   452  						OpenStack: &openstack.MachinePool{
   453  							RootVolume: &openstack.RootVolume{
   454  								DeprecatedType: "fast",
   455  							},
   456  						},
   457  					},
   458  				},
   459  			},
   460  			expected: &types.InstallConfig{
   461  				TypeMeta: metav1.TypeMeta{
   462  					APIVersion: types.InstallConfigVersion,
   463  				},
   464  				Platform: types.Platform{OpenStack: &openstack.Platform{}},
   465  				ControlPlane: &types.MachinePool{
   466  					Platform: types.MachinePoolPlatform{
   467  						OpenStack: &openstack.MachinePool{
   468  							RootVolume: &openstack.RootVolume{
   469  								Types: []string{"fast"},
   470  							},
   471  						},
   472  					},
   473  				},
   474  			},
   475  		},
   476  		{
   477  			name: "openstack deprecated apiVIP",
   478  			config: &types.InstallConfig{
   479  				TypeMeta: metav1.TypeMeta{
   480  					APIVersion: types.InstallConfigVersion,
   481  				},
   482  				Platform: types.Platform{
   483  					OpenStack: &openstack.Platform{
   484  						DeprecatedAPIVIP: "1.2.3.4",
   485  					},
   486  				},
   487  			},
   488  			expected: &types.InstallConfig{
   489  				TypeMeta: metav1.TypeMeta{
   490  					APIVersion: types.InstallConfigVersion,
   491  				},
   492  				Platform: types.Platform{
   493  					OpenStack: &openstack.Platform{
   494  						DeprecatedAPIVIP: "1.2.3.4",
   495  						APIVIPs:          []string{"1.2.3.4"},
   496  					},
   497  				},
   498  			},
   499  		},
   500  		{
   501  			name: "openstack deprecated ingressVIP",
   502  			config: &types.InstallConfig{
   503  				TypeMeta: metav1.TypeMeta{
   504  					APIVersion: types.InstallConfigVersion,
   505  				},
   506  				Platform: types.Platform{
   507  					OpenStack: &openstack.Platform{
   508  						DeprecatedIngressVIP: "1.2.3.4",
   509  					},
   510  				},
   511  			},
   512  			expected: &types.InstallConfig{
   513  				TypeMeta: metav1.TypeMeta{
   514  					APIVersion: types.InstallConfigVersion,
   515  				},
   516  				Platform: types.Platform{
   517  					OpenStack: &openstack.Platform{
   518  						DeprecatedIngressVIP: "1.2.3.4",
   519  						IngressVIPs:          []string{"1.2.3.4"},
   520  					},
   521  				},
   522  			},
   523  		},
   524  		{
   525  			name: "vsphere deprecated apiVIP",
   526  			config: &types.InstallConfig{
   527  				TypeMeta: metav1.TypeMeta{
   528  					APIVersion: types.InstallConfigVersion,
   529  				},
   530  				Platform: types.Platform{
   531  					VSphere: &vsphere.Platform{
   532  						DeprecatedAPIVIP: "1.2.3.4",
   533  					},
   534  				},
   535  			},
   536  			expected: &types.InstallConfig{
   537  				TypeMeta: metav1.TypeMeta{
   538  					APIVersion: types.InstallConfigVersion,
   539  				},
   540  				Platform: types.Platform{
   541  					VSphere: &vsphere.Platform{
   542  						VCenters: []vsphere.VCenter{{
   543  							Server:      "",
   544  							Port:        443,
   545  							Username:    "",
   546  							Password:    "",
   547  							Datacenters: nil,
   548  						}},
   549  						FailureDomains: []vsphere.FailureDomain{{
   550  							Name:   "generated-failure-domain",
   551  							Region: "generated-region",
   552  							Zone:   "generated-zone",
   553  							Server: "",
   554  							Topology: vsphere.Topology{
   555  								Datacenter:     "",
   556  								ComputeCluster: "",
   557  								Networks:       []string{""},
   558  								Datastore:      "",
   559  								ResourcePool:   "",
   560  								Folder:         "",
   561  							},
   562  						}},
   563  						DeprecatedAPIVIP: "1.2.3.4",
   564  						APIVIPs:          []string{"1.2.3.4"},
   565  					},
   566  				},
   567  			},
   568  		},
   569  		{
   570  			name: "vsphere deprecated ingressVIP",
   571  			config: &types.InstallConfig{
   572  				TypeMeta: metav1.TypeMeta{
   573  					APIVersion: types.InstallConfigVersion,
   574  				},
   575  				Platform: types.Platform{
   576  					VSphere: &vsphere.Platform{
   577  						DeprecatedIngressVIP: "1.2.3.4",
   578  					},
   579  				},
   580  			},
   581  			expected: &types.InstallConfig{
   582  				TypeMeta: metav1.TypeMeta{
   583  					APIVersion: types.InstallConfigVersion,
   584  				},
   585  				Platform: types.Platform{
   586  					VSphere: &vsphere.Platform{
   587  						VCenters: []vsphere.VCenter{{
   588  							Server:      "",
   589  							Port:        443,
   590  							Username:    "",
   591  							Password:    "",
   592  							Datacenters: nil,
   593  						}},
   594  						FailureDomains: []vsphere.FailureDomain{{
   595  							Name:   "generated-failure-domain",
   596  							Region: "generated-region",
   597  							Zone:   "generated-zone",
   598  							Server: "",
   599  							Topology: vsphere.Topology{
   600  								Datacenter:     "",
   601  								ComputeCluster: "",
   602  								Networks:       []string{""},
   603  								Datastore:      "",
   604  								ResourcePool:   "",
   605  								Folder:         "",
   606  							},
   607  						}},
   608  						DeprecatedIngressVIP: "1.2.3.4",
   609  						IngressVIPs:          []string{"1.2.3.4"},
   610  					},
   611  				},
   612  			},
   613  		},
   614  		{
   615  			name: "ovirt deprecated apiVIP",
   616  			config: &types.InstallConfig{
   617  				TypeMeta: metav1.TypeMeta{
   618  					APIVersion: types.InstallConfigVersion,
   619  				},
   620  				Platform: types.Platform{
   621  					Ovirt: &ovirt.Platform{
   622  						DeprecatedAPIVIP: "1.2.3.4",
   623  					},
   624  				},
   625  			},
   626  			expected: &types.InstallConfig{
   627  				TypeMeta: metav1.TypeMeta{
   628  					APIVersion: types.InstallConfigVersion,
   629  				},
   630  				Platform: types.Platform{
   631  					Ovirt: &ovirt.Platform{
   632  						DeprecatedAPIVIP: "1.2.3.4",
   633  						APIVIPs:          []string{"1.2.3.4"},
   634  					},
   635  				},
   636  			},
   637  		},
   638  		{
   639  			name: "ovirt deprecated ingressVIP",
   640  			config: &types.InstallConfig{
   641  				TypeMeta: metav1.TypeMeta{
   642  					APIVersion: types.InstallConfigVersion,
   643  				},
   644  				Platform: types.Platform{
   645  					Ovirt: &ovirt.Platform{
   646  						DeprecatedIngressVIP: "1.2.3.4",
   647  					},
   648  				},
   649  			},
   650  			expected: &types.InstallConfig{
   651  				TypeMeta: metav1.TypeMeta{
   652  					APIVersion: types.InstallConfigVersion,
   653  				},
   654  				Platform: types.Platform{
   655  					Ovirt: &ovirt.Platform{
   656  						DeprecatedIngressVIP: "1.2.3.4",
   657  						IngressVIPs:          []string{"1.2.3.4"},
   658  					},
   659  				},
   660  			},
   661  		},
   662  		{
   663  			name: "nutanix deprecated apiVIP",
   664  			config: &types.InstallConfig{
   665  				TypeMeta: metav1.TypeMeta{
   666  					APIVersion: types.InstallConfigVersion,
   667  				},
   668  				Platform: types.Platform{
   669  					Nutanix: &nutanix.Platform{
   670  						DeprecatedAPIVIP: "1.2.3.4",
   671  					},
   672  				},
   673  			},
   674  			expected: &types.InstallConfig{
   675  				TypeMeta: metav1.TypeMeta{
   676  					APIVersion: types.InstallConfigVersion,
   677  				},
   678  				Platform: types.Platform{
   679  					Nutanix: &nutanix.Platform{
   680  						DeprecatedAPIVIP: "1.2.3.4",
   681  						APIVIPs:          []string{"1.2.3.4"},
   682  					},
   683  				},
   684  			},
   685  		},
   686  		{
   687  			name: "nutanix deprecated ingressVIP",
   688  			config: &types.InstallConfig{
   689  				TypeMeta: metav1.TypeMeta{
   690  					APIVersion: types.InstallConfigVersion,
   691  				},
   692  				Platform: types.Platform{
   693  					Nutanix: &nutanix.Platform{
   694  						DeprecatedIngressVIP: "1.2.3.4",
   695  					},
   696  				},
   697  			},
   698  			expected: &types.InstallConfig{
   699  				TypeMeta: metav1.TypeMeta{
   700  					APIVersion: types.InstallConfigVersion,
   701  				},
   702  				Platform: types.Platform{
   703  					Nutanix: &nutanix.Platform{
   704  						DeprecatedIngressVIP: "1.2.3.4",
   705  						IngressVIPs:          []string{"1.2.3.4"},
   706  					},
   707  				},
   708  			},
   709  		},
   710  		{
   711  			name: "aws deprecated platform amiID",
   712  			config: &types.InstallConfig{
   713  				TypeMeta: metav1.TypeMeta{
   714  					APIVersion: types.InstallConfigVersion,
   715  				},
   716  				Platform: types.Platform{
   717  					AWS: &aws.Platform{
   718  						AMIID: "deprec-id",
   719  					},
   720  				},
   721  			},
   722  			expected: &types.InstallConfig{
   723  				TypeMeta: metav1.TypeMeta{
   724  					APIVersion: types.InstallConfigVersion,
   725  				},
   726  				Platform: types.Platform{
   727  					AWS: &aws.Platform{
   728  						AMIID: "deprec-id",
   729  						DefaultMachinePlatform: &aws.MachinePool{
   730  							AMIID: "deprec-id",
   731  						},
   732  					},
   733  				},
   734  			},
   735  		},
   736  	}
   737  
   738  	for _, tc := range cases {
   739  		t.Run(tc.name, func(t *testing.T) {
   740  			err := ConvertInstallConfig(tc.config)
   741  			if tc.expectedError == "" {
   742  				assert.NoError(t, err)
   743  				assert.Equal(t, tc.expected, tc.config, "unexpected install config")
   744  			} else {
   745  				assert.Regexp(t, tc.expectedError, err)
   746  			}
   747  		})
   748  	}
   749  }
   750  
   751  func Test_upconvertVIPs(t *testing.T) {
   752  	tests := []struct {
   753  		name     string
   754  		vips     []string
   755  		oldVIP   string
   756  		wantErr  bool
   757  		wantVIPs []string
   758  	}{
   759  		{
   760  			name:     "should return error if both fields are set and all are unique",
   761  			vips:     []string{"foo", "bar"},
   762  			oldVIP:   "baz",
   763  			wantErr:  true,
   764  			wantVIPs: []string{},
   765  		},
   766  		{
   767  			name:     "should set VIPs if old VIPs is set",
   768  			vips:     []string{},
   769  			oldVIP:   "baz",
   770  			wantErr:  false,
   771  			wantVIPs: []string{"baz"},
   772  		},
   773  		{
   774  			name:     "should return VIPs if only new VIPs is set",
   775  			vips:     []string{"foo", "bar"},
   776  			oldVIP:   "",
   777  			wantErr:  false,
   778  			wantVIPs: []string{"foo", "bar"},
   779  		},
   780  		{
   781  			name:     "should return no error if old VIP is contained in new VIPs",
   782  			vips:     []string{"foo", "bar"},
   783  			oldVIP:   "bar",
   784  			wantErr:  false,
   785  			wantVIPs: []string{"foo", "bar"},
   786  		},
   787  		{
   788  			name:     "should not fail on nil",
   789  			vips:     nil,
   790  			oldVIP:   "",
   791  			wantErr:  false,
   792  			wantVIPs: []string{},
   793  		},
   794  	}
   795  	for _, tt := range tests {
   796  		t.Run(tt.name, func(t *testing.T) {
   797  			if err := upconvertVIP(&tt.vips, tt.oldVIP, "new", "old", field.NewPath("test")); (err != nil) != tt.wantErr {
   798  				t.Errorf("upconvertVIP() error = %v, wantErr %v", err, tt.wantErr)
   799  			} else {
   800  				if !tt.wantErr {
   801  					for _, wantVIP := range tt.wantVIPs {
   802  						if !utilsslice.Contains(tt.vips, wantVIP) {
   803  							t.Errorf("upconvertVIP() didn't update VIPs field (expected \"%v\" to contain \"%s\")", tt.vips, wantVIP)
   804  						}
   805  					}
   806  				}
   807  			}
   808  		})
   809  	}
   810  }