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  }