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

     1  package baremetal
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	baremetalhost "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
     8  	"github.com/stretchr/testify/assert"
     9  	corev1 "k8s.io/api/core/v1"
    10  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  	"sigs.k8s.io/yaml"
    12  
    13  	machineapi "github.com/openshift/api/machine/v1beta1"
    14  	"github.com/openshift/installer/pkg/types"
    15  	baremetaltypes "github.com/openshift/installer/pkg/types/baremetal"
    16  )
    17  
    18  func TestHosts(t *testing.T) {
    19  
    20  	nmstate := `interfaces:
    21  - name: eth0
    22    type: ethernet
    23  routes:
    24    config:
    25    - destination: 198.51.100.0/24
    26      metric: 150
    27      next-hop-address: 192.0.2.1
    28      next-hop-interface: eth1
    29      table-id: 254
    30  `
    31  
    32  	testCases := []struct {
    33  		Scenario        string
    34  		Machines        []machineapi.Machine
    35  		Config          *types.InstallConfig
    36  		ExpectedSecrets []corev1.Secret
    37  		ExpectedHosts   []baremetalhost.BareMetalHost
    38  		ExpectedError   string
    39  		ExpectedSetting *HostSettings
    40  	}{
    41  		{
    42  			Scenario: "no-platform",
    43  			Config: &types.InstallConfig{
    44  				Platform: types.Platform{
    45  					BareMetal: nil,
    46  				},
    47  			},
    48  
    49  			ExpectedError: "no baremetal platform in configuration",
    50  		},
    51  		{
    52  			Scenario: "no-hosts",
    53  			Config:   config().build(),
    54  
    55  			ExpectedSetting: settings().build(),
    56  		},
    57  		{
    58  			Scenario: "default",
    59  			Machines: machines(machine("machine-0")),
    60  			Config:   configHosts(hostType("master-0").bmc("usr0", "pwd0").role("master")),
    61  
    62  			ExpectedSetting: settings().
    63  				secrets(secret("master-0-bmc-secret").creds("usr0", "pwd0")).
    64  				hosts(host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy()).build(),
    65  		},
    66  		{
    67  			Scenario: "default-norole",
    68  			Machines: machines(machine("machine-0")),
    69  			Config:   configHosts(hostType("master-0").bmc("usr0", "pwd0")),
    70  
    71  			ExpectedSetting: settings().
    72  				secrets(secret("master-0-bmc-secret").creds("usr0", "pwd0")).
    73  				hosts(host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy()).build(),
    74  		},
    75  		{
    76  			Scenario: "network-config",
    77  			Machines: machines(machine("machine-0")),
    78  			Config: configHosts(
    79  				hostType("master-0").
    80  					bmc("usr0", "pwd0").
    81  					networkConfig(nmstate)),
    82  
    83  			ExpectedSetting: settings().
    84  				secrets(secret("master-0-bmc-secret").creds("usr0", "pwd0")).
    85  				networkConfigSecrets(secret("master-0-network-config-secret").nmstate(nmstate)).
    86  				hosts(
    87  					host("master-0").
    88  						label("installer.openshift.io/role", "control-plane").
    89  						consumerRef("machine-0").
    90  						userDataRef("user-data-secret").
    91  						preprovisioningNetworkDataName("master-0-network-config-secret").
    92  						customDeploy()).build(),
    93  		},
    94  		{
    95  			Scenario: "3-hosts-3-machines-norole-all",
    96  			Machines: machines(
    97  				machine("machine-0"),
    98  				machine("machine-1"),
    99  				machine("machine-2")),
   100  			Config: configHosts(
   101  				hostType("master-0").bmc("usr0", "pwd0"),
   102  				hostType("master-1").bmc("usr1", "pwd1"),
   103  				hostType("master-2").bmc("usr2", "pwd2")),
   104  
   105  			ExpectedSetting: settings().
   106  				secrets(
   107  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   108  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   109  					secret("master-2-bmc-secret").creds("usr2", "pwd2")).
   110  				hosts(
   111  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   112  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   113  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy()).build(),
   114  		},
   115  		{
   116  			Scenario: "4-hosts-3-machines",
   117  			Machines: machines(
   118  				machine("machine-0"),
   119  				machine("machine-1"),
   120  				machine("machine-2")),
   121  			Config: configHosts(
   122  				hostType("master-0").bmc("usr0", "pwd0").role("master"),
   123  				hostType("master-1").bmc("usr1", "pwd1").role("master"),
   124  				hostType("master-2").bmc("usr2", "pwd2").role("master"),
   125  				hostType("worker-0").bmc("usr3", "pwd3").role("worker")),
   126  
   127  			ExpectedSetting: settings().
   128  				secrets(
   129  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   130  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   131  					secret("master-2-bmc-secret").creds("usr2", "pwd2"),
   132  					secret("worker-0-bmc-secret").creds("usr3", "pwd3")).
   133  				hosts(
   134  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   135  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   136  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy(),
   137  					host("worker-0").annotation("baremetalhost.metal3.io/paused", ""),
   138  				).build(),
   139  		},
   140  		{
   141  			Scenario: "4-hosts-3-machines-norole",
   142  			Machines: machines(
   143  				machine("machine-0"),
   144  				machine("machine-1"),
   145  				machine("machine-2")),
   146  			Config: configHosts(
   147  				hostType("master-0").bmc("usr0", "pwd0"),
   148  				hostType("master-1").bmc("usr1", "pwd1"),
   149  				hostType("master-2").bmc("usr2", "pwd2"),
   150  				hostType("worker-0").bmc("wrk0", "pwd0")),
   151  
   152  			ExpectedSetting: settings().
   153  				secrets(
   154  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   155  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   156  					secret("master-2-bmc-secret").creds("usr2", "pwd2"),
   157  					secret("worker-0-bmc-secret").creds("wrk0", "pwd0")).
   158  				hosts(
   159  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   160  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   161  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy(),
   162  					host("worker-0").annotation("baremetalhost.metal3.io/paused", ""),
   163  				).build(),
   164  		},
   165  		{
   166  			Scenario: "5-hosts-3-machines",
   167  			Machines: machines(
   168  				machine("machine-0"),
   169  				machine("machine-1"),
   170  				machine("machine-2")),
   171  			Config: configHosts(
   172  				hostType("master-0").bmc("usr0", "pwd0").role("master"),
   173  				hostType("master-1").bmc("usr1", "pwd1").role("master"),
   174  				hostType("master-2").bmc("usr2", "pwd2").role("master"),
   175  				hostType("worker-0").bmc("wrk0", "pwd0").role("worker"),
   176  				hostType("worker-1").bmc("wrk1", "pwd1").role("worker")),
   177  
   178  			ExpectedSetting: settings().
   179  				secrets(
   180  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   181  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   182  					secret("master-2-bmc-secret").creds("usr2", "pwd2"),
   183  					secret("worker-0-bmc-secret").creds("wrk0", "pwd0"),
   184  					secret("worker-1-bmc-secret").creds("wrk1", "pwd1")).
   185  				hosts(
   186  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   187  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   188  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy(),
   189  					host("worker-0").annotation("baremetalhost.metal3.io/paused", ""),
   190  					host("worker-1").annotation("baremetalhost.metal3.io/paused", ""),
   191  				).build(),
   192  		},
   193  		{
   194  			Scenario: "5-hosts-3-machines-mixed",
   195  			Machines: machines(
   196  				machine("machine-0"),
   197  				machine("machine-1"),
   198  				machine("machine-2")),
   199  			Config: configHosts(
   200  				hostType("master-1").bmc("usr1", "pwd1").role("master"),
   201  				hostType("worker-0").bmc("wrk0", "pwd0").role("worker"),
   202  				hostType("worker-1").bmc("wrk1", "pwd1").role("worker"),
   203  				hostType("master-0").bmc("usr0", "pwd0"),
   204  				hostType("master-2").bmc("usr2", "pwd2")),
   205  
   206  			ExpectedSetting: settings().
   207  				secrets(
   208  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   209  					secret("worker-0-bmc-secret").creds("wrk0", "pwd0"),
   210  					secret("worker-1-bmc-secret").creds("wrk1", "pwd1"),
   211  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   212  					secret("master-2-bmc-secret").creds("usr2", "pwd2")).
   213  				hosts(
   214  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   215  					host("worker-0").annotation("baremetalhost.metal3.io/paused", ""),
   216  					host("worker-1").annotation("baremetalhost.metal3.io/paused", ""),
   217  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   218  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy()).build(),
   219  		},
   220  		{
   221  			Scenario: "4-hosts-3-machines-norole-master",
   222  			Machines: machines(
   223  				machine("machine-0"),
   224  				machine("machine-1"),
   225  				machine("machine-2")),
   226  			Config: configHosts(
   227  				hostType("worker-0").bmc("wrk0", "pwd0").role("worker"),
   228  				hostType("master-0").bmc("usr0", "pwd0"),
   229  				hostType("master-1").bmc("usr1", "pwd1"),
   230  				hostType("master-2").bmc("usr2", "pwd2")),
   231  
   232  			ExpectedSetting: settings().
   233  				secrets(
   234  					secret("worker-0-bmc-secret").creds("wrk0", "pwd0"),
   235  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   236  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   237  					secret("master-2-bmc-secret").creds("usr2", "pwd2")).
   238  				hosts(
   239  					host("worker-0").annotation("baremetalhost.metal3.io/paused", ""),
   240  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   241  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   242  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy()).build(),
   243  		},
   244  		{
   245  			Scenario: "4-hosts-3-machines-norole-worker",
   246  			Machines: machines(
   247  				machine("machine-0"),
   248  				machine("machine-1"),
   249  				machine("machine-2")),
   250  			Config: configHosts(
   251  				hostType("master-0").bmc("usr0", "pwd0").role("master"),
   252  				hostType("master-1").bmc("usr1", "pwd1").role("master"),
   253  				hostType("master-2").bmc("usr2", "pwd2").role("master"),
   254  				hostType("worker-0").bmc("wrk0", "pwd0")),
   255  
   256  			ExpectedSetting: settings().
   257  				secrets(
   258  					secret("master-0-bmc-secret").creds("usr0", "pwd0"),
   259  					secret("master-1-bmc-secret").creds("usr1", "pwd1"),
   260  					secret("master-2-bmc-secret").creds("usr2", "pwd2"),
   261  					secret("worker-0-bmc-secret").creds("wrk0", "pwd0")).
   262  				hosts(
   263  					host("master-0").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-0").customDeploy(),
   264  					host("master-1").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-1").customDeploy(),
   265  					host("master-2").label("installer.openshift.io/role", "control-plane").userDataRef("user-data-secret").consumerRef("machine-2").customDeploy(),
   266  					host("worker-0").annotation("baremetalhost.metal3.io/paused", "")).build(),
   267  		},
   268  	}
   269  
   270  	for _, tc := range testCases {
   271  		t.Run(tc.Scenario, func(t *testing.T) {
   272  			settings, err := Hosts(tc.Config, tc.Machines, "user-data-secret")
   273  
   274  			if tc.ExpectedError != "" {
   275  				assert.EqualError(t, err, tc.ExpectedError)
   276  			}
   277  
   278  			if tc.ExpectedSetting != nil {
   279  				for i, h := range tc.ExpectedSetting.Hosts {
   280  					assert.Equal(t, h, settings.Hosts[i], fmt.Sprintf("%s and %s are not equal", h.Name, settings.Hosts[i].Name))
   281  				}
   282  
   283  				for i, s := range tc.ExpectedSetting.Secrets {
   284  					assert.Equal(t, s, settings.Secrets[i], s.Name, fmt.Sprintf("%s and %s are not equal", s.Name, settings.Secrets[i].Name))
   285  				}
   286  
   287  				for i, s := range tc.ExpectedSetting.NetworkConfigSecrets {
   288  					assert.Equal(t, s, settings.NetworkConfigSecrets[i], s.Name, fmt.Sprintf("%s and %s are not equal", s.Name, settings.NetworkConfigSecrets[i].Name))
   289  				}
   290  			}
   291  		})
   292  	}
   293  }
   294  
   295  func configHosts(builders ...*hostTypeBuilder) *types.InstallConfig {
   296  	return config().hosts(builders...).build()
   297  }
   298  
   299  type installConfigBuilder struct {
   300  	types.InstallConfig
   301  }
   302  
   303  func (ib *installConfigBuilder) build() *types.InstallConfig {
   304  	return &ib.InstallConfig
   305  }
   306  
   307  func config() *installConfigBuilder {
   308  	return &installConfigBuilder{
   309  		types.InstallConfig{
   310  			Platform: types.Platform{
   311  				BareMetal: &baremetaltypes.Platform{},
   312  			},
   313  		},
   314  	}
   315  }
   316  
   317  func (ib *installConfigBuilder) hosts(builders ...*hostTypeBuilder) *installConfigBuilder {
   318  	ib.Platform.BareMetal.Hosts = []*baremetaltypes.Host{}
   319  
   320  	for _, hb := range builders {
   321  		ib.Platform.BareMetal.Hosts = append(ib.Platform.BareMetal.Hosts, hb.build())
   322  	}
   323  	return ib
   324  }
   325  
   326  type hostTypeBuilder struct {
   327  	baremetaltypes.Host
   328  }
   329  
   330  func (htb *hostTypeBuilder) build() *baremetaltypes.Host {
   331  	return &htb.Host
   332  }
   333  
   334  func hostType(name string) *hostTypeBuilder {
   335  	return &hostTypeBuilder{
   336  		Host: baremetaltypes.Host{
   337  			Name:           name,
   338  			BootMACAddress: "c0:ff:ee:ca:fe:00",
   339  			BootMode:       baremetaltypes.UEFI,
   340  			RootDeviceHints: &baremetaltypes.RootDeviceHints{
   341  				DeviceName: "userd_devicename",
   342  			},
   343  		},
   344  	}
   345  }
   346  
   347  func (htb *hostTypeBuilder) role(role string) *hostTypeBuilder {
   348  	htb.Role = role
   349  	return htb
   350  }
   351  
   352  func (htb *hostTypeBuilder) bmc(user, password string) *hostTypeBuilder {
   353  	htb.BMC = baremetaltypes.BMC{
   354  		Username: user,
   355  		Password: password,
   356  	}
   357  	return htb
   358  }
   359  
   360  func (htb *hostTypeBuilder) networkConfig(config string) *hostTypeBuilder {
   361  	yaml.Unmarshal([]byte(config), &htb.NetworkConfig)
   362  	return htb
   363  }
   364  
   365  type machineBuilder struct {
   366  	machineapi.Machine
   367  }
   368  
   369  func (mb *machineBuilder) build() *machineapi.Machine {
   370  	return &mb.Machine
   371  }
   372  
   373  func machine(name string) *machineBuilder {
   374  	return &machineBuilder{
   375  		machineapi.Machine{
   376  			TypeMeta: metav1.TypeMeta{
   377  				APIVersion: "v1",
   378  				Kind:       "Machine",
   379  			},
   380  			ObjectMeta: metav1.ObjectMeta{
   381  				Name:      name,
   382  				Namespace: "namespace",
   383  			},
   384  		},
   385  	}
   386  }
   387  
   388  func machines(builders ...*machineBuilder) []machineapi.Machine {
   389  	m := []machineapi.Machine{}
   390  
   391  	for _, mb := range builders {
   392  		m = append(m, *mb.build())
   393  	}
   394  	return m
   395  }
   396  
   397  type hostBuilder struct {
   398  	baremetalhost.BareMetalHost
   399  }
   400  
   401  func host(name string) *hostBuilder {
   402  	return &hostBuilder{
   403  		baremetalhost.BareMetalHost{
   404  
   405  			TypeMeta: metav1.TypeMeta{
   406  				APIVersion: "metal3.io/v1alpha1",
   407  				Kind:       "BareMetalHost",
   408  			},
   409  			ObjectMeta: metav1.ObjectMeta{
   410  				Name:      name,
   411  				Namespace: "openshift-machine-api",
   412  			},
   413  			Spec: baremetalhost.BareMetalHostSpec{
   414  				BMC: baremetalhost.BMCDetails{
   415  					CredentialsName: name + "-bmc-secret",
   416  				},
   417  				RootDeviceHints: &baremetalhost.RootDeviceHints{
   418  					DeviceName: "userd_devicename",
   419  				},
   420  				BootMode:       "UEFI",
   421  				BootMACAddress: "c0:ff:ee:ca:fe:00",
   422  				Online:         true,
   423  			},
   424  		},
   425  	}
   426  }
   427  
   428  func (hb *hostBuilder) build() *baremetalhost.BareMetalHost {
   429  	return &hb.BareMetalHost
   430  }
   431  
   432  func (hb *hostBuilder) externallyProvisioned() *hostBuilder {
   433  	hb.Spec.ExternallyProvisioned = true
   434  	return hb
   435  }
   436  
   437  func (hb *hostBuilder) customDeploy() *hostBuilder {
   438  	hb.Spec.CustomDeploy = &baremetalhost.CustomDeploy{
   439  		Method: "install_coreos",
   440  	}
   441  	return hb
   442  }
   443  
   444  func (hb *hostBuilder) annotation(key, value string) *hostBuilder {
   445  	if hb.Annotations == nil {
   446  		hb.Annotations = map[string]string{}
   447  	}
   448  
   449  	hb.Annotations[key] = value
   450  	return hb
   451  }
   452  
   453  func (hb *hostBuilder) label(key, value string) *hostBuilder {
   454  	if hb.Labels == nil {
   455  		hb.Labels = map[string]string{}
   456  	}
   457  
   458  	hb.Labels[key] = value
   459  	return hb
   460  }
   461  
   462  func (hb *hostBuilder) consumerRef(name string) *hostBuilder {
   463  	hb.Spec.ConsumerRef = &corev1.ObjectReference{
   464  		APIVersion: "v1",
   465  		Kind:       "Machine",
   466  		Namespace:  "namespace",
   467  		Name:       name,
   468  	}
   469  	return hb
   470  }
   471  
   472  func (hb *hostBuilder) userDataRef(name string) *hostBuilder {
   473  	hb.Spec.UserData = &corev1.SecretReference{Name: name}
   474  	return hb
   475  }
   476  
   477  func (hb *hostBuilder) preprovisioningNetworkDataName(secretName string) *hostBuilder {
   478  	hb.Spec.PreprovisioningNetworkDataName = secretName
   479  	return hb
   480  }
   481  
   482  type secretBuilder struct {
   483  	corev1.Secret
   484  }
   485  
   486  func secret(name string) *secretBuilder {
   487  	return &secretBuilder{
   488  		corev1.Secret{
   489  			TypeMeta: metav1.TypeMeta{
   490  				APIVersion: "v1",
   491  				Kind:       "Secret",
   492  			},
   493  			ObjectMeta: metav1.ObjectMeta{
   494  				Name:      name,
   495  				Namespace: "openshift-machine-api",
   496  			},
   497  		},
   498  	}
   499  }
   500  
   501  func (sb *secretBuilder) creds(user, password string) *secretBuilder {
   502  	sb.Data = map[string][]byte{
   503  		"username": []byte(user),
   504  		"password": []byte(password),
   505  	}
   506  	return sb
   507  }
   508  
   509  func (sb *secretBuilder) nmstate(config string) *secretBuilder {
   510  	sb.Data = map[string][]byte{
   511  		"nmstate": []byte(config),
   512  	}
   513  	return sb
   514  }
   515  
   516  func (sb *secretBuilder) build() *corev1.Secret {
   517  	return &sb.Secret
   518  }
   519  
   520  type hostSettingsBuilder struct {
   521  	HostSettings
   522  }
   523  
   524  func (hsb *hostSettingsBuilder) secrets(builders ...*secretBuilder) *hostSettingsBuilder {
   525  	hsb.Secrets = []corev1.Secret{}
   526  	for _, sb := range builders {
   527  		hsb.Secrets = append(hsb.Secrets, *sb.build())
   528  	}
   529  	return hsb
   530  }
   531  
   532  func (hsb *hostSettingsBuilder) networkConfigSecrets(builders ...*secretBuilder) *hostSettingsBuilder {
   533  	hsb.Secrets = []corev1.Secret{}
   534  	for _, sb := range builders {
   535  		hsb.NetworkConfigSecrets = append(hsb.NetworkConfigSecrets, *sb.build())
   536  	}
   537  	return hsb
   538  }
   539  
   540  func (hsb *hostSettingsBuilder) hosts(builders ...*hostBuilder) *hostSettingsBuilder {
   541  	hsb.Hosts = []baremetalhost.BareMetalHost{}
   542  	for _, hb := range builders {
   543  		hsb.Hosts = append(hsb.Hosts, *hb.build())
   544  	}
   545  	return hsb
   546  }
   547  
   548  func (hsb *hostSettingsBuilder) build() *HostSettings {
   549  	return &hsb.HostSettings
   550  }
   551  
   552  func settings() *hostSettingsBuilder {
   553  	return &hostSettingsBuilder{
   554  		HostSettings: HostSettings{},
   555  	}
   556  }