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

     1  /*
     2   * Copyright 2021 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     3   */
     4  
     5  package govcd
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"net/http"
    11  	"net/url"
    12  
    13  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    14  	"github.com/vmware/go-vcloud-director/v2/util"
    15  )
    16  
    17  // NsxtImportableSwitch is a read only object to retrieve NSX-T segments (importable switches) to be used for Org VDC
    18  // imported network.
    19  type NsxtImportableSwitch struct {
    20  	NsxtImportableSwitch *types.NsxtImportableSwitch
    21  	client               *Client
    22  }
    23  
    24  // GetNsxtImportableSwitchByName retrieves a particular NSX-T Segment by name available for that VDC
    25  //
    26  // Note. OpenAPI endpoint does not exist for this resource and by default endpoint
    27  // "/network/orgvdcnetworks/importableswitches" returns only unused NSX-T importable switches (the ones that are not
    28  // already consumed in Org VDC networks) and there is no way to get them all (including the used ones).
    29  func (vdc *Vdc) GetNsxtImportableSwitchByName(name string) (*NsxtImportableSwitch, error) {
    30  	if name == "" {
    31  		return nil, fmt.Errorf("empty NSX-T Importable Switch name specified")
    32  	}
    33  
    34  	allNsxtImportableSwitches, err := vdc.GetAllNsxtImportableSwitches()
    35  	if err != nil {
    36  		return nil, fmt.Errorf("error getting all NSX-T Importable Switches for VDC '%s': %s", vdc.Vdc.Name, err)
    37  	}
    38  
    39  	var filteredNsxtImportableSwitches []*NsxtImportableSwitch
    40  	for _, nsxtImportableSwitch := range allNsxtImportableSwitches {
    41  		if nsxtImportableSwitch.NsxtImportableSwitch.Name == name {
    42  			filteredNsxtImportableSwitches = append(filteredNsxtImportableSwitches, nsxtImportableSwitch)
    43  		}
    44  	}
    45  
    46  	if len(filteredNsxtImportableSwitches) == 0 {
    47  		// ErrorEntityNotFound is injected here for the ability to validate problem using ContainsNotFound()
    48  		return nil, fmt.Errorf("%s: no NSX-T Importable Switch with name '%s' for Org VDC with ID '%s' found",
    49  			ErrorEntityNotFound, name, vdc.Vdc.ID)
    50  	}
    51  
    52  	if len(filteredNsxtImportableSwitches) > 1 {
    53  		return nil, fmt.Errorf("more than one (%d) NSX-T Importable Switch with name '%s' for Org VDC with ID '%s' found",
    54  			len(filteredNsxtImportableSwitches), name, vdc.Vdc.ID)
    55  	}
    56  
    57  	return filteredNsxtImportableSwitches[0], nil
    58  }
    59  
    60  // GetNsxtImportableSwitchByName retrieves a particular NSX-T Segment by name available for that VDC
    61  //
    62  // Note. OpenAPI endpoint does not exist for this resource and by default endpoint
    63  // "/network/orgvdcnetworks/importableswitches" returns only unused NSX-T importable switches (the ones that are not
    64  // already consumed in Org VDC networks) and there is no way to get them all (including the used ones).
    65  func (vdcGroup *VdcGroup) GetNsxtImportableSwitchByName(name string) (*NsxtImportableSwitch, error) {
    66  	if name == "" {
    67  		return nil, fmt.Errorf("empty NSX-T Importable Switch name specified")
    68  	}
    69  
    70  	allNsxtImportableSwitches, err := vdcGroup.GetAllNsxtImportableSwitches()
    71  	if err != nil {
    72  		return nil, fmt.Errorf("error getting all NSX-T Importable Switches for VDC Group '%s': %s", vdcGroup.VdcGroup.Name, err)
    73  	}
    74  
    75  	var filteredNsxtImportableSwitches []*NsxtImportableSwitch
    76  	for _, nsxtImportableSwitch := range allNsxtImportableSwitches {
    77  		if nsxtImportableSwitch.NsxtImportableSwitch.Name == name {
    78  			filteredNsxtImportableSwitches = append(filteredNsxtImportableSwitches, nsxtImportableSwitch)
    79  		}
    80  	}
    81  
    82  	if len(filteredNsxtImportableSwitches) == 0 {
    83  		// ErrorEntityNotFound is injected here for the ability to validate problem using ContainsNotFound()
    84  		return nil, fmt.Errorf("%s: no NSX-T Importable Switch with name '%s' for VDC Group with ID '%s' found",
    85  			ErrorEntityNotFound, name, vdcGroup.VdcGroup.Id)
    86  	}
    87  
    88  	if len(filteredNsxtImportableSwitches) > 1 {
    89  		return nil, fmt.Errorf("more than one (%d) NSX-T Importable Switch with name '%s' for VDC Group with ID '%s' found",
    90  			len(filteredNsxtImportableSwitches), name, vdcGroup.VdcGroup.Id)
    91  	}
    92  
    93  	return filteredNsxtImportableSwitches[0], nil
    94  }
    95  
    96  // GetAllNsxtImportableSwitches retrieves all available importable switches which can be consumed for creating NSX-T
    97  // "Imported" Org VDC network
    98  //
    99  // Note. OpenAPI endpoint does not exist for this resource and by default endpoint
   100  // "/network/orgvdcnetworks/importableswitches" returns only unused NSX-T importable switches (the ones that are not
   101  // already consumed in Org VDC networks) and there is no way to get them all.
   102  func (vdcGroup *VdcGroup) GetAllNsxtImportableSwitches() ([]*NsxtImportableSwitch, error) {
   103  	if vdcGroup.VdcGroup.Id == "" {
   104  		return nil, fmt.Errorf("VDC Group must have ID populated to retrieve NSX-T importable switches")
   105  	}
   106  	// request requires Org VDC Group ID to be specified as UUID, not as URN
   107  	orgVdcGroupId, err := getBareEntityUuid(vdcGroup.VdcGroup.Id)
   108  	if err != nil {
   109  		return nil, fmt.Errorf("could not get UUID from URN '%s': %s", vdcGroup.VdcGroup.Id, err)
   110  	}
   111  	filter := map[string]string{"vdcGroup": orgVdcGroupId}
   112  
   113  	return getFilteredNsxtImportableSwitches(filter, vdcGroup.client)
   114  }
   115  
   116  // GetAllNsxtImportableSwitches retrieves all available importable switches which can be consumed for creating NSX-T
   117  // "Imported" Org VDC network
   118  //
   119  // Note. OpenAPI endpoint does not exist for this resource and by default endpoint
   120  // "/network/orgvdcnetworks/importableswitches" returns only unused NSX-T importable switches (the ones that are not
   121  // already consumed in Org VDC networks) and there is no way to get them all.
   122  func (vdc *Vdc) GetAllNsxtImportableSwitches() ([]*NsxtImportableSwitch, error) {
   123  	if vdc.Vdc.ID == "" {
   124  		return nil, fmt.Errorf("VDC must have ID populated to retrieve NSX-T importable switches")
   125  	}
   126  	// request requires Org VDC ID to be specified as UUID, not as URN
   127  	orgVdcId, err := getBareEntityUuid(vdc.Vdc.ID)
   128  	if err != nil {
   129  		return nil, fmt.Errorf("could not get UUID from URN '%s': %s", vdc.Vdc.ID, err)
   130  	}
   131  	filter := map[string]string{"orgVdc": orgVdcId}
   132  
   133  	return getFilteredNsxtImportableSwitches(filter, vdc.client)
   134  }
   135  
   136  // GetFilteredNsxtImportableSwitches returns all available importable switches.
   137  // One of the filters below is required (using plain UUID - not URN):
   138  // * orgVdc
   139  // * nsxTManager (only in VCD 10.3.0+)
   140  //
   141  // Note. OpenAPI endpoint does not exist for this resource and by default endpoint
   142  // "/network/orgvdcnetworks/importableswitches" returns only unused NSX-T importable switches (the ones that are not
   143  // already consumed in Org VDC networks) and there is no way to get them all.
   144  func (vcdClient *VCDClient) GetFilteredNsxtImportableSwitches(filter map[string]string) ([]*NsxtImportableSwitch, error) {
   145  	return getFilteredNsxtImportableSwitches(filter, &vcdClient.Client)
   146  }
   147  
   148  // GetFilteredNsxtImportableSwitchesByName builds on top of GetFilteredNsxtImportableSwitches and additionally performs
   149  // client side filtering by Name
   150  func (vcdClient *VCDClient) GetFilteredNsxtImportableSwitchesByName(filter map[string]string, name string) (*NsxtImportableSwitch, error) {
   151  	importableSwitches, err := getFilteredNsxtImportableSwitches(filter, &vcdClient.Client)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("error getting list of filtered Importable Switches: %s", err)
   154  	}
   155  
   156  	var foundImportableSwitch bool
   157  	var foundSwitches []*NsxtImportableSwitch
   158  
   159  	for index, impSwitch := range importableSwitches {
   160  		if importableSwitches[index].NsxtImportableSwitch.Name == name {
   161  			foundImportableSwitch = true
   162  			foundSwitches = append(foundSwitches, impSwitch)
   163  		}
   164  	}
   165  
   166  	if !foundImportableSwitch {
   167  		return nil, fmt.Errorf("%s: Importable Switch with name '%s' not found", ErrorEntityNotFound, name)
   168  	}
   169  
   170  	if len(foundSwitches) > 1 {
   171  		return nil, fmt.Errorf("found multiple Importable Switches with name '%s'", name)
   172  	}
   173  
   174  	return foundSwitches[0], nil
   175  }
   176  
   177  // getFilteredNsxtImportableSwitches is extracted so that it can be reused across multiple functions
   178  func getFilteredNsxtImportableSwitches(filter map[string]string, client *Client) ([]*NsxtImportableSwitch, error) {
   179  	apiEndpoint := client.VCDHREF
   180  	endpoint := apiEndpoint.Scheme + "://" + apiEndpoint.Host + "/network/orgvdcnetworks/importableswitches/"
   181  	// error below is ignored because it is a static endpoint
   182  	urlRef, err := url.Parse(endpoint)
   183  	if err != nil {
   184  		util.Logger.Printf("[DEBUG - getFilteredNsxtImportableSwitches] error parsing URL: %s", err)
   185  	}
   186  
   187  	headAccept := http.Header{}
   188  	headAccept.Set("Accept", types.JSONMime)
   189  	request := client.newRequest(filter, nil, http.MethodGet, *urlRef, nil, client.APIVersion, headAccept)
   190  	request.Header.Set("Accept", types.JSONMime)
   191  
   192  	response, err := checkResp(client.Http.Do(request))
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	defer func(Body io.ReadCloser) {
   197  		err := Body.Close()
   198  		if err != nil {
   199  			util.Logger.Printf("error closing response Body [getFilteredNsxtImportableSwitches]: %s", err)
   200  		}
   201  	}(response.Body)
   202  
   203  	var nsxtImportableSwitches []*types.NsxtImportableSwitch
   204  	if err = decodeBody(types.BodyTypeJSON, response, &nsxtImportableSwitches); err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	wrappedNsxtImportableSwitches := make([]*NsxtImportableSwitch, len(nsxtImportableSwitches))
   209  	for sliceIndex := range nsxtImportableSwitches {
   210  		wrappedNsxtImportableSwitches[sliceIndex] = &NsxtImportableSwitch{
   211  			NsxtImportableSwitch: nsxtImportableSwitches[sliceIndex],
   212  			client:               client,
   213  		}
   214  	}
   215  
   216  	return wrappedNsxtImportableSwitches, nil
   217  }