Skip to content

Commit

Permalink
Merge pull request #1504 from vmware/service-entries
Browse files Browse the repository at this point in the history
Support service entries in policy rules
  • Loading branch information
annakhm authored Feb 10, 2025
2 parents fef67ec + 00e701f commit aaa2c5f
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 286 deletions.
35 changes: 35 additions & 0 deletions nsxt/policy_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ func getSecurityPolicyAndGatewayRuleSchema(scopeRequired bool, isIds bool, nsxID
},
Optional: true,
},
"service_entries": {
Type: schema.TypeList,
Description: "List of services to match",
Elem: &schema.Resource{
Schema: getPolicyServiceEntrySchema(),
},
Optional: true,
MaxItems: 1,
},
"source_groups": {
Type: schema.TypeSet,
Description: "List of source groups",
Expand Down Expand Up @@ -334,6 +343,17 @@ func getPolicyGatewayPolicySchema(isVPC bool) map[string]*schema.Schema {
return secPolicy
}

func getPolicyServiceEntrySchema() map[string]*schema.Schema {
return map[string]*schema.Schema{
"icmp_entry": getIcmpEntrySchema(),
"l4_port_set_entry": getL4PortSetEntrySchema(),
"igmp_entry": getIgmpEntrySchema(),
"ether_type_entry": getEtherEntrySchema(false),
"ip_protocol_entry": getIPProtocolEntrySchema(),
"algorithm_entry": getAlgorithmEntrySchema(),
}
}

func getPolicySecurityPolicySchema(isIds, withContext, withRule, isVPC bool) map[string]*schema.Schema {
result := map[string]*schema.Schema{
"nsx_id": getNsxIDSchema(),
Expand Down Expand Up @@ -489,6 +509,14 @@ func setPolicyRulesInSchema(d *schema.ResourceData, rules []model.Rule) error {
}
elem["tag"] = tagList

if len(rule.ServiceEntries) > 0 {
var entryList []map[string]interface{}
entry := make(map[string]interface{})
setServiceEntriesInSchema(entry, rule.ServiceEntries, false)
entryList = append(entryList, entry)
elem["service_entries"] = entryList
}

rulesList = append(rulesList, elem)
}

Expand Down Expand Up @@ -583,6 +611,13 @@ func getPolicyRulesFromSchema(d *schema.ResourceData) []model.Rule {
SequenceNumber: &sequenceNumber,
}

schemaServiceEntries := data["service_entries"].([]interface{})
if len(schemaServiceEntries) > 0 {
schemaServiceEntry := schemaServiceEntries[0].(map[string]interface{})
serviceEntries, _ := getServiceEntriesFromSchema(schemaServiceEntry)
elem.ServiceEntries = serviceEntries
}

ruleList = append(ruleList, elem)
}

Expand Down
92 changes: 52 additions & 40 deletions nsxt/resource_nsxt_policy_gateway_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ func TestAccResourceNsxtPolicyGatewayPolicy_withIPCidrRange(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.0", policyRange),
resource.TestCheckResourceAttr(testResourceName, "rule.5.destination_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.service_entries.#", "1"),
),
},
{
Expand Down Expand Up @@ -561,6 +562,7 @@ func TestAccResourceNsxtPolicyGatewayPolicy_withIPCidrRange(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.0", updatedPolicyRange),
resource.TestCheckResourceAttr(testResourceName, "rule.5.destination_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.service_entries.#", "1"),
),
},
},
Expand Down Expand Up @@ -953,48 +955,58 @@ func testAccNsxtPolicyGatewayPolicyWithIPCidrRange(name string, destIP string, d
}
rule {
display_name = "rule2"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
display_name = "rule2"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule3"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule3"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule4"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
rule {
display_name = "rule4"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule5"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule6"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
service_entries {
algorithm_entry {
algorithm = "TFTP"
destination_port = "9000"
}
ether_type_entry {
ether_type = "1536"
}
}
rule {
display_name = "rule5"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
rule {
display_name = "rule6"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
scope = [nsxt_policy_tier1_gateway.gwt1test.path]
action = "ALLOW"
}
}
}`, name, destIP, destCidr, destIPRange, sourceIP, sourceCidr, sourceIPRange)
}
18 changes: 17 additions & 1 deletion nsxt/resource_nsxt_policy_security_policy_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func securityPolicyRuleSchemaToModel(d *schema.ResourceData, id string) model.Ru
tagStructs := getPolicyTagsFromSet(d.Get("tag").(*schema.Set))

resourceType := "Rule"
return model.Rule{
rule := model.Rule{
ResourceType: &resourceType,
Id: &id,
DisplayName: &displayName,
Expand All @@ -123,6 +123,14 @@ func securityPolicyRuleSchemaToModel(d *schema.ResourceData, id string) model.Ru
Profiles: getPathListFromSchema(d, "profiles"),
SequenceNumber: &sequenceNumber,
}

schemaServiceEntries := d.Get("service_entries").([]interface{})
if len(schemaServiceEntries) > 0 {
schemaServiceEntry := schemaServiceEntries[0].(map[string]interface{})
serviceEntries, _ := getServiceEntriesFromSchema(schemaServiceEntry)
rule.ServiceEntries = serviceEntries
}
return rule
}

func resourceNsxtPolicySecurityPolicyRuleExistsPartial(d *schema.ResourceData, m interface{}, policyPath string) func(sessionContext utl.SessionContext, id string, connector client.Connector) (bool, error) {
Expand Down Expand Up @@ -211,6 +219,14 @@ func securityPolicyRuleModelToSchema(d *schema.ResourceData, rule model.Rule) {
d.Set("nsx_id", rule.Id)
d.Set("rule_id", rule.RuleId)

var entryList []map[string]interface{}
if len(rule.ServiceEntries) > 0 {
entry := make(map[string]interface{})
setServiceEntriesInSchema(entry, rule.ServiceEntries, false)
entryList = append(entryList, entry)
}
d.Set("service_entries", entryList)

setPolicyTagsInSchema(d, rule.Tags)
}

Expand Down
18 changes: 18 additions & 0 deletions nsxt/resource_nsxt_policy_security_policy_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func testAccResourceNsxtPolicySecurityPolicyRuleBasic(t *testing.T, withContext
resource.TestCheckResourceAttr(ruleResourceName, "direction", direction),
resource.TestCheckResourceAttr(ruleResourceName, "ip_version", proto),
resource.TestCheckResourceAttr(ruleResourceName, "sequence_number", seqNum),
resource.TestCheckResourceAttr(ruleResourceName, "service_entries.#", "1"),
resource.TestCheckResourceAttr(ruleResourceName, "service_entries.0.igmp_entry.#", "1"),
resource.TestCheckResourceAttr(ruleResourceName, "service_entries.0.l4_port_set_entry.#", "2"),
),
},
{
Expand Down Expand Up @@ -283,6 +286,21 @@ resource "nsxt_policy_security_policy_rule" "%s" {
ip_version = "%s"
sequence_number = %s
service_entries {
igmp_entry {
}
l4_port_set_entry {
protocol = "TCP"
destination_ports = [ "443" ]
}
l4_port_set_entry {
protocol = "TCP"
destination_ports = [ "80" ]
}
}
tag {
scope = "color"
tag = "orange"
Expand Down
71 changes: 42 additions & 29 deletions nsxt/resource_nsxt_policy_security_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,10 @@ func TestAccResourceNsxtPolicySecurityPolicy_withIPCidrRange(t *testing.T) {
updatedPolicyCidr := "10.10.40.0/22"
updatedPolicyRange := "10.10.40.6-10.10.40.7"

// a bug in NSX would cause permadiff when display_name is used in service_entries
// this issue is fixed in 4.0.0 onwards
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { testAccPreCheck(t); testAccNSXVersion(t, "4.0.0") },
Providers: testAccProviders,
CheckDestroy: func(state *terraform.State) error {
return testAccNsxtPolicySecurityPolicyCheckDestroy(state, name, defaultDomain)
Expand Down Expand Up @@ -360,6 +362,7 @@ func TestAccResourceNsxtPolicySecurityPolicy_withIPCidrRange(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.0", policyRange),
resource.TestCheckResourceAttr(testResourceName, "rule.5.destination_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.service_entries.#", "1"),
),
},
{
Expand Down Expand Up @@ -419,6 +422,7 @@ func TestAccResourceNsxtPolicySecurityPolicy_withIPCidrRange(t *testing.T) {
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.source_groups.0", updatedPolicyRange),
resource.TestCheckResourceAttr(testResourceName, "rule.5.destination_groups.#", "1"),
resource.TestCheckResourceAttr(testResourceName, "rule.5.service_entries.#", "1"),
),
},
},
Expand Down Expand Up @@ -871,7 +875,6 @@ resource "nsxt_policy_service" "tcp778" {
}`
}

