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

     1  package ibmcloud
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/pkg/errors"
     7  	corev1 "k8s.io/api/core/v1"
     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/ibmcloud"
    14  	ibmcloudprovider "github.com/openshift/machine-api-provider-ibmcloud/pkg/apis/ibmcloudprovider/v1"
    15  )
    16  
    17  // Machines returns a list of machines for a machinepool.
    18  func Machines(clusterID string, config *types.InstallConfig, subnets map[string]string, pool *types.MachinePool, role, userDataSecret string) ([]machineapi.Machine, error) {
    19  	if configPlatform := config.Platform.Name(); configPlatform != ibmcloud.Name {
    20  		return nil, fmt.Errorf("non-IBMCloud configuration: %q", configPlatform)
    21  	}
    22  	if poolPlatform := pool.Platform.Name(); poolPlatform != ibmcloud.Name {
    23  		return nil, fmt.Errorf("non-IBMCloud machine-pool: %q", poolPlatform)
    24  	}
    25  	platform := config.Platform.IBMCloud
    26  	mpool := pool.Platform.IBMCloud
    27  	azs := mpool.Zones
    28  
    29  	total := int64(1)
    30  	if pool.Replicas != nil {
    31  		total = *pool.Replicas
    32  	}
    33  
    34  	var machines []machineapi.Machine
    35  	for idx := int64(0); idx < total; idx++ {
    36  		azIndex := int(idx) % len(azs)
    37  		provider, err := provider(clusterID, platform, subnets, mpool, azIndex, role, userDataSecret)
    38  		if err != nil {
    39  			return nil, errors.Wrap(err, "failed to create provider")
    40  		}
    41  		machine := machineapi.Machine{
    42  			TypeMeta: metav1.TypeMeta{
    43  				APIVersion: "machine.openshift.io/v1beta1",
    44  				Kind:       "Machine",
    45  			},
    46  			ObjectMeta: metav1.ObjectMeta{
    47  				Namespace: "openshift-machine-api",
    48  				Name:      fmt.Sprintf("%s-%s-%d", clusterID, pool.Name, idx),
    49  				Labels: map[string]string{
    50  					"machine.openshift.io/cluster-api-cluster":      clusterID,
    51  					"machine.openshift.io/cluster-api-machine-role": role,
    52  					"machine.openshift.io/cluster-api-machine-type": role,
    53  				},
    54  			},
    55  			Spec: machineapi.MachineSpec{
    56  				ProviderSpec: machineapi.ProviderSpec{
    57  					Value: &runtime.RawExtension{Object: provider},
    58  				},
    59  			},
    60  		}
    61  
    62  		machines = append(machines, machine)
    63  	}
    64  
    65  	return machines, nil
    66  }
    67  
    68  func provider(clusterID string,
    69  	platform *ibmcloud.Platform,
    70  	subnets map[string]string,
    71  	mpool *ibmcloud.MachinePool,
    72  	azIdx int,
    73  	role string,
    74  	userDataSecret string,
    75  ) (*ibmcloudprovider.IBMCloudMachineProviderSpec, error) {
    76  	az := mpool.Zones[azIdx]
    77  
    78  	var vpc string
    79  	if platform.VPCName != "" {
    80  		vpc = platform.VPCName
    81  	} else {
    82  		vpc = fmt.Sprintf("%s-vpc", clusterID)
    83  	}
    84  
    85  	var resourceGroup string
    86  	if platform.ResourceGroupName != "" {
    87  		resourceGroup = platform.ResourceGroupName
    88  	} else {
    89  		resourceGroup = clusterID
    90  	}
    91  
    92  	// Set the ProviderSpec.BootVolume, with encryption key if provided
    93  	bootVolume := ibmcloudprovider.IBMCloudMachineBootVolume{}
    94  	if mpool.BootVolume != nil && mpool.BootVolume.EncryptionKey != "" {
    95  		bootVolume.EncryptionKey = mpool.BootVolume.EncryptionKey
    96  	}
    97  
    98  	// Set the ProviderSpec.NetworkResourceGroup if NetworkResourceGroupName was provided
    99  	var networkResourceGroup string
   100  	if platform.NetworkResourceGroupName != "" {
   101  		networkResourceGroup = platform.NetworkResourceGroupName
   102  	}
   103  
   104  	subnet, err := getSubnet(subnets, clusterID, role, az)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	securityGroups, err := getSecurityGroupNames(clusterID, role)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  
   114  	var dedicatedHost string
   115  	if len(mpool.DedicatedHosts) == len(mpool.Zones) {
   116  		if mpool.DedicatedHosts[azIdx].Name != "" {
   117  			dedicatedHost = mpool.DedicatedHosts[azIdx].Name
   118  		} else {
   119  			dedicatedHost, err = getDedicatedHostNameForZone(clusterID, role, az)
   120  			if err != nil {
   121  				return nil, err
   122  			}
   123  		}
   124  	}
   125  
   126  	return &ibmcloudprovider.IBMCloudMachineProviderSpec{
   127  		TypeMeta: metav1.TypeMeta{
   128  			APIVersion: "ibmcloudproviderconfig.openshift.io/v1beta1",
   129  			Kind:       "IBMCloudMachineProviderSpec",
   130  		},
   131  		VPC:                  vpc,
   132  		BootVolume:           bootVolume,
   133  		DedicatedHost:        dedicatedHost,
   134  		Tags:                 []ibmcloudprovider.TagSpecs{},
   135  		Image:                fmt.Sprintf("%s-rhcos", clusterID),
   136  		NetworkResourceGroup: networkResourceGroup,
   137  		Profile:              mpool.InstanceType,
   138  		Region:               platform.Region,
   139  		ResourceGroup:        resourceGroup,
   140  		Zone:                 az,
   141  		PrimaryNetworkInterface: ibmcloudprovider.NetworkInterface{
   142  			Subnet:         subnet,
   143  			SecurityGroups: securityGroups,
   144  		},
   145  		UserDataSecret:    &corev1.LocalObjectReference{Name: userDataSecret},
   146  		CredentialsSecret: &corev1.LocalObjectReference{Name: "ibmcloud-credentials"},
   147  	}, nil
   148  }
   149  
   150  func getDedicatedHostNameForZone(clusterID string, role string, zone string) (string, error) {
   151  	switch role {
   152  	case "master":
   153  		return fmt.Sprintf("%s-dhost-control-plane-%s", clusterID, zone), nil
   154  	case "worker":
   155  		return fmt.Sprintf("%s-dhost-compute-%s", clusterID, zone), nil
   156  	default:
   157  		return "", fmt.Errorf("invalid machine role %v", role)
   158  	}
   159  }
   160  
   161  func getSubnet(subnets map[string]string, clusterID string, role string, zone string) (string, error) {
   162  	if len(subnets) == 0 {
   163  		return getSubnetName(clusterID, role, zone)
   164  	}
   165  
   166  	if subnet, found := subnets[zone]; found {
   167  		return subnet, nil
   168  	}
   169  	return "", fmt.Errorf("no subnet found for %s", zone)
   170  }
   171  
   172  func getSubnetName(clusterID string, role string, zone string) (string, error) {
   173  	switch role {
   174  	case "master":
   175  		return fmt.Sprintf("%s-subnet-control-plane-%s", clusterID, zone), nil
   176  	case "worker":
   177  		return fmt.Sprintf("%s-subnet-compute-%s", clusterID, zone), nil
   178  	default:
   179  		return "", fmt.Errorf("invalid machine role %v", role)
   180  	}
   181  }
   182  
   183  func getSecurityGroupNames(clusterID string, role string) ([]string, error) {
   184  	switch role {
   185  	case "master":
   186  		return []string{
   187  			fmt.Sprintf("%s-sg-cluster-wide", clusterID),
   188  			fmt.Sprintf("%s-sg-openshift-net", clusterID),
   189  			fmt.Sprintf("%s-sg-control-plane", clusterID),
   190  			fmt.Sprintf("%s-sg-cp-internal", clusterID),
   191  		}, nil
   192  	case "worker":
   193  		return []string{
   194  			fmt.Sprintf("%s-sg-cluster-wide", clusterID),
   195  			fmt.Sprintf("%s-sg-openshift-net", clusterID),
   196  		}, nil
   197  	default:
   198  		return nil, fmt.Errorf("invalid machine role %v", role)
   199  	}
   200  }