github.com/openshift/installer@v1.4.17/pkg/tfvars/openstack/ports.go (about)

     1  package openstack
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/gophercloud/gophercloud/v2"
     8  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/subnets"
     9  	"github.com/gophercloud/gophercloud/v2/pagination"
    10  	network_utils "github.com/gophercloud/utils/v2/openstack/networking/v2/networks"
    11  
    12  	machinev1alpha1 "github.com/openshift/api/machine/v1alpha1"
    13  	types_openstack "github.com/openshift/installer/pkg/types/openstack"
    14  )
    15  
    16  type terraformFixedIP struct {
    17  	SubnetID  string `json:"subnet_id"`
    18  	IPAddress string `json:"ip_address"`
    19  }
    20  
    21  type terraformPort struct {
    22  	NetworkID string             `json:"network_id"`
    23  	FixedIP   []terraformFixedIP `json:"fixed_ips"`
    24  }
    25  
    26  func portTargetToTerraformPort(ctx context.Context, networkClient *gophercloud.ServiceClient, portTarget types_openstack.PortTarget) (terraformPort, error) {
    27  	networkID := portTarget.Network.ID
    28  	if networkID == "" && portTarget.Network.Name != "" {
    29  		var err error
    30  		networkID, err = network_utils.IDFromName(ctx, networkClient, portTarget.Network.Name)
    31  		if err != nil {
    32  			return terraformPort{}, fmt.Errorf("failed to resolve network ID for network name %q: %w", portTarget.Network.Name, err)
    33  		}
    34  	}
    35  
    36  	terraformFixedIPs := make([]terraformFixedIP, 0, len(portTarget.FixedIPs))
    37  	for _, fixedIP := range portTarget.FixedIPs {
    38  		subnetFilter := machinev1alpha1.SubnetFilter{
    39  			ID:   fixedIP.Subnet.ID,
    40  			Name: fixedIP.Subnet.Name,
    41  		}
    42  		resolvedSubnetID, resolvedNetworkID, err := resolveSubnetFilter(ctx, networkClient, networkID, subnetFilter)
    43  		if err != nil {
    44  			return terraformPort{}, fmt.Errorf("failed to resolve the subnet filter: %w", err)
    45  		}
    46  
    47  		if networkID == "" {
    48  			networkID = resolvedNetworkID
    49  		}
    50  
    51  		if networkID != resolvedNetworkID {
    52  			return terraformPort{}, fmt.Errorf("control plane port has ports on multiple networks")
    53  		}
    54  
    55  		terraformFixedIPs = append(terraformFixedIPs, terraformFixedIP{
    56  			SubnetID: resolvedSubnetID,
    57  		})
    58  	}
    59  
    60  	return terraformPort{
    61  		NetworkID: networkID,
    62  		FixedIP:   terraformFixedIPs,
    63  	}, nil
    64  }
    65  
    66  func resolveSubnetFilter(ctx context.Context, networkClient *gophercloud.ServiceClient, networkID string, subnetFilter machinev1alpha1.SubnetFilter) (resolvedSubnetID, resolvedNetworkID string, err error) {
    67  	if subnetFilter.ProjectID != "" {
    68  		subnetFilter.TenantID = ""
    69  	}
    70  	if err = subnets.List(networkClient, subnets.ListOpts{
    71  		NetworkID: networkID,
    72  		Name:      subnetFilter.Name,
    73  		ID:        subnetFilter.ID,
    74  	}).EachPage(ctx, func(ctx context.Context, page pagination.Page) (bool, error) {
    75  		returnedSubnets, err := subnets.ExtractSubnets(page)
    76  		if err != nil {
    77  			return false, err
    78  		}
    79  		for _, subnet := range returnedSubnets {
    80  			if resolvedSubnetID == "" {
    81  				resolvedSubnetID = subnet.ID
    82  				resolvedNetworkID = subnet.NetworkID
    83  			} else {
    84  				return false, fmt.Errorf("more than one subnet found")
    85  			}
    86  		}
    87  		return true, nil
    88  	}); err != nil {
    89  		return "", "", fmt.Errorf("failed to list subnets: %w", err)
    90  	}
    91  
    92  	if resolvedSubnetID == "" {
    93  		return "", "", fmt.Errorf("no subnet found")
    94  	}
    95  
    96  	return resolvedSubnetID, resolvedNetworkID, err
    97  }