github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/nsxv_distributed_firewall_test.go (about)

     1  //go:build functional || network || ALL
     2  
     3  /*
     4   * Copyright 2023 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     5   */
     6  package govcd
     7  
     8  import (
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/kr/pretty"
    13  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    14  	. "gopkg.in/check.v1"
    15  )
    16  
    17  func (vcd *TestVCD) Test_NsxvDistributedFirewall(check *C) {
    18  	fmt.Printf("Running: %s\n", check.TestName())
    19  
    20  	org, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
    21  	check.Assert(err, IsNil)
    22  	check.Assert(org, NotNil)
    23  
    24  	if vcd.config.VCD.Nsxt.Vdc != "" {
    25  		if testVerbose {
    26  			fmt.Println("Testing attempted access to NSX-T VDC")
    27  		}
    28  		// Retrieve a NSX-T VDC
    29  		nsxtVdc, err := org.GetAdminVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
    30  		check.Assert(err, IsNil)
    31  
    32  		notWorkingDfw := NewNsxvDistributedFirewall(nsxtVdc.client, nsxtVdc.AdminVdc.ID)
    33  		check.Assert(notWorkingDfw, NotNil)
    34  
    35  		isEnabled, err := notWorkingDfw.IsEnabled()
    36  		check.Assert(err, IsNil)
    37  		check.Assert(isEnabled, Equals, false)
    38  
    39  		err = notWorkingDfw.Enable()
    40  		// NSX-T VDCs don't support NSX-V distributed firewalls. We expect an error here.
    41  		check.Assert(err, NotNil)
    42  		check.Assert(strings.Contains(err.Error(), "Forbidden"), Equals, true)
    43  		if testVerbose {
    44  			fmt.Printf("notWorkingDfw: %s\n", err)
    45  		}
    46  		config, err := notWorkingDfw.GetConfiguration()
    47  		// Also this operation should fail
    48  		check.Assert(err, NotNil)
    49  		check.Assert(config, IsNil)
    50  	}
    51  
    52  	// Retrieve a NSX-V VDC
    53  	vdc, err := org.GetAdminVDCByName(vcd.config.VCD.Vdc, false)
    54  	check.Assert(err, IsNil)
    55  	check.Assert(vdc, NotNil)
    56  
    57  	dfw := NewNsxvDistributedFirewall(vdc.client, vdc.AdminVdc.ID)
    58  	check.Assert(dfw, NotNil)
    59  
    60  	// dfw.Enable is an idempotent operation. It can be repeated on an already enabled DFW
    61  	// without errors.
    62  	err = dfw.Enable()
    63  	check.Assert(err, IsNil)
    64  
    65  	enabled, err := dfw.IsEnabled()
    66  	check.Assert(err, IsNil)
    67  	check.Assert(enabled, Equals, true)
    68  
    69  	config, err := dfw.GetConfiguration()
    70  	check.Assert(err, IsNil)
    71  	check.Assert(config, NotNil)
    72  	if testVerbose {
    73  		fmt.Printf("%# v\n", pretty.Formatter(config))
    74  	}
    75  
    76  	// Repeat enable operation
    77  	err = dfw.Enable()
    78  	check.Assert(err, IsNil)
    79  
    80  	enabled, err = dfw.IsEnabled()
    81  	check.Assert(err, IsNil)
    82  	check.Assert(enabled, Equals, true)
    83  
    84  	err = dfw.Disable()
    85  	check.Assert(err, IsNil)
    86  	enabled, err = dfw.IsEnabled()
    87  	check.Assert(err, IsNil)
    88  	check.Assert(enabled, Equals, false)
    89  
    90  	// Also dfw.Disable is idempotent
    91  	err = dfw.Disable()
    92  	check.Assert(err, IsNil)
    93  
    94  	enabled, err = dfw.IsEnabled()
    95  	check.Assert(err, IsNil)
    96  	check.Assert(enabled, Equals, false)
    97  }
    98  
    99  func (vcd *TestVCD) Test_NsxvDistributedFirewallUpdate(check *C) {
   100  	fmt.Printf("Running: %s\n", check.TestName())
   101  
   102  	org, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   103  	check.Assert(err, IsNil)
   104  	check.Assert(org, NotNil)
   105  
   106  	// Retrieve a NSX-V VDC
   107  	adminVdc, err := org.GetAdminVDCByName(vcd.config.VCD.Vdc, false)
   108  	check.Assert(err, IsNil)
   109  	check.Assert(adminVdc, NotNil)
   110  	vdc, err := org.GetVDCByName(vcd.config.VCD.Vdc, false)
   111  	check.Assert(err, IsNil)
   112  
   113  	dfw := NewNsxvDistributedFirewall(adminVdc.client, adminVdc.AdminVdc.ID)
   114  	check.Assert(dfw, NotNil)
   115  	enabled, err := dfw.IsEnabled()
   116  	check.Assert(err, IsNil)
   117  	//
   118  	if enabled {
   119  		check.Skip(fmt.Sprintf("VDC %s already contains a distributed firewall - skipping", vcd.config.VCD.Vdc))
   120  	}
   121  
   122  	vms, err := vdc.QueryVmList(types.VmQueryFilterOnlyDeployed)
   123  	check.Assert(err, IsNil)
   124  
   125  	sampleDestination := &types.Destinations{}
   126  	if len(vms) > 0 {
   127  		sampleDestination.Destination = []types.Destination{
   128  			{
   129  				Name:    vms[0].Name,
   130  				Value:   extractUuid(vms[0].HREF),
   131  				Type:    types.DFWElementVirtualMachine,
   132  				IsValid: true,
   133  			},
   134  		}
   135  	}
   136  	err = dfw.Enable()
   137  	check.Assert(err, IsNil)
   138  
   139  	dnsService, err := dfw.GetServiceByName("DNS")
   140  	check.Assert(err, IsNil)
   141  	integrationServiceGroup, err := dfw.GetServiceGroupByName("MSSQL Integration Services")
   142  	check.Assert(err, IsNil)
   143  
   144  	network, err := vdc.GetOrgVdcNetworkByName(vcd.config.VCD.Network.Net1, false)
   145  	check.Assert(err, IsNil)
   146  	AddToCleanupList(vcd.config.VCD.Vdc, "nsxv_dfw", vcd.config.VCD.Org, check.TestName())
   147  	rules := []types.NsxvDistributedFirewallRule{
   148  		{
   149  			Name:   "first",
   150  			Action: types.DFWActionDeny,
   151  			AppliedToList: &types.AppliedToList{
   152  				AppliedTo: []types.AppliedTo{
   153  					{
   154  						Name:    adminVdc.AdminVdc.Name,
   155  						Value:   adminVdc.AdminVdc.ID,
   156  						Type:    "VDC",
   157  						IsValid: true,
   158  					},
   159  				},
   160  			},
   161  			Direction:  types.DFWDirectionInout,
   162  			PacketType: types.DFWPacketAny,
   163  		},
   164  		{
   165  			Name:          "second",
   166  			AppliedToList: &types.AppliedToList{},
   167  			SectionID:     nil,
   168  			Sources:       nil,
   169  			Destinations:  nil,
   170  			Services:      nil,
   171  			Direction:     types.DFWDirectionIn,
   172  			PacketType:    types.DFWPacketAny,
   173  			Action:        types.DFWActionAllow,
   174  		},
   175  		{
   176  			Name:          "third",
   177  			Action:        types.DFWActionAllow,
   178  			AppliedToList: &types.AppliedToList{},
   179  			Sources: &types.Sources{
   180  				Source: []types.Source{
   181  					// Anonymous source
   182  					{
   183  						Name:  "10.10.10.1",
   184  						Value: "10.10.10.1",
   185  						Type:  types.DFWElementIpv4,
   186  					},
   187  					// Named source
   188  					{
   189  						Name:    network.OrgVDCNetwork.Name,
   190  						Value:   extractUuid(network.OrgVDCNetwork.ID),
   191  						Type:    types.DFWElementNetwork,
   192  						IsValid: true,
   193  					},
   194  				},
   195  			},
   196  			Destinations: sampleDestination,
   197  			Services: &types.Services{
   198  				Service: []types.Service{
   199  					// Anonymous service
   200  					{
   201  						IsValid:         true,
   202  						SourcePort:      addrOf("1000"),
   203  						DestinationPort: addrOf("1200"),
   204  						Protocol:        addrOf(types.NsxvProtocolCodes[types.DFWProtocolTcp]),
   205  						ProtocolName:    addrOf(types.DFWProtocolTcp),
   206  					},
   207  					// Named service
   208  					{
   209  						IsValid: true,
   210  						Name:    dnsService.Name,
   211  						Value:   dnsService.ObjectID,
   212  						Type:    types.DFWServiceTypeApplication,
   213  					},
   214  					// Named service group
   215  					{
   216  						IsValid: true,
   217  						Name:    integrationServiceGroup.Name,
   218  						Value:   integrationServiceGroup.ObjectID,
   219  						Type:    types.DFWServiceTypeApplicationGroup,
   220  					},
   221  				},
   222  			},
   223  			Direction:  types.DFWDirectionIn,
   224  			PacketType: types.DFWPacketIpv4,
   225  		},
   226  	}
   227  
   228  	updatedRules, err := dfw.UpdateConfiguration(rules)
   229  	check.Assert(err, IsNil)
   230  	check.Assert(updatedRules, NotNil)
   231  
   232  	err = dfw.Disable()
   233  	check.Assert(err, IsNil)
   234  
   235  }
   236  
   237  func (vcd *TestVCD) Test_NsxvServices(check *C) {
   238  	fmt.Printf("Running: %s\n", check.TestName())
   239  
   240  	org, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   241  	check.Assert(err, IsNil)
   242  	check.Assert(org, NotNil)
   243  
   244  	// Retrieve a NSX-V VDC
   245  	vdc, err := org.GetAdminVDCByName(vcd.config.VCD.Vdc, false)
   246  	check.Assert(err, IsNil)
   247  	check.Assert(vdc, NotNil)
   248  
   249  	dfw := NewNsxvDistributedFirewall(vdc.client, vdc.AdminVdc.ID)
   250  	check.Assert(dfw, NotNil)
   251  
   252  	services, err := dfw.GetServices(false)
   253  	check.Assert(err, IsNil)
   254  	check.Assert(services, NotNil)
   255  	check.Assert(len(services) > 0, Equals, true)
   256  
   257  	if testVerbose {
   258  		fmt.Printf("services: %d\n", len(services))
   259  		fmt.Printf("%# v\n", pretty.Formatter(services[0]))
   260  	}
   261  
   262  	serviceName := "PostgreSQL"
   263  	serviceByName, err := dfw.GetServiceByName(serviceName)
   264  
   265  	check.Assert(err, IsNil)
   266  	check.Assert(serviceByName, NotNil)
   267  	check.Assert(serviceByName.Name, Equals, serviceName)
   268  
   269  	serviceById, err := dfw.GetServiceById(serviceByName.ObjectID)
   270  	check.Assert(err, IsNil)
   271  	check.Assert(serviceById.Name, Equals, serviceName)
   272  
   273  	searchRegex := "M.SQL" // Finds, among others, names containing "MySQL" or "MSSQL"
   274  	servicesByRegex, err := dfw.GetServicesByRegex(searchRegex)
   275  	check.Assert(err, IsNil)
   276  	check.Assert(len(servicesByRegex) > 1, Equals, true)
   277  
   278  	searchRegex = "." // Finds all services
   279  	servicesByRegex, err = dfw.GetServicesByRegex(searchRegex)
   280  	check.Assert(err, IsNil)
   281  	check.Assert(len(servicesByRegex), Equals, len(services))
   282  
   283  	searchRegex = "^####--no-such-service--####$" // Finds no services
   284  	servicesByRegex, err = dfw.GetServicesByRegex(searchRegex)
   285  	check.Assert(err, IsNil)
   286  	check.Assert(len(servicesByRegex), Equals, 0)
   287  
   288  	serviceGroups, err := dfw.GetServiceGroups(false)
   289  	check.Assert(err, IsNil)
   290  	check.Assert(serviceGroups, NotNil)
   291  	check.Assert(len(serviceGroups) > 0, Equals, true)
   292  	if testVerbose {
   293  		fmt.Printf("service groups: %d\n", len(serviceGroups))
   294  		fmt.Printf("%# v\n", pretty.Formatter(serviceGroups[0]))
   295  	}
   296  	serviceGroupName := "Orchestrator"
   297  	serviceGroupByName, err := dfw.GetServiceGroupByName(serviceGroupName)
   298  	check.Assert(err, IsNil)
   299  	check.Assert(serviceGroupByName, NotNil)
   300  	check.Assert(serviceGroupByName.Name, Equals, serviceGroupName)
   301  
   302  	serviceGroupById, err := dfw.GetServiceGroupById(serviceGroupByName.ObjectID)
   303  	check.Assert(err, IsNil)
   304  	check.Assert(serviceGroupById, NotNil)
   305  	check.Assert(serviceGroupById.Name, Equals, serviceGroupName)
   306  
   307  	searchRegex = "Oracle"
   308  	serviceGroupsByRegex, err := dfw.GetServiceGroupsByRegex(searchRegex)
   309  	check.Assert(err, IsNil)
   310  	check.Assert(len(serviceGroupsByRegex) > 1, Equals, true)
   311  
   312  	searchRegex = "."
   313  	serviceGroupsByRegex, err = dfw.GetServiceGroupsByRegex(searchRegex)
   314  	check.Assert(err, IsNil)
   315  	check.Assert(len(serviceGroupsByRegex), Equals, len(serviceGroups))
   316  
   317  	searchRegex = "^####--no-such-service-group--####$"
   318  	serviceGroupsByRegex, err = dfw.GetServiceGroupsByRegex(searchRegex)
   319  	check.Assert(err, IsNil)
   320  	check.Assert(len(serviceGroupsByRegex), Equals, 0)
   321  }