github.com/openshift/installer@v1.4.17/pkg/infrastructure/openstack/clusterapi/clusterapi.go (about)

     1  package clusterapi
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/sirupsen/logrus"
     8  	capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
     9  	"sigs.k8s.io/controller-runtime/pkg/client"
    10  	"sigs.k8s.io/yaml"
    11  
    12  	configv1 "github.com/openshift/api/config/v1"
    13  	mapov1alpha1 "github.com/openshift/api/machine/v1alpha1"
    14  	"github.com/openshift/installer/pkg/asset/manifests"
    15  	"github.com/openshift/installer/pkg/asset/manifests/capiutils"
    16  	"github.com/openshift/installer/pkg/infrastructure/clusterapi"
    17  	"github.com/openshift/installer/pkg/infrastructure/openstack/infraready"
    18  	"github.com/openshift/installer/pkg/infrastructure/openstack/postprovision"
    19  	"github.com/openshift/installer/pkg/infrastructure/openstack/preprovision"
    20  	"github.com/openshift/installer/pkg/rhcos"
    21  	"github.com/openshift/installer/pkg/types/openstack"
    22  )
    23  
    24  // Provider defines the InfraProvider.
    25  type Provider struct {
    26  	clusterapi.InfraProvider
    27  }
    28  
    29  // Name contains the name of the openstack provider.
    30  func (p Provider) Name() string {
    31  	return openstack.Name
    32  }
    33  
    34  // PublicGatherEndpoint indicates that machine ready checks should NOT wait for an ExternalIP
    35  // in the status when declaring machines ready.
    36  func (Provider) PublicGatherEndpoint() clusterapi.GatherEndpoint { return clusterapi.InternalIP }
    37  
    38  var _ clusterapi.PreProvider = Provider{}
    39  
    40  // PreProvision tags the VIP ports, and creates the security groups and the
    41  // server groups defined in the Machine manifests.
    42  func (p Provider) PreProvision(ctx context.Context, in clusterapi.PreProvisionInput) error {
    43  	var (
    44  		infraID          = in.InfraID
    45  		installConfig    = in.InstallConfig
    46  		rhcosImage       = in.RhcosImage.ControlPlane
    47  		manifestsAsset   = in.ManifestsAsset
    48  		machineManifests = in.MachineManifests
    49  		workersAsset     = in.WorkersAsset
    50  	)
    51  
    52  	if err := preprovision.TagVIPPorts(ctx, installConfig, infraID); err != nil {
    53  		return fmt.Errorf("failed to tag VIP ports: %w", err)
    54  	}
    55  
    56  	// upload the corresponding image to Glance if rhcosImage contains a
    57  	// URL. If rhcosImage contains a name, then that points to an existing
    58  	// Glance image.
    59  	if imageName, isURL := rhcos.GenerateOpenStackImageName(rhcosImage, infraID); isURL {
    60  		if err := preprovision.UploadBaseImage(ctx, installConfig.Config.Platform.OpenStack.Cloud, rhcosImage, imageName, infraID, installConfig.Config.Platform.OpenStack.ClusterOSImageProperties); err != nil {
    61  			return fmt.Errorf("failed to upload the RHCOS base image: %w", err)
    62  		}
    63  	}
    64  
    65  	{
    66  		var mastersSchedulable bool
    67  		for _, f := range manifestsAsset.Files() {
    68  			if f.Filename == manifests.SchedulerCfgFilename {
    69  				schedulerConfig := configv1.Scheduler{}
    70  				if err := yaml.Unmarshal(f.Data, &schedulerConfig); err != nil {
    71  					return fmt.Errorf("unable to decode the scheduler manifest: %w", err)
    72  				}
    73  				mastersSchedulable = schedulerConfig.Spec.MastersSchedulable
    74  				break
    75  			}
    76  		}
    77  		if err := preprovision.SecurityGroups(ctx, installConfig, infraID, mastersSchedulable); err != nil {
    78  			return fmt.Errorf("failed to create security groups: %w", err)
    79  		}
    80  	}
    81  
    82  	{
    83  		capiMachines := make([]capo.OpenStackMachine, 0, len(machineManifests))
    84  		for i := range machineManifests {
    85  			if m, ok := machineManifests[i].(*capo.OpenStackMachine); ok {
    86  				capiMachines = append(capiMachines, *m)
    87  			}
    88  		}
    89  
    90  		var workerSpecs []mapov1alpha1.OpenstackProviderSpec
    91  		{
    92  			machineSets, err := workersAsset.MachineSets()
    93  			if err != nil {
    94  				return fmt.Errorf("failed to extract MachineSets from the worker assets: %w", err)
    95  			}
    96  			workerSpecs = make([]mapov1alpha1.OpenstackProviderSpec, 0, len(machineSets))
    97  			for _, machineSet := range machineSets {
    98  				workerSpecs = append(workerSpecs, *machineSet.Spec.Template.Spec.ProviderSpec.Value.Object.(*mapov1alpha1.OpenstackProviderSpec))
    99  			}
   100  		}
   101  		if err := preprovision.ServerGroups(ctx, installConfig, capiMachines, workerSpecs); err != nil {
   102  			return fmt.Errorf("failed to create server groups: %w", err)
   103  		}
   104  	}
   105  
   106  	return nil
   107  }
   108  
   109  var _ clusterapi.InfraReadyProvider = Provider{}
   110  
   111  // InfraReady creates the API and Ingress ports and attaches the Floating IPs to them.
   112  func (p Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput) error {
   113  	var (
   114  		k8sClient     = in.Client
   115  		infraID       = in.InfraID
   116  		installConfig = in.InstallConfig
   117  	)
   118  
   119  	ospCluster := &capo.OpenStackCluster{}
   120  	key := client.ObjectKey{
   121  		Name:      infraID,
   122  		Namespace: capiutils.Namespace,
   123  	}
   124  	if err := k8sClient.Get(ctx, key, ospCluster); err != nil {
   125  		return fmt.Errorf("failed to get OSPCluster: %w", err)
   126  	}
   127  
   128  	return infraready.FloatingIPs(ctx, ospCluster, installConfig, infraID)
   129  }
   130  
   131  var _ clusterapi.IgnitionProvider = Provider{}
   132  
   133  // Ignition uploads the bootstrap machine's Ignition file to OpenStack.
   134  func (p Provider) Ignition(ctx context.Context, in clusterapi.IgnitionInput) ([]byte, error) {
   135  	logrus.Debugf("Uploading the bootstrap machine's Ignition file to OpenStack")
   136  	var (
   137  		bootstrapIgnData = in.BootstrapIgnData
   138  		infraID          = in.InfraID
   139  		installConfig    = in.InstallConfig
   140  	)
   141  
   142  	return preprovision.UploadIgnitionAndBuildShim(ctx, installConfig.Config.Platform.OpenStack.Cloud, infraID, installConfig.Config.Proxy, bootstrapIgnData)
   143  }
   144  
   145  var _ clusterapi.PostProvider = Provider{}
   146  
   147  // PostProvision creates and attaches a Floating IP to the Bootstrap Machine.
   148  func (p Provider) PostProvision(ctx context.Context, in clusterapi.PostProvisionInput) error {
   149  	var (
   150  		k8sClient     = in.Client
   151  		infraID       = in.InfraID
   152  		installConfig = in.InstallConfig
   153  	)
   154  
   155  	ospCluster := &capo.OpenStackCluster{}
   156  	key := client.ObjectKey{
   157  		Name:      infraID,
   158  		Namespace: capiutils.Namespace,
   159  	}
   160  	if err := k8sClient.Get(ctx, key, ospCluster); err != nil {
   161  		return fmt.Errorf("failed to get OSPCluster: %w", err)
   162  	}
   163  
   164  	return postprovision.FloatingIPs(ctx, k8sClient, ospCluster, installConfig, infraID)
   165  }