github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/nsxt_firewall_group.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  	"errors"
     9  	"fmt"
    10  	"net/url"
    11  
    12  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    13  )
    14  
    15  // NsxtFirewallGroup uses OpenAPI endpoint to operate NSX-T Security Groups and IP Sets which use
    16  // the same Firewall Group API endpoint
    17  //
    18  // IP sets are groups of objects to which the firewall rules apply. Combining multiple objects into
    19  // IP sets helps reduce the total number of firewall rules to be created.
    20  //
    21  // Security groups are groups of Org Vdc networks to which distributed firewall rules apply.
    22  // Grouping networks helps you to reduce the total number of distributed firewall rules to be
    23  // created.
    24  type NsxtFirewallGroup struct {
    25  	NsxtFirewallGroup *types.NsxtFirewallGroup
    26  	client            *Client
    27  }
    28  
    29  // CreateNsxtFirewallGroup allows users to create NSX-T Firewall Group
    30  func (vdc *Vdc) CreateNsxtFirewallGroup(firewallGroupConfig *types.NsxtFirewallGroup) (*NsxtFirewallGroup, error) {
    31  	return createNsxtFirewallGroup(vdc.client, firewallGroupConfig)
    32  }
    33  
    34  // CreateNsxtFirewallGroup allows users to create NSX-T Firewall Group
    35  func (egw *NsxtEdgeGateway) CreateNsxtFirewallGroup(firewallGroupConfig *types.NsxtFirewallGroup) (*NsxtFirewallGroup, error) {
    36  	return createNsxtFirewallGroup(egw.client, firewallGroupConfig)
    37  }
    38  
    39  // CreateNsxtFirewallGroup allows users to create NSX-T Firewall Group
    40  func (vdcGroup *VdcGroup) CreateNsxtFirewallGroup(firewallGroupConfig *types.NsxtFirewallGroup) (*NsxtFirewallGroup, error) {
    41  	return createNsxtFirewallGroup(vdcGroup.client, firewallGroupConfig)
    42  }
    43  
    44  // GetAllNsxtFirewallGroups allows users to retrieve all Firewall Groups for Org
    45  // firewallGroupType can be one of the following:
    46  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Security Groups
    47  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
    48  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
    49  //
    50  // It is possible to add additional filtering by using queryParameters of type 'url.Values'.
    51  // One special filter is `_context==` filtering. Value can be one of the following:
    52  //
    53  // * Org Vdc Network ID (_context==networkId) - Returns all the firewall groups which the specified
    54  // network is a member of.
    55  //
    56  // * Edge Gateway ID (_context==edgeGatewayId) - Returns all the firewall groups which are available
    57  // to the specific edge gateway. Or use a shorthand NsxtEdgeGateway.GetAllNsxtFirewallGroups() which
    58  // automatically injects this filter.
    59  //
    60  // * Network Provider ID (_context==networkProviderId) - Returns all the firewall groups which are
    61  // available under a specific network provider. This context requires system admin privilege.
    62  // 'networkProviderId' is NSX-T manager ID
    63  func (org *Org) GetAllNsxtFirewallGroups(queryParameters url.Values, firewallGroupType string) ([]*NsxtFirewallGroup, error) {
    64  	queryParams := copyOrNewUrlValues(queryParameters)
    65  	if firewallGroupType != "" {
    66  		queryParams = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
    67  	}
    68  
    69  	return getAllNsxtFirewallGroups(org.client, queryParams)
    70  }
    71  
    72  // GetAllNsxtFirewallGroups allows users to retrieve all NSX-T Firewall Groups
    73  func (vdc *Vdc) GetAllNsxtFirewallGroups(queryParameters url.Values, firewallGroupType string) ([]*NsxtFirewallGroup, error) {
    74  	if vdc.IsNsxv() {
    75  		return nil, errors.New("only NSX-T VDCs support Firewall Groups")
    76  	}
    77  	return getAllNsxtFirewallGroups(vdc.client, queryParameters)
    78  }
    79  
    80  // GetAllNsxtFirewallGroups allows users to retrieve all NSX-T Firewall Groups in a particular Edge Gateway
    81  // firewallGroupType can be one of the following:
    82  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Security Groups
    83  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
    84  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
    85  func (egw *NsxtEdgeGateway) GetAllNsxtFirewallGroups(queryParameters url.Values, firewallGroupType string) ([]*NsxtFirewallGroup, error) {
    86  	queryParams := copyOrNewUrlValues(queryParameters)
    87  
    88  	if firewallGroupType != "" {
    89  		queryParams = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
    90  	}
    91  
    92  	// Automatically inject Edge Gateway filter because this is an Edge Gateway scoped query
    93  	queryParams = queryParameterFilterAnd("_context=="+egw.EdgeGateway.ID, queryParams)
    94  
    95  	return getAllNsxtFirewallGroups(egw.client, queryParams)
    96  }
    97  
    98  // GetNsxtFirewallGroupByName allows users to retrieve Firewall Group by Name
    99  // firewallGroupType can be one of the following:
   100  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Security Groups
   101  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
   102  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
   103  //
   104  // Note. One might get an error if IP Set and Security Group exist with the same name (two objects
   105  // of the same type cannot exist) and firewallGroupType is left empty.
   106  func (org *Org) GetNsxtFirewallGroupByName(name, firewallGroupType string) (*NsxtFirewallGroup, error) {
   107  	queryParameters := url.Values{}
   108  	if firewallGroupType != "" {
   109  		queryParameters = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
   110  	}
   111  
   112  	return getNsxtFirewallGroupByName(org.client, name, queryParameters)
   113  }
   114  
   115  // GetNsxtFirewallGroupByName allows users to retrieve Firewall Group by Name
   116  // firewallGroupType can be one of the following:
   117  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Security Groups
   118  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
   119  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
   120  //
   121  // Note. One might get an error if IP Set and Security Group exist with the same name (two objects
   122  // of the same type cannot exist) and firewallGroupType is left empty.
   123  func (vdc *Vdc) GetNsxtFirewallGroupByName(name, firewallGroupType string) (*NsxtFirewallGroup, error) {
   124  
   125  	queryParameters := url.Values{}
   126  	if firewallGroupType != "" {
   127  		queryParameters = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
   128  	}
   129  	return getNsxtFirewallGroupByName(vdc.client, name, queryParameters)
   130  }
   131  
   132  // GetNsxtFirewallGroupByName allows users to retrieve Firewall Group by Name in a particular VDC Group
   133  // firewallGroupType can be one of the following:
   134  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Static Security Groups
   135  // * types.FirewallGroupTypeVmCriteria - for NSX-T Dynamic Security Groups
   136  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
   137  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
   138  //
   139  // Note. One might get an error if IP Set and Security Group exist with the same name (two objects
   140  // of the same type cannot exist) and firewallGroupType is left empty.
   141  func (vdcGroup *VdcGroup) GetNsxtFirewallGroupByName(name string, firewallGroupType string) (*NsxtFirewallGroup, error) {
   142  	queryParameters := url.Values{}
   143  
   144  	if firewallGroupType != "" {
   145  		queryParameters = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
   146  	}
   147  
   148  	// Automatically inject Edge Gateway filter because this is an Edge Gateway scoped query
   149  	queryParameters = queryParameterFilterAnd("ownerRef.id=="+vdcGroup.VdcGroup.Id, queryParameters)
   150  
   151  	return getNsxtFirewallGroupByName(vdcGroup.client, name, queryParameters)
   152  }
   153  
   154  // GetNsxtFirewallGroupByName allows users to retrieve Firewall Group by Name in a particular Edge Gateway
   155  // firewallGroupType can be one of the following:
   156  // * types.FirewallGroupTypeSecurityGroup - for NSX-T Security Groups
   157  // * types.FirewallGroupTypeIpSet - for NSX-T IP Sets
   158  // * "" (empty) - search will not be limited and will get both - IP Sets and Security Groups
   159  //
   160  // Note. One might get an error if IP Set and Security Group exist with the same name (two objects
   161  // of the same type cannot exist) and firewallGroupType is left empty.
   162  func (egw *NsxtEdgeGateway) GetNsxtFirewallGroupByName(name string, firewallGroupType string) (*NsxtFirewallGroup, error) {
   163  	queryParameters := url.Values{}
   164  
   165  	if firewallGroupType != "" {
   166  		queryParameters = queryParameterFilterAnd(fmt.Sprintf("typeValue==%s", firewallGroupType), queryParameters)
   167  	}
   168  
   169  	// Automatically inject Edge Gateway filter because this is an Edge Gateway scoped query
   170  	queryParameters = queryParameterFilterAnd("_context=="+egw.EdgeGateway.ID, queryParameters)
   171  
   172  	return getNsxtFirewallGroupByName(egw.client, name, queryParameters)
   173  }
   174  
   175  // GetNsxtFirewallGroupById retrieves NSX-T Firewall Group by ID
   176  func (org *Org) GetNsxtFirewallGroupById(id string) (*NsxtFirewallGroup, error) {
   177  	return getNsxtFirewallGroupById(org.client, id)
   178  }
   179  
   180  // GetNsxtFirewallGroupById retrieves NSX-T Firewall Group by ID
   181  func (vdc *Vdc) GetNsxtFirewallGroupById(id string) (*NsxtFirewallGroup, error) {
   182  	return getNsxtFirewallGroupById(vdc.client, id)
   183  }
   184  
   185  // GetNsxtFirewallGroupById retrieves NSX-T Firewall Group by ID
   186  func (egw *NsxtEdgeGateway) GetNsxtFirewallGroupById(id string) (*NsxtFirewallGroup, error) {
   187  	return getNsxtFirewallGroupById(egw.client, id)
   188  }
   189  
   190  // GetNsxtFirewallGroupById retrieves NSX-T Firewall Group by ID
   191  func (vdcGroup *VdcGroup) GetNsxtFirewallGroupById(id string) (*NsxtFirewallGroup, error) {
   192  	return getNsxtFirewallGroupById(vdcGroup.client, id)
   193  }
   194  
   195  // Update allows users to update NSX-T Firewall Group
   196  func (firewallGroup *NsxtFirewallGroup) Update(firewallGroupConfig *types.NsxtFirewallGroup) (*NsxtFirewallGroup, error) {
   197  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   198  	apiVersion, err := firewallGroup.client.getOpenApiHighestElevatedVersion(endpoint)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	if firewallGroupConfig.ID == "" {
   204  		return nil, fmt.Errorf("cannot update NSX-T Firewall Group without ID")
   205  	}
   206  
   207  	urlRef, err := firewallGroup.client.OpenApiBuildEndpoint(endpoint, firewallGroupConfig.ID)
   208  	if err != nil {
   209  		return nil, err
   210  	}
   211  
   212  	returnObject := &NsxtFirewallGroup{
   213  		NsxtFirewallGroup: &types.NsxtFirewallGroup{},
   214  		client:            firewallGroup.client,
   215  	}
   216  
   217  	err = firewallGroup.client.OpenApiPutItem(apiVersion, urlRef, nil, firewallGroupConfig, returnObject.NsxtFirewallGroup, nil)
   218  	if err != nil {
   219  		return nil, fmt.Errorf("error updating NSX-T firewall group: %s", err)
   220  	}
   221  
   222  	return returnObject, nil
   223  }
   224  
   225  // Delete allows users to delete NSX-T Firewall Group
   226  func (firewallGroup *NsxtFirewallGroup) Delete() error {
   227  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   228  	apiVersion, err := firewallGroup.client.getOpenApiHighestElevatedVersion(endpoint)
   229  	if err != nil {
   230  		return err
   231  	}
   232  
   233  	if firewallGroup.NsxtFirewallGroup.ID == "" {
   234  		return fmt.Errorf("cannot delete NSX-T Firewall Group without ID")
   235  	}
   236  
   237  	urlRef, err := firewallGroup.client.OpenApiBuildEndpoint(endpoint, firewallGroup.NsxtFirewallGroup.ID)
   238  	if err != nil {
   239  		return err
   240  	}
   241  
   242  	err = firewallGroup.client.OpenApiDeleteItem(apiVersion, urlRef, nil, nil)
   243  
   244  	if err != nil {
   245  		return fmt.Errorf("error deleting NSX-T Firewall Group: %s", err)
   246  	}
   247  
   248  	return nil
   249  }
   250  
   251  // GetAssociatedVms allows users to retrieve a list of references to child VMs (with vApps when they exist).
   252  //
   253  // Note. Only Security Groups have associated VMs. Executing it on an IP Set will return an error
   254  // similar to: "only Security Groups have associated VMs. This Firewall Group has type 'IP_SET'"
   255  func (firewallGroup *NsxtFirewallGroup) GetAssociatedVms() ([]*types.NsxtFirewallGroupMemberVms, error) {
   256  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   257  	apiVersion, err := firewallGroup.client.getOpenApiHighestElevatedVersion(endpoint)
   258  	if err != nil {
   259  		return nil, err
   260  	}
   261  
   262  	if firewallGroup.NsxtFirewallGroup.ID == "" {
   263  		return nil, fmt.Errorf("cannot retrieve associated VMs for NSX-T Firewall Group without ID")
   264  	}
   265  
   266  	if !firewallGroup.IsSecurityGroup() && !firewallGroup.IsDynamicSecurityGroup() {
   267  		return nil, fmt.Errorf("only Security Groups have associated VMs. This Firewall Group has type '%s'",
   268  			firewallGroup.NsxtFirewallGroup.Type)
   269  	}
   270  
   271  	urlRef, err := firewallGroup.client.OpenApiBuildEndpoint(endpoint, firewallGroup.NsxtFirewallGroup.ID, "/associatedVMs")
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  
   276  	associatedVms := []*types.NsxtFirewallGroupMemberVms{{}}
   277  
   278  	err = firewallGroup.client.OpenApiGetAllItems(apiVersion, urlRef, nil, &associatedVms, nil)
   279  
   280  	if err != nil {
   281  		return nil, fmt.Errorf("error retrieving associated VMs: %s", err)
   282  	}
   283  
   284  	return associatedVms, nil
   285  }
   286  
   287  // IsSecurityGroup allows users to check if Firewall Group is a Static Security Group
   288  func (firewallGroup *NsxtFirewallGroup) IsSecurityGroup() bool {
   289  	return firewallGroup.NsxtFirewallGroup.Type == types.FirewallGroupTypeSecurityGroup
   290  }
   291  
   292  // IsDynamicSecurityGroup allows users to check if Firewall Group is a Dynamic Security Group
   293  func (firewallGroup *NsxtFirewallGroup) IsDynamicSecurityGroup() bool {
   294  	return firewallGroup.NsxtFirewallGroup.TypeValue == types.FirewallGroupTypeVmCriteria
   295  }
   296  
   297  // IsIpSet allows users to check if Firewall Group is an IP Set
   298  func (firewallGroup *NsxtFirewallGroup) IsIpSet() bool {
   299  	return firewallGroup.NsxtFirewallGroup.Type == types.FirewallGroupTypeIpSet
   300  }
   301  
   302  func getNsxtFirewallGroupByName(client *Client, name string, queryParameters url.Values) (*NsxtFirewallGroup, error) {
   303  	queryParams := copyOrNewUrlValues(queryParameters)
   304  	queryParams = queryParameterFilterAnd("name=="+name, queryParams)
   305  
   306  	allGroups, err := getAllNsxtFirewallGroups(client, queryParams)
   307  	if err != nil {
   308  		return nil, fmt.Errorf("could not find NSX-T Firewall Group with name '%s': %s", name, err)
   309  	}
   310  
   311  	if len(allGroups) == 0 {
   312  		return nil, fmt.Errorf("%s: expected exactly one NSX-T Firewall Group with name '%s'. Got %d", ErrorEntityNotFound, name, len(allGroups))
   313  	}
   314  
   315  	if len(allGroups) > 1 {
   316  		return nil, fmt.Errorf("expected exactly one NSX-T Firewall Group with name '%s'. Got %d", name, len(allGroups))
   317  	}
   318  
   319  	// TODO API V36.0 - maybe it is fixed
   320  	// There is a bug that not all data is present (e.g. missing IpAddresses field for IP_SET) when
   321  	// using "getAll" endpoint therefore after finding the object by name we must retrieve it once
   322  	// again using its direct endpoint.
   323  	//
   324  	// return allGroups[0], nil
   325  
   326  	return getNsxtFirewallGroupById(client, allGroups[0].NsxtFirewallGroup.ID)
   327  }
   328  
   329  func getNsxtFirewallGroupById(client *Client, id string) (*NsxtFirewallGroup, error) {
   330  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   331  	apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
   332  	if err != nil {
   333  		return nil, err
   334  	}
   335  
   336  	if id == "" {
   337  		return nil, fmt.Errorf("empty NSX-T Firewall Group ID specified")
   338  	}
   339  
   340  	urlRef, err := client.OpenApiBuildEndpoint(endpoint, id)
   341  	if err != nil {
   342  		return nil, err
   343  	}
   344  
   345  	fwGroup := &NsxtFirewallGroup{
   346  		NsxtFirewallGroup: &types.NsxtFirewallGroup{},
   347  		client:            client,
   348  	}
   349  
   350  	err = client.OpenApiGetItem(apiVersion, urlRef, nil, fwGroup.NsxtFirewallGroup, nil)
   351  	if err != nil {
   352  		return nil, err
   353  	}
   354  
   355  	return fwGroup, nil
   356  }
   357  
   358  func getAllNsxtFirewallGroups(client *Client, queryParameters url.Values) ([]*NsxtFirewallGroup, error) {
   359  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   360  	apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  
   365  	// This Object does not follow regular REST scheme and for get the endpoint must be
   366  	// 1.0.0/firewallGroups/summaries therefore bellow "summaries" is appended to the path
   367  	urlRef, err := client.OpenApiBuildEndpoint(endpoint, "summaries")
   368  	if err != nil {
   369  		return nil, err
   370  	}
   371  
   372  	typeResponses := []*types.NsxtFirewallGroup{{}}
   373  	err = client.OpenApiGetAllItems(apiVersion, urlRef, queryParameters, &typeResponses, nil)
   374  	if err != nil {
   375  		return nil, err
   376  	}
   377  
   378  	// Wrap all typeResponses into NsxtEdgeGateway types with client
   379  	wrappedResponses := make([]*NsxtFirewallGroup, len(typeResponses))
   380  	for sliceIndex := range typeResponses {
   381  		wrappedResponses[sliceIndex] = &NsxtFirewallGroup{
   382  			NsxtFirewallGroup: typeResponses[sliceIndex],
   383  			client:            client,
   384  		}
   385  	}
   386  
   387  	return wrappedResponses, nil
   388  }
   389  
   390  func createNsxtFirewallGroup(client *Client, firewallGroupConfig *types.NsxtFirewallGroup) (*NsxtFirewallGroup, error) {
   391  	endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointFirewallGroups
   392  	apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint)
   393  	if err != nil {
   394  		return nil, err
   395  	}
   396  
   397  	urlRef, err := client.OpenApiBuildEndpoint(endpoint)
   398  	if err != nil {
   399  		return nil, err
   400  	}
   401  
   402  	returnObject := &NsxtFirewallGroup{
   403  		NsxtFirewallGroup: &types.NsxtFirewallGroup{},
   404  		client:            client,
   405  	}
   406  
   407  	err = client.OpenApiPostItem(apiVersion, urlRef, nil, firewallGroupConfig, returnObject.NsxtFirewallGroup, nil)
   408  	if err != nil {
   409  		return nil, fmt.Errorf("error creating NSX-T Firewall Group: %s", err)
   410  	}
   411  
   412  	return returnObject, nil
   413  }