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

     1  // Package powervs generates Machine objects for powerVS.
     2  package powervs
     3  
     4  import (
     5  	"errors"
     6  	"fmt"
     7  
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  
    11  	machinev1 "github.com/openshift/api/machine/v1"
    12  	machineapi "github.com/openshift/api/machine/v1beta1"
    13  	"github.com/openshift/installer/pkg/types"
    14  	"github.com/openshift/installer/pkg/types/powervs"
    15  )
    16  
    17  // Machines returns a list of machines for a machinepool.
    18  func Machines(clusterID string, config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]machineapi.Machine, *machinev1.ControlPlaneMachineSet, error) {
    19  	if configPlatform := config.Platform.Name(); configPlatform != powervs.Name {
    20  		return nil, nil, fmt.Errorf("non-PowerVS configuration: %q", configPlatform)
    21  	}
    22  	if poolPlatform := pool.Platform.Name(); poolPlatform != powervs.Name {
    23  		return nil, nil, fmt.Errorf("non-PowerVS machine-pool: %q", poolPlatform)
    24  	}
    25  	platform := config.Platform.PowerVS
    26  	mpool := pool.Platform.PowerVS
    27  
    28  	// Only the service instance is guaranteed to exist and be passed via the install config
    29  	// The other two, we should standardize a name including the cluster id.
    30  	image := fmt.Sprintf("rhcos-%s", clusterID)
    31  	var network string
    32  	if platform.ClusterOSImage != "" {
    33  		image = platform.ClusterOSImage
    34  	}
    35  
    36  	total := int64(1)
    37  	if pool.Replicas != nil {
    38  		total = *pool.Replicas
    39  	}
    40  	var machines []machineapi.Machine
    41  	machineProvider, err := provider(clusterID, platform, mpool, userDataSecret, image, network)
    42  	if err != nil {
    43  		return nil, nil, fmt.Errorf("failed to create provider: %w", err)
    44  	}
    45  	for idx := int64(0); idx < total; idx++ {
    46  		machine := machineapi.Machine{
    47  			TypeMeta: metav1.TypeMeta{
    48  				APIVersion: "machine.openshift.io/v1beta1",
    49  				Kind:       "Machine",
    50  			},
    51  			ObjectMeta: metav1.ObjectMeta{
    52  				Namespace: "openshift-machine-api",
    53  				Name:      fmt.Sprintf("%s-%s-%d", clusterID, pool.Name, idx),
    54  				Labels: map[string]string{
    55  					"machine.openshift.io/cluster-api-cluster":      clusterID,
    56  					"machine.openshift.io/cluster-api-machine-role": role,
    57  					"machine.openshift.io/cluster-api-machine-type": role,
    58  				},
    59  			},
    60  			Spec: machineapi.MachineSpec{
    61  				ProviderSpec: machineapi.ProviderSpec{
    62  					Value: &runtime.RawExtension{Object: machineProvider},
    63  				},
    64  			},
    65  		}
    66  		machines = append(machines, machine)
    67  	}
    68  	replicas := int32(total)
    69  	controlPlaneMachineSet := &machinev1.ControlPlaneMachineSet{
    70  		TypeMeta: metav1.TypeMeta{
    71  			APIVersion: "machine.openshift.io/v1",
    72  			Kind:       "ControlPlaneMachineSet",
    73  		},
    74  		ObjectMeta: metav1.ObjectMeta{
    75  			Namespace: "openshift-machine-api",
    76  			Name:      "cluster",
    77  			Labels: map[string]string{
    78  				"machine.openshift.io/cluster-api-cluster": clusterID,
    79  			},
    80  		},
    81  		Spec: machinev1.ControlPlaneMachineSetSpec{
    82  			Replicas: &replicas,
    83  			State:    machinev1.ControlPlaneMachineSetStateInactive,
    84  			Selector: metav1.LabelSelector{
    85  				MatchLabels: map[string]string{
    86  					"machine.openshift.io/cluster-api-machine-role": role,
    87  					"machine.openshift.io/cluster-api-machine-type": role,
    88  					"machine.openshift.io/cluster-api-cluster":      clusterID,
    89  				},
    90  			},
    91  			Template: machinev1.ControlPlaneMachineSetTemplate{
    92  				MachineType: machinev1.OpenShiftMachineV1Beta1MachineType,
    93  				OpenShiftMachineV1Beta1Machine: &machinev1.OpenShiftMachineV1Beta1MachineTemplate{
    94  					ObjectMeta: machinev1.ControlPlaneMachineSetTemplateObjectMeta{
    95  						Labels: map[string]string{
    96  							"machine.openshift.io/cluster-api-cluster":      clusterID,
    97  							"machine.openshift.io/cluster-api-machine-role": role,
    98  							"machine.openshift.io/cluster-api-machine-type": role,
    99  						},
   100  					},
   101  					Spec: machineapi.MachineSpec{
   102  						ProviderSpec: machineapi.ProviderSpec{
   103  							Value: &runtime.RawExtension{Object: machineProvider},
   104  						},
   105  					},
   106  				},
   107  			},
   108  		},
   109  	}
   110  	return machines, controlPlaneMachineSet, nil
   111  }
   112  
   113  func provider(clusterID string, platform *powervs.Platform, mpool *powervs.MachinePool, userDataSecret string, image string, network string) (*machinev1.PowerVSMachineProviderConfig, error) {
   114  
   115  	if clusterID == "" || platform == nil || mpool == nil || userDataSecret == "" || image == "" {
   116  		return nil, fmt.Errorf("invalid value passed to provider")
   117  	}
   118  
   119  	dhcpNetRegex := fmt.Sprintf("^DHCPSERVER.*%s.*_Private$", clusterID)
   120  
   121  	var config *machinev1.PowerVSMachineProviderConfig
   122  
   123  	// If a service instance GUID was not passed in the install-config.yaml file, then
   124  	// we tell the machine provider to use a specific name via XXXTypeName.  Otherwide,
   125  	// we tell the machine provider the given GUID via XXXTypeID.
   126  	if platform.ServiceInstanceGUID == "" {
   127  		serviceName := fmt.Sprintf("%s-power-iaas", clusterID)
   128  
   129  		// Setting only the mandatory parameters
   130  		config = &machinev1.PowerVSMachineProviderConfig{
   131  			TypeMeta: metav1.TypeMeta{
   132  				Kind:       "PowerVSMachineProviderConfig",
   133  				APIVersion: machinev1.GroupVersion.String(),
   134  			},
   135  			ObjectMeta: metav1.ObjectMeta{},
   136  			ServiceInstance: machinev1.PowerVSResource{
   137  				Type: machinev1.PowerVSResourceTypeName,
   138  				Name: &serviceName,
   139  			},
   140  			Image: machinev1.PowerVSResource{
   141  				Type: machinev1.PowerVSResourceTypeName,
   142  				Name: &image,
   143  			},
   144  			UserDataSecret: &machinev1.PowerVSSecretReference{
   145  				Name: userDataSecret,
   146  			},
   147  			CredentialsSecret: &machinev1.PowerVSSecretReference{
   148  				Name: "powervs-credentials",
   149  			},
   150  			SystemType:    mpool.SysType,
   151  			ProcessorType: mpool.ProcType,
   152  			Processors:    mpool.Processors,
   153  			MemoryGiB:     mpool.MemoryGiB,
   154  			KeyPairName:   fmt.Sprintf("%s-key", clusterID),
   155  		}
   156  	} else {
   157  		// Setting only the mandatory parameters
   158  		config = &machinev1.PowerVSMachineProviderConfig{
   159  			TypeMeta: metav1.TypeMeta{
   160  				Kind:       "PowerVSMachineProviderConfig",
   161  				APIVersion: machinev1.GroupVersion.String(),
   162  			},
   163  			ObjectMeta: metav1.ObjectMeta{},
   164  			ServiceInstance: machinev1.PowerVSResource{
   165  				Type: machinev1.PowerVSResourceTypeID,
   166  				ID:   &platform.ServiceInstanceGUID,
   167  			},
   168  			Image: machinev1.PowerVSResource{
   169  				Type: machinev1.PowerVSResourceTypeName,
   170  				Name: &image,
   171  			},
   172  			UserDataSecret: &machinev1.PowerVSSecretReference{
   173  				Name: userDataSecret,
   174  			},
   175  			CredentialsSecret: &machinev1.PowerVSSecretReference{
   176  				Name: "powervs-credentials",
   177  			},
   178  			SystemType:    mpool.SysType,
   179  			ProcessorType: mpool.ProcType,
   180  			Processors:    mpool.Processors,
   181  			MemoryGiB:     mpool.MemoryGiB,
   182  			KeyPairName:   fmt.Sprintf("%s-key", clusterID),
   183  		}
   184  	}
   185  	if network != "" {
   186  		config.Network = machinev1.PowerVSResource{
   187  			Type: machinev1.PowerVSResourceTypeName,
   188  			Name: &network,
   189  		}
   190  	} else {
   191  		config.Network = machinev1.PowerVSResource{
   192  			Type:  machinev1.PowerVSResourceTypeRegEx,
   193  			RegEx: &dhcpNetRegex,
   194  		}
   195  	}
   196  	return config, nil
   197  }
   198  
   199  // ConfigMasters sets the PublicIP flag and assigns a set of load balancers to the given machines.
   200  func ConfigMasters(machines []machineapi.Machine, controlPlane *machinev1.ControlPlaneMachineSet, infraID string, publish types.PublishingStrategy) error {
   201  	lbrefs := []machinev1.LoadBalancerReference{{
   202  		Name: fmt.Sprintf("%s-loadbalancer-int", infraID),
   203  		Type: machinev1.ApplicationLoadBalancerType,
   204  	}}
   205  
   206  	if publish == types.ExternalPublishingStrategy {
   207  		lbrefs = append(lbrefs, machinev1.LoadBalancerReference{
   208  			Name: fmt.Sprintf("%s-loadbalancer", infraID),
   209  			Type: machinev1.ApplicationLoadBalancerType,
   210  		})
   211  	}
   212  
   213  	for _, machine := range machines {
   214  		providerSpec, ok := machine.Spec.ProviderSpec.Value.Object.(*machinev1.PowerVSMachineProviderConfig)
   215  		if !ok {
   216  			return errors.New("unable to set load balancers to control plane machine set")
   217  		}
   218  		providerSpec.LoadBalancers = lbrefs
   219  	}
   220  
   221  	providerSpec, ok := controlPlane.Spec.Template.OpenShiftMachineV1Beta1Machine.Spec.ProviderSpec.Value.Object.(*machinev1.PowerVSMachineProviderConfig)
   222  	if !ok {
   223  		return errors.New("unable to set load balancers to control plane machine set")
   224  	}
   225  	providerSpec.LoadBalancers = lbrefs
   226  	return nil
   227  }