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

     1  package postprovision
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/gophercloud/gophercloud/v2"
     8  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/attributestags"
     9  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips"
    10  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports"
    11  	"github.com/gophercloud/gophercloud/v2/pagination"
    12  	capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
    13  	"sigs.k8s.io/controller-runtime/pkg/client"
    14  
    15  	"github.com/openshift/installer/pkg/asset/installconfig"
    16  	"github.com/openshift/installer/pkg/asset/manifests/capiutils"
    17  	openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
    18  )
    19  
    20  // FloatingIPs creates and attaches a Floating IP to the Bootstrap Machine.
    21  func FloatingIPs(ctx context.Context, c client.Client, cluster *capo.OpenStackCluster, installConfig *installconfig.InstallConfig, infraID string) error {
    22  	if cluster.Status.ExternalNetwork == nil {
    23  		return nil
    24  	}
    25  	bootstrapMachine := &capo.OpenStackMachine{}
    26  	key := client.ObjectKey{
    27  		Name:      capiutils.GenerateBoostrapMachineName(infraID),
    28  		Namespace: capiutils.Namespace,
    29  	}
    30  	if err := c.Get(ctx, key, bootstrapMachine); err != nil {
    31  		return fmt.Errorf("failed to get bootstrap Machine: %w", err)
    32  	}
    33  
    34  	networkClient, err := openstackdefaults.NewServiceClient(ctx, "network", openstackdefaults.DefaultClientOpts(installConfig.Config.Platform.OpenStack.Cloud))
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	bootstrapPort, err := getPortForInstance(ctx, networkClient, *bootstrapMachine.Status.InstanceID, cluster.Status.Network.ID)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	_, err = createAndAttachFIP(ctx, networkClient, "bootstrap", infraID, cluster.Status.ExternalNetwork.ID, bootstrapPort.ID)
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	return nil
    50  }
    51  
    52  // Return the first port associated with the given instance and existing on the
    53  // given network.
    54  func getPortForInstance(ctx context.Context, client *gophercloud.ServiceClient, instanceID, networkID string) (*ports.Port, error) {
    55  	var port *ports.Port
    56  	if err := ports.List(client, ports.ListOpts{DeviceID: instanceID, NetworkID: networkID}).EachPage(ctx, func(_ context.Context, page pagination.Page) (bool, error) {
    57  		ports, err := ports.ExtractPorts(page)
    58  		if err != nil {
    59  			return false, err
    60  		}
    61  		if len(ports) > 0 {
    62  			port = &ports[0]
    63  			return false, nil
    64  		}
    65  		return true, nil
    66  	}); err != nil {
    67  		return nil, fmt.Errorf("failed to list the ports of the bootstrap server: %w", err)
    68  	}
    69  	if port == nil {
    70  		return nil, fmt.Errorf("the bootstrap server has no associated ports")
    71  	}
    72  	return port, nil
    73  }
    74  
    75  // Create a floating IP.
    76  func createAndAttachFIP(ctx context.Context, client *gophercloud.ServiceClient, role, infraID, networkID, portID string) (*floatingips.FloatingIP, error) {
    77  	createOpts := floatingips.CreateOpts{
    78  		Description:       fmt.Sprintf("%s-%s-fip", infraID, role),
    79  		FloatingNetworkID: networkID,
    80  		PortID:            portID,
    81  	}
    82  
    83  	floatingIP, err := floatingips.Create(ctx, client, createOpts).Extract()
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	tag := fmt.Sprintf("openshiftClusterID=%s", infraID)
    89  	err = attributestags.Add(ctx, client, "floatingips", floatingIP.ID, tag).ExtractErr()
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	return floatingIP, err
    95  }