github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/endpoint_location.go (about)

     1  package openstack
     2  
     3  import (
     4  	"github.com/huaweicloud/golangsdk"
     5  	tokens2 "github.com/huaweicloud/golangsdk/openstack/identity/v2/tokens"
     6  	tokens3 "github.com/huaweicloud/golangsdk/openstack/identity/v3/tokens"
     7  )
     8  
     9  /*
    10  V2EndpointURL discovers the endpoint URL for a specific service from a
    11  ServiceCatalog acquired during the v2 identity service.
    12  
    13  The specified EndpointOpts are used to identify a unique, unambiguous endpoint
    14  to return. It's an error both when multiple endpoints match the provided
    15  criteria and when none do. The minimum that can be specified is a Type, but you
    16  will also often need to specify a Name and/or a Region depending on what's
    17  available on your OpenStack deployment.
    18  */
    19  func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts golangsdk.EndpointOpts) (string, error) {
    20  	// Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
    21  	var endpoints = make([]tokens2.Endpoint, 0, 1)
    22  	for _, entry := range catalog.Entries {
    23  		if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) {
    24  			for _, endpoint := range entry.Endpoints {
    25  				if endpoint.Region == opts.Region || (opts.Region == "" && endpoint.Region == "*") {
    26  					endpoints = append(endpoints, endpoint)
    27  				}
    28  			}
    29  		}
    30  	}
    31  
    32  	// Report an error if the options were ambiguous.
    33  	if len(endpoints) > 1 {
    34  		err := &ErrMultipleMatchingEndpointsV2{}
    35  		err.Endpoints = endpoints
    36  		return "", err
    37  	}
    38  
    39  	// Extract the appropriate URL from the matching Endpoint.
    40  	for _, endpoint := range endpoints {
    41  		switch opts.Availability {
    42  		case golangsdk.AvailabilityPublic:
    43  			return golangsdk.NormalizeURL(endpoint.PublicURL), nil
    44  		case golangsdk.AvailabilityInternal:
    45  			return golangsdk.NormalizeURL(endpoint.InternalURL), nil
    46  		case golangsdk.AvailabilityAdmin:
    47  			return golangsdk.NormalizeURL(endpoint.AdminURL), nil
    48  		default:
    49  			err := &ErrInvalidAvailabilityProvided{}
    50  			err.Argument = "Availability"
    51  			err.Value = opts.Availability
    52  			return "", err
    53  		}
    54  	}
    55  
    56  	// Report an error if there were no matching endpoints.
    57  	err := &golangsdk.ErrEndpointNotFound{}
    58  	return "", err
    59  }
    60  
    61  /*
    62  V3EndpointURL discovers the endpoint URL for a specific service from a Catalog
    63  acquired during the v3 identity service.
    64  
    65  The specified EndpointOpts are used to identify a unique, unambiguous endpoint
    66  to return. It's an error both when multiple endpoints match the provided
    67  criteria and when none do. The minimum that can be specified is a Type, but you
    68  will also often need to specify a Name and/or a Region depending on what's
    69  available on your OpenStack deployment.
    70  */
    71  func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts golangsdk.EndpointOpts) (string, error) {
    72  	// Extract Endpoints from the catalog entries that match the requested Type, Interface,
    73  	// Name if provided, and Region if provided.
    74  	var endpoints = make([]tokens3.Endpoint, 0, 1)
    75  	for _, entry := range catalog.Entries {
    76  		if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) {
    77  			for _, endpoint := range entry.Endpoints {
    78  				if opts.Availability != golangsdk.AvailabilityAdmin &&
    79  					opts.Availability != golangsdk.AvailabilityPublic &&
    80  					opts.Availability != golangsdk.AvailabilityInternal {
    81  					err := &ErrInvalidAvailabilityProvided{}
    82  					err.Argument = "Availability"
    83  					err.Value = opts.Availability
    84  					return "", err
    85  				}
    86  				if opts.Availability == golangsdk.Availability(endpoint.Interface) &&
    87  					(endpoint.Region == opts.Region ||
    88  						(opts.Region == "" && endpoint.Region == "*")) {
    89  					endpoints = append(endpoints, endpoint)
    90  				}
    91  			}
    92  		}
    93  	}
    94  
    95  	// Report an error if the options were ambiguous.
    96  	if len(endpoints) > 1 {
    97  		return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints}
    98  	}
    99  
   100  	// Extract the URL from the matching Endpoint.
   101  	for _, endpoint := range endpoints {
   102  		return golangsdk.NormalizeURL(endpoint.URL), nil
   103  	}
   104  
   105  	// Report an error if there were no matching endpoints.
   106  	err := &golangsdk.ErrEndpointNotFound{}
   107  	return "", err
   108  }