github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/nsxt_edgegateway_bgp_ip_prefix_list.go (about) 1 /* 2 * Copyright 2022 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 3 */ 4 5 package govcd 6 7 import ( 8 "fmt" 9 "net/url" 10 11 "github.com/vmware/go-vcloud-director/v2/types/v56" 12 ) 13 14 // EdgeBgpIpPrefixList helps to configure BGP IP Prefix Lists in NSX-T Edge Gateways 15 type EdgeBgpIpPrefixList struct { 16 EdgeBgpIpPrefixList *types.EdgeBgpIpPrefixList 17 client *Client 18 // edgeGatewayId is stored for usage in EdgeBgpIpPrefixList receiver functions 19 edgeGatewayId string 20 } 21 22 // CreateBgpIpPrefixList creates a BGP IP Prefix List with supplied configuration 23 // 24 // Note. VCD 10.2 versions do not automatically return ID for created BGP IP Prefix List. To work around it this code 25 // automatically retrieves the entity by Name after the task is finished. This function may fail on VCD 10.2 if 26 // duplicate BGP IP Prefix Lists exist. 27 func (egw *NsxtEdgeGateway) CreateBgpIpPrefixList(bgpIpPrefixList *types.EdgeBgpIpPrefixList) (*EdgeBgpIpPrefixList, error) { 28 client := egw.client 29 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists 30 apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) 31 if err != nil { 32 return nil, err 33 } 34 35 // Insert Edge Gateway ID into endpoint path 36 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID)) 37 if err != nil { 38 return nil, err 39 } 40 41 returnObject := &EdgeBgpIpPrefixList{ 42 client: egw.client, 43 edgeGatewayId: egw.EdgeGateway.ID, 44 EdgeBgpIpPrefixList: &types.EdgeBgpIpPrefixList{}, 45 } 46 47 task, err := client.OpenApiPostItemAsync(apiVersion, urlRef, nil, bgpIpPrefixList) 48 if err != nil { 49 return nil, fmt.Errorf("error creating NSX-T Edge Gateway BGP IP Prefix List: %s", err) 50 } 51 52 err = task.WaitTaskCompletion() 53 if err != nil { 54 return nil, fmt.Errorf("error creating NSX-T Edge Gateway BGP IP Prefix List: %s", err) 55 } 56 57 // API is not consistent across different versions therefore explicit manual handling is 58 // required to lookup newly created object 59 // 60 // VCD 10.2 -> no ID for newly created object is returned at all 61 // VCD 10.3 -> `Details` field in task contains ID of newly created object 62 // To cover all cases this code will at first look for ID in `Details` field and fall back to 63 // lookup by name if `Details` field is empty. 64 // 65 // The drawback of this is that it is possible to create duplicate records with the same name on 66 // VCD versions that don't return IDs, but there is no better way for VCD versions that don't 67 // return IDs for created objects 68 69 bgpIpPrefixListId := task.Task.Details 70 if bgpIpPrefixListId != "" { 71 getUrlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID), bgpIpPrefixListId) 72 if err != nil { 73 return nil, err 74 } 75 err = client.OpenApiGetItem(apiVersion, getUrlRef, nil, returnObject.EdgeBgpIpPrefixList, nil) 76 if err != nil { 77 return nil, fmt.Errorf("error retrieving NSX-T Edge Gateway BGP IP Prefix List after creation: %s", err) 78 } 79 } else { 80 // ID after object creation was not returned therefore retrieving the entity by Name to lookup ID 81 // This has a risk of duplicate items, but is the only way to find the object when ID is not returned 82 bgpIpPrefixList, err := egw.GetBgpIpPrefixListByName(bgpIpPrefixList.Name) 83 if err != nil { 84 return nil, fmt.Errorf("error retrieving NSX-T Edge Gateway BGP IP Prefix List after creation: %s", err) 85 } 86 returnObject = bgpIpPrefixList 87 } 88 89 return returnObject, nil 90 } 91 92 // GetAllBgpIpPrefixLists retrieves all BGP IP Prefix Lists in a given NSX-T Edge Gateway with optional queryParameters 93 func (egw *NsxtEdgeGateway) GetAllBgpIpPrefixLists(queryParameters url.Values) ([]*EdgeBgpIpPrefixList, error) { 94 queryParams := copyOrNewUrlValues(queryParameters) 95 96 client := egw.client 97 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists 98 apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) 99 if err != nil { 100 return nil, err 101 } 102 103 // Insert Edge Gateway ID into endpoint path 104 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID)) 105 if err != nil { 106 return nil, err 107 } 108 109 typeResponses := []*types.EdgeBgpIpPrefixList{{}} 110 err = client.OpenApiGetAllItems(apiVersion, urlRef, queryParams, &typeResponses, nil) 111 if err != nil { 112 return nil, err 113 } 114 115 // Wrap all typeResponses into NsxtNatRule types with client 116 wrappedResponses := make([]*EdgeBgpIpPrefixList, len(typeResponses)) 117 for sliceIndex := range typeResponses { 118 wrappedResponses[sliceIndex] = &EdgeBgpIpPrefixList{ 119 EdgeBgpIpPrefixList: typeResponses[sliceIndex], 120 client: client, 121 edgeGatewayId: egw.EdgeGateway.ID, 122 } 123 } 124 125 return wrappedResponses, nil 126 } 127 128 // GetBgpIpPrefixListByName retrieves BGP IP Prefix List By Name 129 // It is meant to retrieve exactly one entry: 130 // * Will fail if more than one entry with the same name found 131 // * Will return an error containing `ErrorEntityNotFound` if no entries are found 132 // 133 // Note. API does not support filtering by 'name' field therefore filtering is performed on client 134 // side 135 func (egw *NsxtEdgeGateway) GetBgpIpPrefixListByName(name string) (*EdgeBgpIpPrefixList, error) { 136 if name == "" { 137 return nil, fmt.Errorf("name cannot be empty") 138 } 139 140 allBgpIpPrefixLists, err := egw.GetAllBgpIpPrefixLists(nil) 141 if err != nil { 142 return nil, fmt.Errorf("error retrieving NSX-T Edge Gateway BGP IP Prefix List: %s", err) 143 } 144 145 var filteredBgpIpPrefixLists []*EdgeBgpIpPrefixList 146 for _, bgpIpPrefixList := range allBgpIpPrefixLists { 147 if bgpIpPrefixList.EdgeBgpIpPrefixList.Name == name { 148 filteredBgpIpPrefixLists = append(filteredBgpIpPrefixLists, bgpIpPrefixList) 149 } 150 } 151 152 if len(filteredBgpIpPrefixLists) > 1 { 153 return nil, fmt.Errorf("more than one NSX-T Edge Gateway BGP IP Prefix List found with Name '%s'", name) 154 } 155 156 if len(filteredBgpIpPrefixLists) == 0 { 157 return nil, fmt.Errorf("%s: no NSX-T Edge Gateway BGP IP Prefix List found with name '%s'", ErrorEntityNotFound, name) 158 } 159 160 return filteredBgpIpPrefixLists[0], nil 161 } 162 163 // GetBgpIpPrefixListById retrieves BGP IP Prefix List By ID 164 func (egw *NsxtEdgeGateway) GetBgpIpPrefixListById(id string) (*EdgeBgpIpPrefixList, error) { 165 if id == "" { 166 return nil, fmt.Errorf("id is required") 167 } 168 169 client := egw.client 170 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists 171 apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) 172 if err != nil { 173 return nil, err 174 } 175 176 // Insert Edge Gateway ID into endpoint path 177 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, egw.EdgeGateway.ID), id) 178 if err != nil { 179 return nil, err 180 } 181 182 returnObject := &EdgeBgpIpPrefixList{ 183 client: egw.client, 184 edgeGatewayId: egw.EdgeGateway.ID, 185 EdgeBgpIpPrefixList: &types.EdgeBgpIpPrefixList{}, 186 } 187 188 err = client.OpenApiGetItem(apiVersion, urlRef, nil, returnObject.EdgeBgpIpPrefixList, nil) 189 if err != nil { 190 return nil, fmt.Errorf("error retrieving NSX-T Edge Gateway BGP IP Prefix List: %s", err) 191 } 192 193 return returnObject, nil 194 } 195 196 // Update updates existing BGP IP Prefix List with new configuration and returns it 197 func (bgpIpPrefixListCfg *EdgeBgpIpPrefixList) Update(bgpIpPrefixList *types.EdgeBgpIpPrefixList) (*EdgeBgpIpPrefixList, error) { 198 client := bgpIpPrefixListCfg.client 199 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists 200 apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) 201 if err != nil { 202 return nil, err 203 } 204 205 // Insert Edge Gateway ID into endpoint path 206 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, bgpIpPrefixListCfg.edgeGatewayId), bgpIpPrefixList.ID) 207 if err != nil { 208 return nil, err 209 } 210 211 returnObject := &EdgeBgpIpPrefixList{ 212 client: bgpIpPrefixListCfg.client, 213 edgeGatewayId: bgpIpPrefixListCfg.edgeGatewayId, 214 EdgeBgpIpPrefixList: &types.EdgeBgpIpPrefixList{}, 215 } 216 217 err = client.OpenApiPutItem(apiVersion, urlRef, nil, bgpIpPrefixList, returnObject.EdgeBgpIpPrefixList, nil) 218 if err != nil { 219 return nil, fmt.Errorf("error setting NSX-T Edge Gateway BGP IP Prefix List: %s", err) 220 } 221 222 return returnObject, nil 223 } 224 225 // Delete deletes existing BGP IP Prefix List 226 func (bgpIpPrefixListCfg *EdgeBgpIpPrefixList) Delete() error { 227 client := bgpIpPrefixListCfg.client 228 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeBgpConfigPrefixLists 229 apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) 230 if err != nil { 231 return err 232 } 233 234 // Insert Edge Gateway ID into endpoint path 235 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, bgpIpPrefixListCfg.edgeGatewayId), bgpIpPrefixListCfg.EdgeBgpIpPrefixList.ID) 236 if err != nil { 237 return err 238 } 239 240 err = client.OpenApiDeleteItem(apiVersion, urlRef, nil, nil) 241 if err != nil { 242 return fmt.Errorf("error deleting NSX-T Edge Gateway BGP IP Prefix List: %s", err) 243 } 244 245 return nil 246 }