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 }