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

     1  // Package vsphere generates Machine objects for vsphere.package vsphere
     2  package vsphere
     3  
     4  import (
     5  	"fmt"
     6  
     7  	"github.com/pkg/errors"
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  
    11  	machineapi "github.com/openshift/api/machine/v1beta1"
    12  	"github.com/openshift/installer/pkg/types"
    13  	"github.com/openshift/installer/pkg/types/vsphere"
    14  )
    15  
    16  func getMachineSetWithPlatform(
    17  	clusterID string,
    18  	name string,
    19  	mpool *vsphere.MachinePool,
    20  	osImage string,
    21  	failureDomain vsphere.FailureDomain,
    22  	vcenter *vsphere.VCenter,
    23  	replicas int32,
    24  	role,
    25  	userDataSecret string,
    26  	hosts []*vsphere.Host) (*machineapi.MachineSet, error) {
    27  	provider, err := provider(clusterID, vcenter, failureDomain, mpool, osImage, userDataSecret)
    28  	if err != nil {
    29  		return nil, errors.Wrap(err, "failed to create provider")
    30  	}
    31  
    32  	// If static IP, create the addressesFromPools
    33  	if len(hosts) > 0 {
    34  		// Get an example host def for network specific nameserver
    35  		var nameservers []string
    36  		for _, host := range hosts {
    37  			if (host.IsCompute() && role == "worker") || (host.IsControlPlane() && role == "master") {
    38  				nameservers = host.NetworkDevice.Nameservers
    39  				break
    40  			}
    41  		}
    42  
    43  		// Generate AddressesFromPools for each device
    44  		for idx := range provider.Network.Devices {
    45  			provider.Network.Devices[idx].Nameservers = nameservers
    46  			provider.Network.Devices[idx].AddressesFromPools = []machineapi.AddressesFromPool{
    47  				{
    48  					Group:    "installer.openshift.io",
    49  					Name:     fmt.Sprintf("default-%d", idx),
    50  					Resource: "IPPool",
    51  				},
    52  			}
    53  		}
    54  	}
    55  
    56  	mset := &machineapi.MachineSet{
    57  		TypeMeta: metav1.TypeMeta{
    58  			APIVersion: "machine.openshift.io/v1beta1",
    59  			Kind:       "MachineSet",
    60  		},
    61  		ObjectMeta: metav1.ObjectMeta{
    62  			Namespace: "openshift-machine-api",
    63  			Name:      name,
    64  			Labels: map[string]string{
    65  				"machine.openshift.io/cluster-api-cluster": clusterID,
    66  			},
    67  		},
    68  		Spec: machineapi.MachineSetSpec{
    69  			Replicas: &replicas,
    70  			Selector: metav1.LabelSelector{
    71  				MatchLabels: map[string]string{
    72  					"machine.openshift.io/cluster-api-machineset": name,
    73  					"machine.openshift.io/cluster-api-cluster":    clusterID,
    74  				},
    75  			},
    76  			Template: machineapi.MachineTemplateSpec{
    77  				ObjectMeta: machineapi.ObjectMeta{
    78  					Labels: map[string]string{
    79  						"machine.openshift.io/cluster-api-machineset":   name,
    80  						"machine.openshift.io/cluster-api-cluster":      clusterID,
    81  						"machine.openshift.io/cluster-api-machine-role": role,
    82  						"machine.openshift.io/cluster-api-machine-type": role,
    83  					},
    84  				},
    85  				Spec: machineapi.MachineSpec{
    86  					ProviderSpec: machineapi.ProviderSpec{
    87  						Value: &runtime.RawExtension{Object: provider},
    88  					},
    89  					// we don't need to set Versions, because we control those via cluster operators.
    90  				},
    91  			},
    92  		},
    93  	}
    94  	return mset, nil
    95  }
    96  
    97  func getVCenterFromServerName(server string, platformSpec *vsphere.Platform) (*vsphere.VCenter, error) {
    98  	for _, vCenter := range platformSpec.VCenters {
    99  		if vCenter.Server == server {
   100  			return &vCenter, nil
   101  		}
   102  	}
   103  	return nil, errors.Errorf("unable to find vCenter %s", server)
   104  }
   105  
   106  func getDefinedZonesFromTopology(p *vsphere.Platform) (map[string]vsphere.FailureDomain, error) {
   107  	zones := make(map[string]vsphere.FailureDomain)
   108  	for _, failureDomain := range p.FailureDomains {
   109  		zones[failureDomain.Name] = failureDomain
   110  	}
   111  	return zones, nil
   112  }
   113  
   114  // MachineSets returns a list of machinesets for a machinepool.
   115  func MachineSets(clusterID string, config *types.InstallConfig, pool *types.MachinePool, osImage, role, userDataSecret string) ([]*machineapi.MachineSet, error) {
   116  	if configPlatform := config.Platform.Name(); configPlatform != vsphere.Name {
   117  		return nil, fmt.Errorf("non vsphere configuration: %q", configPlatform)
   118  	}
   119  	if poolPlatform := pool.Platform.Name(); poolPlatform != vsphere.Name {
   120  		return nil, fmt.Errorf("non-vsphere machine-pool: %q", poolPlatform)
   121  	}
   122  	platform := config.Platform.VSphere
   123  	mpool := pool.Platform.VSphere
   124  	// The machinepool has no zones defined, there are FailureDomains
   125  	// This is a vSphere zonal installation. Generate machinepool zone
   126  	// list.
   127  	if len(mpool.Zones) == 0 {
   128  		for _, fd := range config.VSphere.FailureDomains {
   129  			mpool.Zones = append(mpool.Zones, fd.Name)
   130  		}
   131  	}
   132  	azs := mpool.Zones
   133  	total := 0
   134  	if pool.Replicas != nil {
   135  		total = int(*pool.Replicas)
   136  	}
   137  	numOfAZs := len(azs)
   138  	machinesets := make([]*machineapi.MachineSet, 0, numOfAZs)
   139  
   140  	zones, err := getDefinedZonesFromTopology(platform)
   141  
   142  	if err != nil {
   143  		return machinesets, err
   144  	}
   145  	for idx := range azs {
   146  		replicas := int32(total / numOfAZs)
   147  		if idx < total%numOfAZs {
   148  			replicas++
   149  		}
   150  		desiredZone := azs[idx]
   151  		if _, exists := zones[desiredZone]; !exists {
   152  			return nil, errors.Errorf("zone [%s] specified by machinepool is not defined", desiredZone)
   153  		}
   154  		name := fmt.Sprintf("%s-%s-%d", clusterID, pool.Name, idx)
   155  
   156  		failureDomain := zones[desiredZone]
   157  
   158  		vcenter, err := getVCenterFromServerName(failureDomain.Server, platform)
   159  		if err != nil {
   160  			return nil, err
   161  		}
   162  
   163  		osImageForZone := failureDomain.Topology.Template
   164  		if failureDomain.Topology.Template == "" {
   165  			osImageForZone = fmt.Sprintf("%s-%s-%s", osImage, failureDomain.Region, failureDomain.Zone)
   166  		}
   167  		machineset, err := getMachineSetWithPlatform(
   168  			clusterID,
   169  			name,
   170  			mpool,
   171  			osImageForZone,
   172  			failureDomain,
   173  			vcenter,
   174  			replicas,
   175  			role,
   176  			userDataSecret,
   177  			platform.Hosts)
   178  		if err != nil {
   179  			return machinesets, err
   180  		}
   181  		machinesets = append(machinesets, machineset)
   182  	}
   183  
   184  	return machinesets, nil
   185  }