github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/installconfig_test.go (about)

     1  package installconfig
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/stretchr/testify/assert"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/utils/pointer"
    13  
    14  	"github.com/openshift/installer/pkg/asset"
    15  	"github.com/openshift/installer/pkg/asset/mock"
    16  	"github.com/openshift/installer/pkg/ipnet"
    17  	"github.com/openshift/installer/pkg/types"
    18  	"github.com/openshift/installer/pkg/types/aws"
    19  	"github.com/openshift/installer/pkg/types/none"
    20  )
    21  
    22  func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) {
    23  	sshPublicKey := &sshPublicKey{}
    24  	baseDomain := &baseDomain{"test-domain", types.ExternalPublishingStrategy}
    25  	clusterName := &clusterName{"test-cluster"}
    26  	pullSecret := &pullSecret{`{"auths":{"example.com":{"auth":"authorization value"}}}`}
    27  	platform := &platform{
    28  		Platform: types.Platform{None: &none.Platform{}},
    29  	}
    30  	installConfig := &InstallConfig{}
    31  	parents := asset.Parents{}
    32  	parents.Add(
    33  		sshPublicKey,
    34  		baseDomain,
    35  		clusterName,
    36  		pullSecret,
    37  		platform,
    38  	)
    39  	if err := installConfig.Generate(context.Background(), parents); err != nil {
    40  		t.Errorf("unexpected error generating install config: %v", err)
    41  	}
    42  	expected := &types.InstallConfig{
    43  		TypeMeta: metav1.TypeMeta{
    44  			APIVersion: types.InstallConfigVersion,
    45  		},
    46  		ObjectMeta: metav1.ObjectMeta{
    47  			Name: "test-cluster",
    48  		},
    49  		AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
    50  		BaseDomain:                  "test-domain",
    51  		Networking: &types.Networking{
    52  			MachineNetwork: []types.MachineNetworkEntry{
    53  				{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
    54  			},
    55  			NetworkType:    "OVNKubernetes",
    56  			ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
    57  			ClusterNetwork: []types.ClusterNetworkEntry{
    58  				{
    59  					CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
    60  					HostPrefix: 23,
    61  				},
    62  			},
    63  		},
    64  		ControlPlane: &types.MachinePool{
    65  			Name:           "master",
    66  			Replicas:       pointer.Int64Ptr(3),
    67  			Hyperthreading: types.HyperthreadingEnabled,
    68  			Architecture:   types.ArchitectureAMD64,
    69  		},
    70  		Compute: []types.MachinePool{
    71  			{
    72  				Name:           "worker",
    73  				Replicas:       pointer.Int64Ptr(3),
    74  				Hyperthreading: types.HyperthreadingEnabled,
    75  				Architecture:   types.ArchitectureAMD64,
    76  			},
    77  		},
    78  		Platform: types.Platform{
    79  			None: &none.Platform{},
    80  		},
    81  		PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
    82  		Publish:    types.ExternalPublishingStrategy,
    83  	}
    84  	assert.Equal(t, expected, installConfig.Config, "unexpected config generated")
    85  }
    86  
    87  func TestInstallConfigLoad(t *testing.T) {
    88  	cases := []struct {
    89  		name           string
    90  		data           string
    91  		fetchError     error
    92  		expectedFound  bool
    93  		expectedError  bool
    94  		expectedConfig *types.InstallConfig
    95  	}{
    96  		{
    97  			name: "valid InstallConfig",
    98  			data: `
    99  apiVersion: v1
   100  metadata:
   101    name: test-cluster
   102  baseDomain: test-domain
   103  platform:
   104    aws:
   105      region: us-east-1
   106  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   107  `,
   108  			expectedFound: true,
   109  			expectedConfig: &types.InstallConfig{
   110  				TypeMeta: metav1.TypeMeta{
   111  					APIVersion: types.InstallConfigVersion,
   112  				},
   113  				ObjectMeta: metav1.ObjectMeta{
   114  					Name: "test-cluster",
   115  				},
   116  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   117  				BaseDomain:                  "test-domain",
   118  				Networking: &types.Networking{
   119  					MachineNetwork: []types.MachineNetworkEntry{
   120  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   121  					},
   122  					NetworkType:    "OVNKubernetes",
   123  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   124  					ClusterNetwork: []types.ClusterNetworkEntry{
   125  						{
   126  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   127  							HostPrefix: 23,
   128  						},
   129  					},
   130  				},
   131  				ControlPlane: &types.MachinePool{
   132  					Name:           "master",
   133  					Replicas:       pointer.Int64Ptr(3),
   134  					Hyperthreading: types.HyperthreadingEnabled,
   135  					Architecture:   types.ArchitectureAMD64,
   136  				},
   137  				Compute: []types.MachinePool{
   138  					{
   139  						Name:           "worker",
   140  						Replicas:       pointer.Int64Ptr(3),
   141  						Hyperthreading: types.HyperthreadingEnabled,
   142  						Architecture:   types.ArchitectureAMD64,
   143  					},
   144  				},
   145  				Platform: types.Platform{
   146  					AWS: &aws.Platform{
   147  						Region: "us-east-1",
   148  					},
   149  				},
   150  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   151  				Publish:    types.ExternalPublishingStrategy,
   152  			},
   153  		},
   154  		{
   155  			name: "invalid InstallConfig",
   156  			data: `
   157  metadata:
   158    name: test-cluster
   159  `,
   160  			expectedError: true,
   161  		},
   162  		{
   163  			name:          "empty",
   164  			data:          "",
   165  			expectedError: true,
   166  		},
   167  		{
   168  			name:          "not yaml",
   169  			data:          "This is not yaml.",
   170  			expectedError: true,
   171  		},
   172  		{
   173  			name:       "file not found",
   174  			fetchError: &os.PathError{Err: os.ErrNotExist},
   175  		},
   176  		{
   177  			name:          "error fetching file",
   178  			fetchError:    errors.New("fetch failed"),
   179  			expectedError: true,
   180  		},
   181  		{
   182  			name: "unknown field",
   183  			data: `
   184  apiVersion: v1
   185  metadata:
   186    name: test-cluster
   187  additionalTrustBundlePolicy: Proxyonly
   188  baseDomain: test-domain
   189  platform:
   190    aws:
   191      region: us-east-1
   192  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   193  wrong_key: wrong_value 
   194  `,
   195  			expectedFound: true,
   196  			expectedConfig: &types.InstallConfig{
   197  				TypeMeta: metav1.TypeMeta{
   198  					APIVersion: types.InstallConfigVersion,
   199  				},
   200  				ObjectMeta: metav1.ObjectMeta{
   201  					Name: "test-cluster",
   202  				},
   203  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   204  				BaseDomain:                  "test-domain",
   205  				Networking: &types.Networking{
   206  					MachineNetwork: []types.MachineNetworkEntry{
   207  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   208  					},
   209  					NetworkType:    "OVNKubernetes",
   210  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   211  					ClusterNetwork: []types.ClusterNetworkEntry{
   212  						{
   213  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   214  							HostPrefix: 23,
   215  						},
   216  					},
   217  				},
   218  				ControlPlane: &types.MachinePool{
   219  					Name:           "master",
   220  					Replicas:       pointer.Int64Ptr(3),
   221  					Hyperthreading: types.HyperthreadingEnabled,
   222  					Architecture:   types.ArchitectureAMD64,
   223  				},
   224  				Compute: []types.MachinePool{
   225  					{
   226  						Name:           "worker",
   227  						Replicas:       pointer.Int64Ptr(3),
   228  						Hyperthreading: types.HyperthreadingEnabled,
   229  						Architecture:   types.ArchitectureAMD64,
   230  					},
   231  				},
   232  				Platform: types.Platform{
   233  					AWS: &aws.Platform{
   234  						Region: "us-east-1",
   235  					},
   236  				},
   237  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   238  				Publish:    types.ExternalPublishingStrategy,
   239  			},
   240  		},
   241  		{
   242  			name: "old valid InstallConfig",
   243  			data: `
   244  apiVersion: v1beta3
   245  metadata:
   246    name: test-cluster
   247  baseDomain: test-domain
   248  platform:
   249    aws:
   250      region: us-east-1
   251  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   252  `,
   253  			expectedFound: true,
   254  			expectedConfig: &types.InstallConfig{
   255  				TypeMeta: metav1.TypeMeta{
   256  					APIVersion: types.InstallConfigVersion,
   257  				},
   258  				ObjectMeta: metav1.ObjectMeta{
   259  					Name: "test-cluster",
   260  				},
   261  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   262  				BaseDomain:                  "test-domain",
   263  				Networking: &types.Networking{
   264  					MachineNetwork: []types.MachineNetworkEntry{
   265  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   266  					},
   267  					NetworkType:    "OVNKubernetes",
   268  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   269  					ClusterNetwork: []types.ClusterNetworkEntry{
   270  						{
   271  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   272  							HostPrefix: 23,
   273  						},
   274  					},
   275  				},
   276  				ControlPlane: &types.MachinePool{
   277  					Name:           "master",
   278  					Replicas:       pointer.Int64Ptr(3),
   279  					Hyperthreading: types.HyperthreadingEnabled,
   280  					Architecture:   types.ArchitectureAMD64,
   281  				},
   282  				Compute: []types.MachinePool{
   283  					{
   284  						Name:           "worker",
   285  						Replicas:       pointer.Int64Ptr(3),
   286  						Hyperthreading: types.HyperthreadingEnabled,
   287  						Architecture:   types.ArchitectureAMD64,
   288  					},
   289  				},
   290  				Platform: types.Platform{
   291  					AWS: &aws.Platform{
   292  						Region: "us-east-1",
   293  					},
   294  				},
   295  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   296  				Publish:    types.ExternalPublishingStrategy,
   297  			},
   298  		},
   299  		{
   300  			name: "experimentalPropagateUserTags takes precedence",
   301  			data: `
   302  apiVersion: v1
   303  metadata:
   304    name: test-cluster
   305  baseDomain: test-domain
   306  platform:
   307    aws:
   308      region: us-east-1
   309      experimentalPropagateUserTags: false
   310      propagateUserTags: true
   311  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   312  `,
   313  			expectedFound: true,
   314  			expectedConfig: &types.InstallConfig{
   315  				TypeMeta: metav1.TypeMeta{
   316  					APIVersion: types.InstallConfigVersion,
   317  				},
   318  				ObjectMeta: metav1.ObjectMeta{
   319  					Name: "test-cluster",
   320  				},
   321  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   322  				BaseDomain:                  "test-domain",
   323  				Networking: &types.Networking{
   324  					MachineNetwork: []types.MachineNetworkEntry{
   325  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   326  					},
   327  					NetworkType:    "OVNKubernetes",
   328  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   329  					ClusterNetwork: []types.ClusterNetworkEntry{
   330  						{
   331  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   332  							HostPrefix: 23,
   333  						},
   334  					},
   335  				},
   336  				ControlPlane: &types.MachinePool{
   337  					Name:           "master",
   338  					Replicas:       pointer.Int64Ptr(3),
   339  					Hyperthreading: types.HyperthreadingEnabled,
   340  					Architecture:   types.ArchitectureAMD64,
   341  				},
   342  				Compute: []types.MachinePool{
   343  					{
   344  						Name:           "worker",
   345  						Replicas:       pointer.Int64Ptr(3),
   346  						Hyperthreading: types.HyperthreadingEnabled,
   347  						Architecture:   types.ArchitectureAMD64,
   348  					},
   349  				},
   350  				Platform: types.Platform{
   351  					AWS: &aws.Platform{
   352  						Region:                       "us-east-1",
   353  						ExperimentalPropagateUserTag: pointer.BoolPtr(false),
   354  						PropagateUserTag:             false,
   355  					},
   356  				},
   357  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   358  				Publish:    types.ExternalPublishingStrategy,
   359  			},
   360  		},
   361  		{
   362  			name: "missing experimentalPropagateUserTags",
   363  			data: `
   364  apiVersion: v1
   365  metadata:
   366    name: test-cluster
   367  baseDomain: test-domain
   368  platform:
   369    aws:
   370      region: us-east-1
   371      propagateUserTags: true
   372  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   373  `,
   374  			expectedFound: true,
   375  			expectedConfig: &types.InstallConfig{
   376  				TypeMeta: metav1.TypeMeta{
   377  					APIVersion: types.InstallConfigVersion,
   378  				},
   379  				ObjectMeta: metav1.ObjectMeta{
   380  					Name: "test-cluster",
   381  				},
   382  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   383  				BaseDomain:                  "test-domain",
   384  				Networking: &types.Networking{
   385  					MachineNetwork: []types.MachineNetworkEntry{
   386  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   387  					},
   388  					NetworkType:    "OVNKubernetes",
   389  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   390  					ClusterNetwork: []types.ClusterNetworkEntry{
   391  						{
   392  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   393  							HostPrefix: 23,
   394  						},
   395  					},
   396  				},
   397  				ControlPlane: &types.MachinePool{
   398  					Name:           "master",
   399  					Replicas:       pointer.Int64Ptr(3),
   400  					Hyperthreading: types.HyperthreadingEnabled,
   401  					Architecture:   types.ArchitectureAMD64,
   402  				},
   403  				Compute: []types.MachinePool{
   404  					{
   405  						Name:           "worker",
   406  						Replicas:       pointer.Int64Ptr(3),
   407  						Hyperthreading: types.HyperthreadingEnabled,
   408  						Architecture:   types.ArchitectureAMD64,
   409  					},
   410  				},
   411  				Platform: types.Platform{
   412  					AWS: &aws.Platform{
   413  						Region:                       "us-east-1",
   414  						ExperimentalPropagateUserTag: nil,
   415  						PropagateUserTag:             true,
   416  					},
   417  				},
   418  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   419  				Publish:    types.ExternalPublishingStrategy,
   420  			},
   421  		},
   422  		{
   423  			name: "support only experimental - backport test",
   424  			data: `
   425  apiVersion: v1
   426  metadata:
   427    name: test-cluster
   428  baseDomain: test-domain
   429  platform:
   430    aws:
   431      region: us-east-1
   432      experimentalPropagateUsertags: true
   433  pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}"
   434  `,
   435  			expectedFound: true,
   436  			expectedConfig: &types.InstallConfig{
   437  				TypeMeta: metav1.TypeMeta{
   438  					APIVersion: types.InstallConfigVersion,
   439  				},
   440  				ObjectMeta: metav1.ObjectMeta{
   441  					Name: "test-cluster",
   442  				},
   443  				AdditionalTrustBundlePolicy: types.PolicyProxyOnly,
   444  				BaseDomain:                  "test-domain",
   445  				Networking: &types.Networking{
   446  					MachineNetwork: []types.MachineNetworkEntry{
   447  						{CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")},
   448  					},
   449  					NetworkType:    "OVNKubernetes",
   450  					ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")},
   451  					ClusterNetwork: []types.ClusterNetworkEntry{
   452  						{
   453  							CIDR:       *ipnet.MustParseCIDR("10.128.0.0/14"),
   454  							HostPrefix: 23,
   455  						},
   456  					},
   457  				},
   458  				ControlPlane: &types.MachinePool{
   459  					Name:           "master",
   460  					Replicas:       pointer.Int64Ptr(3),
   461  					Hyperthreading: types.HyperthreadingEnabled,
   462  					Architecture:   types.ArchitectureAMD64,
   463  				},
   464  				Compute: []types.MachinePool{
   465  					{
   466  						Name:           "worker",
   467  						Replicas:       pointer.Int64Ptr(3),
   468  						Hyperthreading: types.HyperthreadingEnabled,
   469  						Architecture:   types.ArchitectureAMD64,
   470  					},
   471  				},
   472  				Platform: types.Platform{
   473  					AWS: &aws.Platform{
   474  						Region:                       "us-east-1",
   475  						ExperimentalPropagateUserTag: pointer.BoolPtr(true),
   476  						PropagateUserTag:             true,
   477  					},
   478  				},
   479  				PullSecret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
   480  				Publish:    types.ExternalPublishingStrategy,
   481  			},
   482  		},
   483  	}
   484  	for _, tc := range cases {
   485  		t.Run(tc.name, func(t *testing.T) {
   486  			mockCtrl := gomock.NewController(t)
   487  			defer mockCtrl.Finish()
   488  
   489  			fileFetcher := mock.NewMockFileFetcher(mockCtrl)
   490  			fileFetcher.EXPECT().FetchByName(installConfigFilename).
   491  				Return(
   492  					&asset.File{
   493  						Filename: installConfigFilename,
   494  						Data:     []byte(tc.data)},
   495  					tc.fetchError,
   496  				)
   497  
   498  			ic := &InstallConfig{}
   499  			found, err := ic.Load(fileFetcher)
   500  			assert.Equal(t, tc.expectedFound, found, "unexpected found value returned from Load")
   501  			if tc.expectedError {
   502  				assert.Error(t, err, "expected error from Load")
   503  			} else {
   504  				assert.NoError(t, err, "unexpected error from Load")
   505  			}
   506  			if tc.expectedFound {
   507  				assert.Equal(t, tc.expectedConfig, ic.Config, "unexpected Config in InstallConfig")
   508  			}
   509  		})
   510  	}
   511  }