// TODO: add profiles when available
func testAccNsxtPolicySecurityPolicyWithDepsCreate(name string) string {
return testAccNsxtPolicySecurityPolicyDeps() + fmt.Sprintf(`
resource "nsxt_policy_security_policy" "test" {
Expand Down Expand Up @@ -964,44 +967,54 @@ func testAccNsxtPolicySecurityPolicyWithIPCidrRange(name string, destIP string,
}
rule {
display_name = "rule2"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
display_name = "rule2"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
}
rule {
display_name = "rule3"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
sequence_number = 50
display_name = "rule3"
source_groups = [nsxt_policy_group.group1.path]
destination_groups = ["%s"]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
sequence_number = 50
}
rule {
display_name = "rule4"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
display_name = "rule4"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
}
rule {
display_name = "rule5"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
sequence_number = 105
display_name = "rule5"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
sequence_number = 105
}
rule {
display_name = "rule6"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
services = [nsxt_policy_service.icmp.path]
action = "ALLOW"
display_name = "rule6"
source_groups = ["%s"]
destination_groups = [nsxt_policy_group.group2.path]
service_entries {
icmp_entry {
display_name = "test"
icmp_type = "3"
protocol = "ICMPv4"
}
l4_port_set_entry {
protocol = "TCP"
destination_ports = ["8000-8080"]
}
}
action = "ALLOW"
}
}`, name, destIP, destCidr, destIPRange, sourceIP, sourceCidr, sourceIPRange)
}
Expand Down
Loading

0 comments on commit aaa2c5f

Please sign in to comment.