github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/openapi_endpoints.go (about)

     1  package govcd
     2  
     3  /*
     4   * Copyright 2021 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     5   */
     6  
     7  import (
     8  	"fmt"
     9  	"sort"
    10  	"strings"
    11  
    12  	"github.com/vmware/go-vcloud-director/v2/util"
    13  
    14  	"github.com/hashicorp/go-version"
    15  
    16  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    17  )
    18  
    19  // endpointMinApiVersions holds mapping of OpenAPI endpoints and API versions they were introduced in.
    20  var endpointMinApiVersions = map[string]string{
    21  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRights:                              "31.0",
    22  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRightsBundles:                       "31.0",
    23  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRightsCategories:                    "31.0",
    24  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRoles:                               "31.0",
    25  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointGlobalRoles:                         "31.0",
    26  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRoles + types.OpenApiEndpointRights: "31.0",
    27  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAuditTrail:                          "33.0",
    28  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointImportableTier0Routers:              "32.0",
    29  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointImportableDvpgs:                     "36.0",
    30  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointTestConnection:                      "34.0",
    31  	// OpenApiEndpointExternalNetworks endpoint support was introduced with version 32.0 however it was still not stable
    32  	// enough to be used. (i.e. it did not support update "PUT")
    33  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks:           "33.0",
    34  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcComputePolicies:         "32.0",
    35  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcAssignedComputePolicies: "33.0",
    36  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointSessionCurrent:             "34.0",
    37  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeClusters:               "34.0", // VCD 10.1+
    38  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointQosProfiles:                "36.2", // VCD 10.3.2+ (NSX-T only)
    39  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayQos:             "36.2", // VCD 10.3.2+ (NSX-T only)
    40  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDhcpForwarder:   "36.1", // VCD 10.3.1+ (NSX-T only)
    41  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDns:             "37.0", // VCD 10.4.0+ (NSX-T only)
    42  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayL2VpnTunnel:     "35.0", // VCD 10.2.0+ (NSX-T only)
    43  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewaySlaacProfile:    "35.0",
    44  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayStaticRoutes:    "37.0", // VCD 10.4.0+ (NSX-T only)
    45  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways:               "34.0",
    46  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayUsedIpAddresses: "34.0",
    47  
    48  	// Static security groups and IP sets in VCD 10.2, Dynamic security groups in VCD 10.3+
    49  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups:                     "34.0",
    50  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtNatRules:                       "34.0",
    51  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtFirewallRules:                  "34.0",
    52  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworks:                     "32.0", // VCD 9.7+ for NSX-V, 10.1+ for NSX-T
    53  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworkSegmentProfiles:       "37.0",
    54  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworksDhcp:                 "32.0", // VCD 9.7+ for NSX-V, 10.1+ for NSX-T
    55  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworksDhcpBindings:         "36.1", // VCD 10.3.1+ (NSX-T only)
    56  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcCapabilities:                    "32.0",
    57  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAppPortProfiles:                    "34.0", // VCD 10.1+
    58  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSecVpnTunnel:                     "34.0", // VCD 10.1+
    59  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSecVpnTunnelConnectionProperties: "34.0", // VCD 10.1+
    60  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSecVpnTunnelStatus:               "34.0", // VCD 10.1+
    61  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroups:                          "35.0", // VCD 10.2+
    62  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroupsCandidateVdcs:             "35.0", // VCD 10.2+
    63  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroupsDfwPolicies:               "35.0", // VCD 10.2+
    64  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroupsDfwDefaultPolicies:        "35.0", // VCD 10.2+
    65  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointSecurityTags:                       "36.0", // VCD 10.3+
    66  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtRouteAdvertisement:             "34.0", // VCD 10.1+
    67  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointLogicalVmGroups:                    "35.0", // VCD 10.2+
    68  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaces:                      "35.0", // VCD 10.2+
    69  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeInterfaceBehaviors:              "35.0", // VCD 10.2+
    70  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntityTypes:                     "35.0", // VCD 10.2+
    71  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeTypeBehaviors:                   "35.0", // VCD 10.2+
    72  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeTypeBehaviorAccessControls:      "35.0", // VCD 10.2+
    73  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntities:                        "35.0", // VCD 10.2+
    74  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntitiesTypes:                   "35.0", // VCD 10.2+
    75  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntitiesResolve:                 "35.0", // VCD 10.2+
    76  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntitiesBehaviorsInvocations:    "35.0", // VCD 10.2+
    77  
    78  	// IP Spaces
    79  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces:                     "37.1", // VCD 10.4.1+
    80  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceSummaries:             "37.1", // VCD 10.4.1+
    81  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceUplinks:               "37.1", // VCD 10.4.1+
    82  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceUplinksAllocate:       "37.1", // VCD 10.4.1+
    83  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceIpAllocations:         "37.1", // VCD 10.4.1+
    84  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceOrgAssignments:        "37.1", // VCD 10.4.1+
    85  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceFloatingIpSuggestions: "37.1", // VCD 10.4.1+
    86  
    87  	// NSX-T ALB (Advanced/AVI Load Balancer) support was introduced in 10.2
    88  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbController:                    "35.0", // VCD 10.2+
    89  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbImportableClouds:              "35.0", // VCD 10.2+
    90  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbImportableServiceEngineGroups: "35.0", // VCD 10.2+
    91  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbCloud:                         "35.0", // VCD 10.2+
    92  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbServiceEngineGroups:           "35.0", // VCD 10.2+
    93  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbEdgeGateway:                   "35.0", // VCD 10.2+
    94  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbServiceEngineGroupAssignments: "35.0", // VCD 10.2+
    95  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools:                         "35.0", // VCD 10.2+
    96  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPoolSummaries:                 "35.0", // VCD 10.2+
    97  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices:               "35.0", // VCD 10.2+
    98  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServiceSummaries:       "35.0", // VCD 10.2+
    99  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointSSLCertificateLibrary:            "35.0", // VCD 10.2+
   100  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointSSLCertificateLibraryOld:         "35.0", // VCD 10.2+ and deprecated from 10.3
   101  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroupsDfwRules:                "35.0", // VCD 10.2+
   102  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNetworkContextProfiles:           "35.0", // VCD 10.2+
   103  
   104  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpNeighbor:          "35.0", // VCD 10.2+
   105  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists: "35.0", // VCD 10.2+
   106  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfig:            "35.0", // VCD 10.2+
   107  
   108  	types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcAssignedComputePolicies: "35.0",
   109  	types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies:         "35.0",
   110  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcNetworkProfile:          "36.0", // VCD 10.3+
   111  
   112  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVirtualCenters:                           "36.0",
   113  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointResourcePools:                            "36.0",
   114  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointResourcePoolsBrowseAll:                   "36.2",
   115  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointResourcePoolHardware:                     "36.0",
   116  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNetworkPools:                             "36.0",
   117  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNetworkPoolSummaries:                     "36.0",
   118  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointStorageProfiles:                          "33.0",
   119  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentProfileTemplates:              "36.2",
   120  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtGlobalDefaultSegmentProfileTemplates: "36.2",
   121  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentIpDiscoveryProfiles:           "36.2",
   122  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentMacDiscoveryProfiles:          "36.2",
   123  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentSpoofGuardProfiles:            "36.2",
   124  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentQosProfiles:                   "36.2",
   125  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtSegmentSecurityProfiles:              "36.2",
   126  
   127  	// Extensions API endpoints. These are not versioned
   128  	types.OpenApiEndpointExtensionsUi:                    "35.0", // VCD 10.2+
   129  	types.OpenApiEndpointExtensionsUiPlugin:              "35.0", // VCD 10.2+
   130  	types.OpenApiEndpointExtensionsUiTenants:             "35.0", // VCD 10.2+
   131  	types.OpenApiEndpointExtensionsUiTenantsPublishAll:   "35.0", // VCD 10.2+
   132  	types.OpenApiEndpointExtensionsUiTenantsPublish:      "35.0", // VCD 10.2+
   133  	types.OpenApiEndpointExtensionsUiTenantsUnpublishAll: "35.0", // VCD 10.2+
   134  	types.OpenApiEndpointExtensionsUiTenantsUnpublish:    "35.0", // VCD 10.2+
   135  
   136  	// Endpoints for managing tokens and service accounts
   137  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointTokens:                   "36.1", // VCD 10.3.1+
   138  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointServiceAccounts:          "37.0", // VCD 10.4.0+
   139  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointServiceAccountGrant:      "37.0", // VCD 10.4.0+
   140  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointImportableTransportZones: "33.0",
   141  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVCenterDistributedSwitch: "33.0",
   142  
   143  	// Endpoint for managing vGPU profiles
   144  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVgpuProfile: "36.2",
   145  }
   146  
   147  // endpointElevatedApiVersions endpoint elevated API versions
   148  var endpointElevatedApiVersions = map[string][]string{
   149  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNsxtNatRules: {
   150  		//"34.0", // Basic minimum required version
   151  		"35.2", // Introduces support for new fields FirewallMatch and Priority
   152  		"36.0", // Adds support for new NAT Rule Type - REFLEXIVE (field Type must be used instead of RuleType)
   153  	},
   154  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks: {
   155  		//"33.0", // Basic minimum required version
   156  		"35.0", // Deprecates field BackingType in favor of BackingTypeValue
   157  		"36.0", // Adds support new type of BackingTypeValue - IMPORTED_T_LOGICAL_SWITCH (backed by NSX-T segment)
   158  		"37.1", // Adds support for IP Spaces with new fields - UsingIpSpace, DedicatedOrg
   159  	},
   160  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroupsDfwRules: {
   161  		//"35.0", // Basic minimum required version
   162  		"35.2", // Deprecates Action field in favor of ActionValue
   163  		"36.2", // Adds 3 new fields - Comments, SourceGroupsExcluded, and DestinationGroupsExcluded
   164  	},
   165  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworksDhcp: {
   166  		//"32.0", // Basic minimum required version
   167  		"36.1", // Adds support for dnsServers
   168  	},
   169  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups: {
   170  		//"34.0", // Basic minimum required version
   171  		"36.0", // Adds support for Dynamic Security Groups by deprecating `Type` field in favor of `TypeValue`
   172  	},
   173  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbController: {
   174  		//"35.0", // Basic minimum required version
   175  		"37.0", // Deprecates LicenseType in favor of SupportedFeatureSet
   176  	},
   177  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbServiceEngineGroups: {
   178  		//"35.0", // Basic minimum required version
   179  		"37.0", // Adds SupportedFeatureSet
   180  	},
   181  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbEdgeGateway: {
   182  		//"35.0", // Basic minimum required version
   183  		"37.0", // Deprecates LicenseType in favor of SupportedFeatureSet. Adds IPv6 service network definition support
   184  		"37.1", // Adds support for Transparent Mode
   185  	},
   186  	//
   187  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServices: {
   188  		//"35.0", // Basic minimum required version
   189  		"37.0", // Adds IPv6 Virtual Service Support
   190  		"37.1", // Adds support for Transparent Mode
   191  	},
   192  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbVirtualServiceSummaries: {
   193  		//"35.0", // Basic minimum required version
   194  		"37.0", // Adds IPv6 Virtual Service Support
   195  		"37.1", // Adds support for Transparent Mode
   196  	},
   197  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcNetworkProfile: {
   198  		//"36.0", // Introduced support
   199  		"36.2", // 2 additional fields vappNetworkSegmentProfileTemplateRef and vdcNetworkSegmentProfileTemplateRef added
   200  	},
   201  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntityTypes: {
   202  		//"35.0", // Introduced support
   203  		"37.1", // Added MaxImplicitRight property in DefinedEntityType
   204  	},
   205  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointRdeEntities: {
   206  		//"35.0", // Introduced support
   207  		"37.0", // Added metadata support
   208  	},
   209  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways: {
   210  		//"35.0", // Introduced support
   211  		"37.1", // Exposes computed field `UsingIpSpace` in `types.EdgeGatewayUplinks`
   212  	},
   213  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGatewayDns: {
   214  		"37.0", // Introduced support
   215  		"38.0", // New field SnatRuleExternalIpAddress
   216  	},
   217  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceUplinksAllocate: {
   218  		//"37.1", // Introduced support
   219  		"37.2", // Adds 'value' field
   220  	},
   221  	types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces: {
   222  		//"37.1", // Introduced support
   223  		"38.0", // Adds 'DefaultGatewayServiceConfig' structure for firewall and NAT rule creation
   224  	},
   225  }
   226  
   227  // checkOpenApiEndpointCompatibility checks if VCD version (to which the client is connected) is sufficient to work with
   228  // specified OpenAPI endpoint and returns either an error or the Api version to use for calling that endpoint. This Api
   229  // version can then be supplied to low level OpenAPI client functions.
   230  // If the system default API version is higher than endpoint introduction version - default system one is used.
   231  func (client *Client) checkOpenApiEndpointCompatibility(endpoint string) (string, error) {
   232  	minimumApiVersion, ok := endpointMinApiVersions[endpoint]
   233  	if !ok {
   234  		return "", fmt.Errorf("minimum API version for endpoint '%s' is not defined", endpoint)
   235  	}
   236  
   237  	if client.APIVCDMaxVersionIs("< " + minimumApiVersion) {
   238  		maxSupportedVersion, err := client.MaxSupportedVersion()
   239  		if err != nil {
   240  			return "", fmt.Errorf("error reading maximum supported API version: %s", err)
   241  		}
   242  		return "", fmt.Errorf("endpoint '%s' requires API version to support at least '%s'. Maximum supported version in this instance: '%s'",
   243  			endpoint, minimumApiVersion, maxSupportedVersion)
   244  	}
   245  
   246  	// If default API version is higher than minimum required API version for endpoint - use the system default one.
   247  	if client.APIClientVersionIs("> " + minimumApiVersion) {
   248  		return client.APIVersion, nil
   249  	}
   250  
   251  	return minimumApiVersion, nil
   252  }
   253  
   254  // getOpenApiHighestElevatedVersion returns the highest supported API version for particular endpoint
   255  // These API versions must be defined in endpointElevatedApiVersions. If none are there - it will return minimum
   256  // supported API versions just like client.checkOpenApiEndpointCompatibility().
   257  //
   258  // The advantage of this function is that it provides a controlled API elevation instead of just picking the highest
   259  // which could be risky and untested (especially if new API version is released after release of package consuming this
   260  // SDK)
   261  func (client *Client) getOpenApiHighestElevatedVersion(endpoint string) (string, error) {
   262  	util.Logger.Printf("[DEBUG] Checking if elevated API versions are defined for endpoint '%s'", endpoint)
   263  
   264  	// At first get minimum API version and check if it can be supported
   265  	minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
   266  	if err != nil {
   267  		return "", fmt.Errorf("error getting minimum required API version: %s", err)
   268  	}
   269  
   270  	// If no elevated versions are defined - return minimumApiVersion
   271  	elevatedVersionSlice, elevatedVersionsDefined := endpointElevatedApiVersions[endpoint]
   272  	if !elevatedVersionsDefined {
   273  		util.Logger.Printf("[DEBUG] No elevated API versions are defined for endpoint '%s'. Using minimum '%s'",
   274  			endpoint, minimumApiVersion)
   275  		return minimumApiVersion, nil
   276  	}
   277  
   278  	util.Logger.Printf("[DEBUG] Found '%d' (%s) elevated API versions for endpoint '%s' ",
   279  		len(elevatedVersionSlice), strings.Join(elevatedVersionSlice, ", "), endpoint)
   280  
   281  	// Reverse sort (highest to lowest) slice of elevated API versions so that we can start by highest supported and go down
   282  	versionsRaw := elevatedVersionSlice
   283  	versions := make([]*version.Version, len(versionsRaw))
   284  	for i, raw := range versionsRaw {
   285  		v, err := version.NewVersion(raw)
   286  		if err != nil {
   287  			return "", fmt.Errorf("error evaluating version %s: %s", raw, err)
   288  		}
   289  		versions[i] = v
   290  	}
   291  	sort.Sort(sort.Reverse(version.Collection(versions)))
   292  
   293  	var supportedElevatedVersion string
   294  	// Loop highest to the lowest elevated versions and try to find highest from the list of supported ones
   295  	for _, elevatedVersion := range versions {
   296  
   297  		util.Logger.Printf("[DEBUG] Checking if elevated version '%s' is supported by VCD instance for endpoint '%s'",
   298  			elevatedVersion.Original(), endpoint)
   299  		// Check if maximum VCD API version supported is greater or equal to elevated version
   300  		if client.APIVCDMaxVersionIs(fmt.Sprintf(">= %s", elevatedVersion.Original())) {
   301  			util.Logger.Printf("[DEBUG] Elevated version '%s' is supported by VCD instance for endpoint '%s'",
   302  				elevatedVersion.Original(), endpoint)
   303  			// highest version found - store it and abort the loop
   304  			supportedElevatedVersion = elevatedVersion.Original()
   305  			break
   306  		}
   307  		util.Logger.Printf("[DEBUG] API version '%s' is not supported by VCD instance for endpoint '%s'",
   308  			elevatedVersion.Original(), endpoint)
   309  	}
   310  
   311  	if supportedElevatedVersion == "" {
   312  		util.Logger.Printf("[DEBUG] No elevated API versions are supported for endpoint '%s'. Will use minimum "+
   313  			"required version '%s'", endpoint, minimumApiVersion)
   314  		return minimumApiVersion, nil
   315  	}
   316  
   317  	util.Logger.Printf("[DEBUG] Will use elevated version '%s for endpoint '%s'",
   318  		supportedElevatedVersion, endpoint)
   319  	return supportedElevatedVersion, nil
   320  }