github.com/openshift/installer@v1.4.17/pkg/asset/machines/master_test.go (about)

     1  package machines
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
     9  	"github.com/stretchr/testify/assert"
    10  	corev1 "k8s.io/api/core/v1"
    11  	v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	"k8s.io/utils/pointer"
    14  	"sigs.k8s.io/yaml"
    15  
    16  	"github.com/openshift/installer/pkg/asset"
    17  	"github.com/openshift/installer/pkg/asset/ignition/machine"
    18  	"github.com/openshift/installer/pkg/asset/installconfig"
    19  	"github.com/openshift/installer/pkg/asset/rhcos"
    20  	"github.com/openshift/installer/pkg/types"
    21  	awstypes "github.com/openshift/installer/pkg/types/aws"
    22  	"github.com/openshift/installer/pkg/types/baremetal"
    23  )
    24  
    25  func TestMasterGenerateMachineConfigs(t *testing.T) {
    26  	cases := []struct {
    27  		name                  string
    28  		key                   string
    29  		hyperthreading        types.HyperthreadingMode
    30  		expectedMachineConfig []string
    31  	}{
    32  		{
    33  			name:           "no key hyperthreading enabled",
    34  			hyperthreading: types.HyperthreadingEnabled,
    35  		},
    36  		{
    37  			name:           "key present hyperthreading enabled",
    38  			key:            "ssh-rsa: dummy-key",
    39  			hyperthreading: types.HyperthreadingEnabled,
    40  			expectedMachineConfig: []string{`apiVersion: machineconfiguration.openshift.io/v1
    41  kind: MachineConfig
    42  metadata:
    43    creationTimestamp: null
    44    labels:
    45      machineconfiguration.openshift.io/role: master
    46    name: 99-master-ssh
    47  spec:
    48    baseOSExtensionsContainerImage: ""
    49    config:
    50      ignition:
    51        version: 3.2.0
    52      passwd:
    53        users:
    54        - name: core
    55          sshAuthorizedKeys:
    56          - 'ssh-rsa: dummy-key'
    57    extensions: null
    58    fips: false
    59    kernelArguments: null
    60    kernelType: ""
    61    osImageURL: ""
    62  `},
    63  		},
    64  		{
    65  			name:           "no key hyperthreading disabled",
    66  			hyperthreading: types.HyperthreadingDisabled,
    67  			expectedMachineConfig: []string{`apiVersion: machineconfiguration.openshift.io/v1
    68  kind: MachineConfig
    69  metadata:
    70    creationTimestamp: null
    71    labels:
    72      machineconfiguration.openshift.io/role: master
    73    name: 99-master-disable-hyperthreading
    74  spec:
    75    baseOSExtensionsContainerImage: ""
    76    config:
    77      ignition:
    78        version: 3.2.0
    79    extensions: null
    80    fips: false
    81    kernelArguments:
    82    - nosmt
    83    - smt-enabled=off
    84    kernelType: ""
    85    osImageURL: ""
    86  `},
    87  		},
    88  		{
    89  			name:           "key present hyperthreading disabled",
    90  			key:            "ssh-rsa: dummy-key",
    91  			hyperthreading: types.HyperthreadingDisabled,
    92  			expectedMachineConfig: []string{`apiVersion: machineconfiguration.openshift.io/v1
    93  kind: MachineConfig
    94  metadata:
    95    creationTimestamp: null
    96    labels:
    97      machineconfiguration.openshift.io/role: master
    98    name: 99-master-disable-hyperthreading
    99  spec:
   100    baseOSExtensionsContainerImage: ""
   101    config:
   102      ignition:
   103        version: 3.2.0
   104    extensions: null
   105    fips: false
   106    kernelArguments:
   107    - nosmt
   108    - smt-enabled=off
   109    kernelType: ""
   110    osImageURL: ""
   111  `, `apiVersion: machineconfiguration.openshift.io/v1
   112  kind: MachineConfig
   113  metadata:
   114    creationTimestamp: null
   115    labels:
   116      machineconfiguration.openshift.io/role: master
   117    name: 99-master-ssh
   118  spec:
   119    baseOSExtensionsContainerImage: ""
   120    config:
   121      ignition:
   122        version: 3.2.0
   123      passwd:
   124        users:
   125        - name: core
   126          sshAuthorizedKeys:
   127          - 'ssh-rsa: dummy-key'
   128    extensions: null
   129    fips: false
   130    kernelArguments: null
   131    kernelType: ""
   132    osImageURL: ""
   133  `},
   134  		},
   135  	}
   136  	for _, tc := range cases {
   137  		t.Run(tc.name, func(t *testing.T) {
   138  			parents := asset.Parents{}
   139  			parents.Add(
   140  				&installconfig.ClusterID{
   141  					UUID:    "test-uuid",
   142  					InfraID: "test-infra-id",
   143  				},
   144  				installconfig.MakeAsset(
   145  					&types.InstallConfig{
   146  						ObjectMeta: metav1.ObjectMeta{
   147  							Name: "test-cluster",
   148  						},
   149  						SSHKey:     tc.key,
   150  						BaseDomain: "test-domain",
   151  						Platform: types.Platform{
   152  							AWS: &awstypes.Platform{
   153  								Region: "us-east-1",
   154  							},
   155  						},
   156  						ControlPlane: &types.MachinePool{
   157  							Hyperthreading: tc.hyperthreading,
   158  							Replicas:       pointer.Int64Ptr(1),
   159  							Platform: types.MachinePoolPlatform{
   160  								AWS: &awstypes.MachinePool{
   161  									Zones:        []string{"us-east-1a"},
   162  									InstanceType: "m5.xlarge",
   163  								},
   164  							},
   165  						},
   166  					}),
   167  				rhcos.MakeAsset("test-image"),
   168  				(*rhcos.Release)(pointer.StringPtr("412.86.202208101040-0")),
   169  				&machine.Master{
   170  					File: &asset.File{
   171  						Filename: "master-ignition",
   172  						Data:     []byte("test-ignition"),
   173  					},
   174  				},
   175  			)
   176  			master := &Master{}
   177  			if err := master.Generate(context.Background(), parents); err != nil {
   178  				t.Fatalf("failed to generate master machines: %v", err)
   179  			}
   180  			expectedLen := len(tc.expectedMachineConfig)
   181  			if assert.Equal(t, expectedLen, len(master.MachineConfigFiles)) {
   182  				for i := 0; i < expectedLen; i++ {
   183  					assert.Equal(t, tc.expectedMachineConfig[i], string(master.MachineConfigFiles[i].Data), "unexepcted machine config contents")
   184  				}
   185  			} else {
   186  				assert.Equal(t, 0, len(master.MachineConfigFiles), "expected no machine config files")
   187  			}
   188  		})
   189  	}
   190  }
   191  
   192  func TestControlPlaneIsNotModified(t *testing.T) {
   193  	parents := asset.Parents{}
   194  	installConfig := installconfig.MakeAsset(
   195  		&types.InstallConfig{
   196  			ObjectMeta: metav1.ObjectMeta{
   197  				Name: "test-cluster",
   198  			},
   199  			SSHKey:     "ssh-rsa: dummy-key",
   200  			BaseDomain: "test-domain",
   201  			Platform: types.Platform{
   202  				AWS: &awstypes.Platform{
   203  					Region: "us-east-1",
   204  					DefaultMachinePlatform: &awstypes.MachinePool{
   205  						InstanceType: "TEST_INSTANCE_TYPE",
   206  					},
   207  				},
   208  			},
   209  			ControlPlane: &types.MachinePool{
   210  				Hyperthreading: types.HyperthreadingDisabled,
   211  				Replicas:       pointer.Int64Ptr(1),
   212  				Platform: types.MachinePoolPlatform{
   213  					AWS: &awstypes.MachinePool{
   214  						Zones: []string{"us-east-1a"},
   215  					},
   216  				},
   217  			},
   218  		})
   219  
   220  	parents.Add(
   221  		&installconfig.ClusterID{
   222  			UUID:    "test-uuid",
   223  			InfraID: "test-infra-id",
   224  		},
   225  		installConfig,
   226  		rhcos.MakeAsset("test-image"),
   227  		(*rhcos.Release)(pointer.StringPtr("412.86.202208101040-0")),
   228  		&machine.Master{
   229  			File: &asset.File{
   230  				Filename: "master-ignition",
   231  				Data:     []byte("test-ignition"),
   232  			},
   233  		},
   234  	)
   235  	master := &Master{}
   236  	if err := master.Generate(context.Background(), parents); err != nil {
   237  		t.Fatalf("failed to generate master machines: %v", err)
   238  	}
   239  
   240  	if installConfig.Config.ControlPlane.Platform.AWS.Type != "" {
   241  		t.Fatalf("control plance in the install config has been modified")
   242  	}
   243  }
   244  
   245  func TestBaremetalGeneratedAssetFiles(t *testing.T) {
   246  	parents := asset.Parents{}
   247  	installConfig := installconfig.MakeAsset(
   248  		&types.InstallConfig{
   249  			ObjectMeta: metav1.ObjectMeta{
   250  				Name: "test-cluster",
   251  			},
   252  			Platform: types.Platform{
   253  				BareMetal: &baremetal.Platform{
   254  					Hosts: []*baremetal.Host{
   255  						{
   256  							Name: "master-0",
   257  							Role: "master",
   258  							BMC: baremetal.BMC{
   259  								Username: "usr-0",
   260  								Password: "pwd-0",
   261  							},
   262  							NetworkConfig: networkConfig("interfaces:"),
   263  						},
   264  						{
   265  							Name: "worker-0",
   266  							Role: "worker",
   267  							BMC: baremetal.BMC{
   268  								Username: "usr-1",
   269  								Password: "pwd-1",
   270  							},
   271  						},
   272  					},
   273  				},
   274  			},
   275  			ControlPlane: &types.MachinePool{
   276  				Replicas: pointer.Int64Ptr(1),
   277  				Platform: types.MachinePoolPlatform{
   278  					BareMetal: &baremetal.MachinePool{},
   279  				},
   280  			},
   281  			Compute: []types.MachinePool{
   282  				{
   283  					Replicas: pointer.Int64Ptr(1),
   284  					Platform: types.MachinePoolPlatform{},
   285  				},
   286  			},
   287  		})
   288  
   289  	parents.Add(
   290  		&installconfig.ClusterID{
   291  			UUID:    "test-uuid",
   292  			InfraID: "test-infra-id",
   293  		},
   294  		installConfig,
   295  		rhcos.MakeAsset("test-image"),
   296  		(*rhcos.Release)(pointer.StringPtr("412.86.202208101040-0")),
   297  		&machine.Master{
   298  			File: &asset.File{
   299  				Filename: "master-ignition",
   300  				Data:     []byte("test-ignition"),
   301  			},
   302  		},
   303  	)
   304  	master := &Master{}
   305  	assert.NoError(t, master.Generate(context.Background(), parents))
   306  
   307  	assert.Len(t, master.HostFiles, 2)
   308  	verifyHost(t, master.HostFiles[0], "openshift/99_openshift-cluster-api_hosts-0.yaml", "master-0")
   309  	verifyHost(t, master.HostFiles[1], "openshift/99_openshift-cluster-api_hosts-1.yaml", "worker-0")
   310  
   311  	assert.Len(t, master.SecretFiles, 2)
   312  	verifySecret(t, master.SecretFiles[0], "openshift/99_openshift-cluster-api_host-bmc-secrets-0.yaml", "master-0-bmc-secret", "map[password:[112 119 100 45 48] username:[117 115 114 45 48]]")
   313  	verifySecret(t, master.SecretFiles[1], "openshift/99_openshift-cluster-api_host-bmc-secrets-1.yaml", "worker-0-bmc-secret", "map[password:[112 119 100 45 49] username:[117 115 114 45 49]]")
   314  
   315  	assert.Len(t, master.NetworkConfigSecretFiles, 1)
   316  	verifySecret(t, master.NetworkConfigSecretFiles[0], "openshift/99_openshift-cluster-api_host-network-config-secrets-0.yaml", "master-0-network-config-secret", "map[nmstate:[105 110 116 101 114 102 97 99 101 115 58 32 110 117 108 108 10]]")
   317  	verifyManifestOwnership(t, master)
   318  }
   319  
   320  func verifyHost(t *testing.T, a *asset.File, eFilename, eName string) {
   321  	t.Helper()
   322  	assert.Equal(t, a.Filename, eFilename)
   323  	var host v1alpha1.BareMetalHost
   324  	assert.NoError(t, yaml.Unmarshal(a.Data, &host))
   325  	assert.Equal(t, eName, host.Name)
   326  }
   327  
   328  func verifySecret(t *testing.T, a *asset.File, eFilename, eName, eData string) {
   329  	t.Helper()
   330  	assert.Equal(t, a.Filename, eFilename)
   331  	var secret corev1.Secret
   332  	assert.NoError(t, yaml.Unmarshal(a.Data, &secret))
   333  	assert.Equal(t, eName, secret.Name)
   334  	assert.Equal(t, eData, fmt.Sprintf("%v", secret.Data))
   335  }
   336  
   337  func verifyManifestOwnership(t *testing.T, a asset.WritableAsset) {
   338  	t.Helper()
   339  	for _, file := range a.Files() {
   340  		assert.True(t, IsMachineManifest(file), file.Filename)
   341  	}
   342  }
   343  
   344  func networkConfig(config string) *v1.JSON {
   345  	var nc v1.JSON
   346  	yaml.Unmarshal([]byte(config), &nc)
   347  	return &nc
   348  }