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 }