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