github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/openstack/validvaluesfetcher.go (about)

     1  package openstack
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/flavors"
     8  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/external"
     9  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips"
    10  	"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/networks"
    11  	"github.com/gophercloud/utils/v2/openstack/clientconfig"
    12  	networkutils "github.com/gophercloud/utils/v2/openstack/networking/v2/networks"
    13  
    14  	openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
    15  )
    16  
    17  // getCloudNames gets the valid cloud names. These are read from clouds.yaml.
    18  func getCloudNames() ([]string, error) {
    19  	clouds, err := clientconfig.LoadCloudsYAML()
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  
    24  	cloudNames := []string{}
    25  	for k := range clouds {
    26  		cloudNames = append(cloudNames, k)
    27  	}
    28  	return cloudNames, nil
    29  }
    30  
    31  // getExternalNetworkNames interrogates OpenStack to get the external network
    32  // names.
    33  func getExternalNetworkNames(ctx context.Context, cloud string) ([]string, error) {
    34  	conn, err := openstackdefaults.NewServiceClient(ctx, "network", openstackdefaults.DefaultClientOpts(cloud))
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	iTrue := true
    40  	listOpts := external.ListOptsExt{
    41  		ListOptsBuilder: networks.ListOpts{},
    42  		External:        &iTrue,
    43  	}
    44  
    45  	allPages, err := networks.List(conn, listOpts).AllPages(ctx)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	allNetworks, err := networks.ExtractNetworks(allPages)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	networkNames := make([]string, len(allNetworks))
    56  	for x, network := range allNetworks {
    57  		networkNames[x] = network.Name
    58  	}
    59  
    60  	return networkNames, nil
    61  }
    62  
    63  // getFlavorNames gets a list of valid flavor names.
    64  func getFlavorNames(ctx context.Context, cloud string) ([]string, error) {
    65  	conn, err := openstackdefaults.NewServiceClient(ctx, "compute", openstackdefaults.DefaultClientOpts(cloud))
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	listOpts := flavors.ListOpts{}
    71  	allPages, err := flavors.ListDetail(conn, listOpts).AllPages(ctx)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	allFlavors, err := flavors.ExtractFlavors(allPages)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	if len(allFlavors) == 0 {
    82  		return nil, fmt.Errorf("no OpenStack flavors were found")
    83  	}
    84  
    85  	flavorNames := make([]string, len(allFlavors))
    86  	for i, flavor := range allFlavors {
    87  		flavorNames[i] = flavor.Name
    88  	}
    89  
    90  	return flavorNames, nil
    91  }
    92  
    93  type sortableFloatingIPCollection []floatingips.FloatingIP
    94  
    95  func (fips sortableFloatingIPCollection) Len() int { return len(fips) }
    96  func (fips sortableFloatingIPCollection) Less(i, j int) bool {
    97  	return fips[i].FloatingIP < fips[j].FloatingIP
    98  }
    99  func (fips sortableFloatingIPCollection) Swap(i, j int) {
   100  	fips[i], fips[j] = fips[j], fips[i]
   101  }
   102  
   103  func (fips sortableFloatingIPCollection) Names() []string {
   104  	names := make([]string, len(fips))
   105  	for i := range fips {
   106  		names[i] = fips[i].FloatingIP
   107  	}
   108  	return names
   109  }
   110  
   111  func (fips sortableFloatingIPCollection) Description(index int) string {
   112  	return fips[index].Description
   113  }
   114  
   115  func (fips sortableFloatingIPCollection) Contains(value string) bool {
   116  	for i := range fips {
   117  		if value == fips[i].FloatingIP {
   118  			return true
   119  		}
   120  	}
   121  	return false
   122  }
   123  
   124  func getFloatingIPs(ctx context.Context, cloud string, floatingNetworkName string) (sortableFloatingIPCollection, error) {
   125  	conn, err := openstackdefaults.NewServiceClient(ctx, "network", openstackdefaults.DefaultClientOpts(cloud))
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	// floatingips.ListOpts requires an ID so we must get it from the name
   131  	floatingNetworkID, err := networkutils.IDFromName(ctx, conn, floatingNetworkName)
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	// Only show IPs that belong to the network and are not in use
   137  	listOpts := floatingips.ListOpts{
   138  		FloatingNetworkID: floatingNetworkID,
   139  		Status:            "DOWN",
   140  	}
   141  
   142  	allPages, err := floatingips.List(conn, listOpts).AllPages(ctx)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	allFloatingIPs, err := floatingips.ExtractFloatingIPs(allPages)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  
   152  	if len(allFloatingIPs) == 0 {
   153  		return nil, fmt.Errorf("there are no unassigned floating IP addresses available")
   154  	}
   155  
   156  	return allFloatingIPs, nil
   157  }