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