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

     1  package baremetal
     2  
     3  import (
     4  	"fmt"
     5  
     6  	baremetalhost "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
     7  	hardware "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1/profile"
     8  	"github.com/pkg/errors"
     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  	"github.com/openshift/installer/pkg/types/baremetal"
    16  )
    17  
    18  // HostSettings hold the information needed to build the manifests to
    19  // register hosts with the cluster.
    20  type HostSettings struct {
    21  	// Hosts are the BareMetalHost objects for the hardware making up
    22  	// the cluster.
    23  	Hosts []baremetalhost.BareMetalHost
    24  	// Secrets holds the credential information for communicating with
    25  	// the management controllers on the hosts.
    26  	Secrets []corev1.Secret
    27  	// NetworkConfigSecrets holds the networking configuration defined
    28  	// on the host.
    29  	NetworkConfigSecrets []corev1.Secret
    30  }
    31  
    32  func createNetworkConfigSecret(host *baremetal.Host) (*corev1.Secret, error) {
    33  
    34  	yamlNetworkConfig, err := yaml.Marshal(host.NetworkConfig)
    35  	if err != nil {
    36  		return nil, errors.Wrap(err, "Error while creating network config secret")
    37  	}
    38  
    39  	return &corev1.Secret{
    40  		TypeMeta: metav1.TypeMeta{
    41  			APIVersion: "v1",
    42  			Kind:       "Secret",
    43  		},
    44  		ObjectMeta: metav1.ObjectMeta{
    45  			Name:      fmt.Sprintf("%s-network-config-secret", host.Name),
    46  			Namespace: "openshift-machine-api",
    47  		},
    48  		Data: map[string][]byte{"nmstate": yamlNetworkConfig},
    49  	}, nil
    50  }
    51  
    52  func createSecret(host *baremetal.Host) (*corev1.Secret, baremetalhost.BMCDetails) {
    53  	bmc := baremetalhost.BMCDetails{}
    54  	if host.BMC.Username != "" && host.BMC.Password != "" {
    55  		// Each host needs a secret to hold the credentials for
    56  		// communicating with the management controller that drives
    57  		// that host.
    58  		secret := &corev1.Secret{
    59  			TypeMeta: metav1.TypeMeta{
    60  				APIVersion: "v1",
    61  				Kind:       "Secret",
    62  			},
    63  			ObjectMeta: metav1.ObjectMeta{
    64  				Name:      fmt.Sprintf("%s-bmc-secret", host.Name),
    65  				Namespace: "openshift-machine-api",
    66  			},
    67  			Data: map[string][]byte{
    68  				"username": []byte(host.BMC.Username),
    69  				"password": []byte(host.BMC.Password),
    70  			},
    71  		}
    72  		bmc.Address = host.BMC.Address
    73  		bmc.CredentialsName = secret.Name
    74  		bmc.DisableCertificateVerification = host.BMC.DisableCertificateVerification
    75  
    76  		return secret, bmc
    77  	}
    78  	return nil, bmc
    79  }
    80  
    81  func createBaremetalHost(host *baremetal.Host, bmc baremetalhost.BMCDetails) baremetalhost.BareMetalHost {
    82  
    83  	// Map string 'default' to hardware.DefaultProfileName
    84  	if host.HardwareProfile == "default" {
    85  		host.HardwareProfile = hardware.DefaultProfileName
    86  	}
    87  
    88  	newHost := baremetalhost.BareMetalHost{
    89  		TypeMeta: metav1.TypeMeta{
    90  			APIVersion: baremetalhost.GroupVersion.String(),
    91  			Kind:       "BareMetalHost",
    92  		},
    93  		ObjectMeta: metav1.ObjectMeta{
    94  			Name:      host.Name,
    95  			Namespace: "openshift-machine-api",
    96  		},
    97  		Spec: baremetalhost.BareMetalHostSpec{
    98  			Online:          true,
    99  			BMC:             bmc,
   100  			BootMACAddress:  host.BootMACAddress,
   101  			HardwareProfile: host.HardwareProfile,
   102  			BootMode:        baremetalhost.BootMode(host.BootMode),
   103  			RootDeviceHints: host.RootDeviceHints.MakeCRDHints(),
   104  		},
   105  	}
   106  
   107  	return newHost
   108  }
   109  
   110  // Hosts returns the HostSettings with details of the hardware being
   111  // used to construct the cluster.
   112  func Hosts(config *types.InstallConfig, machines []machineapi.Machine, userDataSecret string) (*HostSettings, error) {
   113  	settings := &HostSettings{}
   114  
   115  	if config.Platform.BareMetal == nil {
   116  		return nil, fmt.Errorf("no baremetal platform in configuration")
   117  	}
   118  
   119  	numRequiredMasters := len(machines)
   120  	numMasters := 0
   121  	for _, host := range config.Platform.BareMetal.Hosts {
   122  
   123  		secret, bmc := createSecret(host)
   124  		if secret != nil {
   125  			settings.Secrets = append(settings.Secrets, *secret)
   126  		}
   127  		newHost := createBaremetalHost(host, bmc)
   128  
   129  		if host.NetworkConfig != nil {
   130  			networkConfigSecret, err := createNetworkConfigSecret(host)
   131  			if err != nil {
   132  				return nil, err
   133  			}
   134  			settings.NetworkConfigSecrets = append(settings.NetworkConfigSecrets, *networkConfigSecret)
   135  			newHost.Spec.PreprovisioningNetworkDataName = networkConfigSecret.Name
   136  		}
   137  
   138  		if !host.IsWorker() && numMasters < numRequiredMasters {
   139  			// Setting CustomDeploy early ensures that the
   140  			// corresponding Ironic node gets correctly configured
   141  			// from the beginning.
   142  			newHost.Spec.CustomDeploy = &baremetalhost.CustomDeploy{
   143  				Method: "install_coreos",
   144  			}
   145  
   146  			newHost.ObjectMeta.Labels = map[string]string{
   147  				"installer.openshift.io/role": "control-plane",
   148  			}
   149  
   150  			// Link the new host to the currently available machine
   151  			machine := machines[numMasters]
   152  			newHost.Spec.ConsumerRef = &corev1.ObjectReference{
   153  				APIVersion: machine.TypeMeta.APIVersion,
   154  				Kind:       machine.TypeMeta.Kind,
   155  				Namespace:  machine.ObjectMeta.Namespace,
   156  				Name:       machine.ObjectMeta.Name,
   157  			}
   158  			newHost.Spec.Online = true
   159  
   160  			// userDataSecret carries a reference to the master ignition file
   161  			newHost.Spec.UserData = &corev1.SecretReference{Name: userDataSecret}
   162  			numMasters++
   163  		} else {
   164  			// Pause workers until the real control plane is up.
   165  			newHost.ObjectMeta.Annotations = map[string]string{
   166  				"baremetalhost.metal3.io/paused": "",
   167  			}
   168  		}
   169  
   170  		settings.Hosts = append(settings.Hosts, newHost)
   171  	}
   172  
   173  	return settings, nil
   174  }