Skip to content

Commit

Permalink
one In/outbound list - to set proirity in right order (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
haim-kermany authored Jan 30, 2025
1 parent 46c3c84 commit 268daed
Show file tree
Hide file tree
Showing 13 changed files with 397 additions and 347 deletions.
2 changes: 1 addition & 1 deletion pkg/model/dfw/category.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func (c *CategorySpec) addRule(src, dst []*endpoints.VM, srcGroups, dstGroups, s
Action: actionFromString(action),
direction: direction,
RuleID: ruleID,
origRuleObj: origRule,
OrigRuleObj: origRule,
origDefaultRuleObj: origDefaultRule,
scope: scope,
ScopeGroups: scopeGroups,
Expand Down
26 changes: 13 additions & 13 deletions pkg/model/dfw/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type FwRule struct {
Conn *netset.TransportSet
Action RuleAction
direction string // "IN","OUT", "IN_OUT"
origRuleObj *collector.Rule
OrigRuleObj *collector.Rule
origDefaultRuleObj *collector.FirewallRule
RuleID int
secPolicyName string
Expand Down Expand Up @@ -127,7 +127,7 @@ func (f *FwRule) getInboundRule() *FwRule {
Conn: f.Conn,
Action: f.Action,
direction: string(nsx.RuleDirectionIN),
origRuleObj: f.origRuleObj,
OrigRuleObj: f.OrigRuleObj,
RuleID: f.RuleID,
secPolicyName: f.secPolicyName,
}
Expand Down Expand Up @@ -166,7 +166,7 @@ func (f *FwRule) getOutboundRule() *FwRule {
Conn: f.Conn,
Action: f.Action,
direction: string(nsx.RuleDirectionOUT),
origRuleObj: f.origRuleObj,
OrigRuleObj: f.OrigRuleObj,
RuleID: f.RuleID,
secPolicyName: f.secPolicyName,
}
Expand Down Expand Up @@ -251,16 +251,16 @@ func getSrcOrDstExcludedStr(groupsStr string) string {
}

func (f *FwRule) getSrcString() string {
srcGroups := f.getShortPathsString(f.origRuleObj.SourceGroups)
if f.origRuleObj.SourcesExcluded {
srcGroups := f.getShortPathsString(f.OrigRuleObj.SourceGroups)
if f.OrigRuleObj.SourcesExcluded {
return getSrcOrDstExcludedStr(srcGroups)
}
return srcGroups
}

func (f *FwRule) getDstString() string {
dstGroups := f.getShortPathsString(f.origRuleObj.DestinationGroups)
if f.origRuleObj.DestinationsExcluded {
dstGroups := f.getShortPathsString(f.OrigRuleObj.DestinationGroups)
if f.OrigRuleObj.DestinationsExcluded {
return getSrcOrDstExcludedStr(dstGroups)
}
return dstGroups
Expand All @@ -286,14 +286,14 @@ func (f *FwRule) originalRuleComponentsStr() []string {
const (
anyStr = "ANY"
)
if f.origRuleObj == nil && f.origDefaultRuleObj == nil {
if f.OrigRuleObj == nil && f.origDefaultRuleObj == nil {
f.ruleWarning("has no origRuleObj or origDefaultRuleObj")
return []string{}
}

// if this is a "default rule" from category with ConnectivityPreference configured,
// the rule object is of different type
if f.origRuleObj == nil && f.origDefaultRuleObj != nil {
if f.OrigRuleObj == nil && f.origDefaultRuleObj != nil {
return []string{
*f.origDefaultRuleObj.Id,
*f.origDefaultRuleObj.DisplayName,
Expand All @@ -311,18 +311,18 @@ func (f *FwRule) originalRuleComponentsStr() []string {
}

name := ""
if f.origRuleObj.DisplayName != nil {
name = *f.origRuleObj.DisplayName
if f.OrigRuleObj.DisplayName != nil {
name = *f.OrigRuleObj.DisplayName
}
return []string{
fmt.Sprintf("%d", f.RuleID),
name,
f.getSrcString(),
f.getDstString(),
// todo: origRuleObj.Services is not always the services, can also be service_entries
f.getShortPathsString(f.origRuleObj.Services),
f.getShortPathsString(f.OrigRuleObj.Services),
string(f.Action), f.direction,
strings.Join(f.origRuleObj.Scope, common.CommaSeparator),
strings.Join(f.OrigRuleObj.Scope, common.CommaSeparator),
f.secPolicyName,
f.secPolicyCategory,
}
Expand Down
36 changes: 22 additions & 14 deletions pkg/synthesis/k8sPolicies.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,34 @@ type k8sPolicies struct {

func (policies *k8sPolicies) toNetworkPolicies(model *AbstractModelSyn) ([]*networking.NetworkPolicy, []*admin.AdminNetworkPolicy) {
for _, p := range model.policy {
policies.symbolicRulesToPolicies(model, p.outbound, false)
policies.symbolicRulesToPolicies(model, p.inbound, true)
policies.symbolicRulePairsToPolicies(model, p.toPairs())
}
policies.addDefaultDenyNetworkPolicy()
return policies.networkPolicies, policies.adminNetworkPolicies
}

func (policies *k8sPolicies) symbolicRulesToPolicies(model *AbstractModelSyn, rules []*symbolicRule, inbound bool) {
for _, rule := range rules {
isAdmin := model.allowOnlyFromCategory > rule.origRuleCategory
paths := &rule.allowOnlyRulePaths
if isAdmin {
paths = rule.origSymbolicPaths
func (policies *k8sPolicies) symbolicRulePairsToPolicies(model *AbstractModelSyn, rulePairs []*symbolicRulePair) {
for _, rulePair := range rulePairs {
if rulePair.outbound != nil {
policies.symbolicRulesToPolicies(model, rulePair.outbound, false)
}
for _, p := range *paths {
if !p.Conn.TCPUDPSet().IsEmpty() {
policies.addNewPolicy(p, inbound, isAdmin, rule.origRule.Action, fmt.Sprintf("%d", rule.origRule.RuleID))
} else {
logging.Debugf("do not create a k8s policy for rule %s - connection %s is not supported", rule.origRule.String(), p.Conn.String())
}
if rulePair.inbound != nil {
policies.symbolicRulesToPolicies(model, rulePair.inbound, true)
}
}
}

func (policies *k8sPolicies) symbolicRulesToPolicies(model *AbstractModelSyn, rule *symbolicRule, inbound bool) {
isAdmin := model.allowOnlyFromCategory > rule.origRuleCategory
paths := &rule.allowOnlyRulePaths
if isAdmin {
paths = rule.origSymbolicPaths
}
for _, p := range *paths {
if !p.Conn.TCPUDPSet().IsEmpty() {
policies.addNewPolicy(p, inbound, isAdmin, rule.origRule.Action, fmt.Sprintf("%d", rule.origRule.RuleID))
} else {
logging.Debugf("do not create a k8s policy for rule %s - connection %s is not supported", rule.origRule.String(), p.Conn.String())
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions pkg/synthesis/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package synthesis

import (
"maps"
"slices"

"github.com/np-guard/vmware-analyzer/pkg/collector"
"github.com/np-guard/vmware-analyzer/pkg/model/dfw"
"github.com/np-guard/vmware-analyzer/pkg/model/endpoints"
Expand Down Expand Up @@ -45,6 +48,45 @@ type symbolicPolicy struct {
outbound []*symbolicRule // ordered list outbound symbolicRule
}

type symbolicRulePair struct {
inbound *symbolicRule // inbound symbolicRule
outbound *symbolicRule // outbound symbolicRule
}

// a temporary function to get pairs of rules, each pair represent an orig rule.
// to be remove after reorg symbolicPolicy
func (policy *symbolicPolicy) toPairs() []*symbolicRulePair {
ruleToPair := map[*collector.Rule]*symbolicRulePair{}
getRulePair := func(r *symbolicRule) *symbolicRulePair {
if _, ok := ruleToPair[r.origRule.OrigRuleObj]; !ok {
ruleToPair[r.origRule.OrigRuleObj] = &symbolicRulePair{}
}
return ruleToPair[r.origRule.OrigRuleObj]
}
for _, r := range policy.inbound {
getRulePair(r).inbound = r
}
for _, r := range policy.outbound {
getRulePair(r).outbound = r
}
res := slices.Collect(maps.Values(ruleToPair))
slices.SortStableFunc(res, func(p1, p2 *symbolicRulePair) int {
in1 := slices.Index(policy.inbound, p1.inbound)
in2 := slices.Index(policy.inbound, p2.inbound)
out1 := slices.Index(policy.outbound, p1.outbound)
out2 := slices.Index(policy.outbound, p2.outbound)
switch {
case in1 >= 0 && in2 >= 0:
return in1 - in2
case out1 >= 0 && out2 >= 0:
return out1 - out2
default:
return 0
}
})
return res
}

// maps used by AbstractModelSyn

// Segments topology; map from segment name to the segment
Expand Down
2 changes: 1 addition & 1 deletion pkg/synthesis/synthesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,12 @@ func (synTest *synthesisTest) runConvertToAbstract(t *testing.T, mode testMode)
abstractModel, err := NSXToK8sSynthesis(rc, outDir, hintsParm, synTest.allowOnlyFromCategory)
expectedOutputFileName := filepath.Join(getTestsDirOut(), synTest.name+suffix)
expectedOutputDir := filepath.Join(getTestsDirOut(), k8sResourcesDir, baseName)
compareOrRegenerateOutputDirPerTest(t, mode, filepath.Join(outDir, k8sResourcesDir), expectedOutputDir, synTest.name)
require.Nil(t, err)
addDebugFiles(t, rc, abstractModel, outDir)
actualOutput := strAllowOnlyPolicy(abstractModel.policy[0])
fmt.Println(actualOutput)
compareOrRegenerateOutputPerTest(t, mode, actualOutput, expectedOutputFileName, synTest.name)
compareOrRegenerateOutputDirPerTest(t, mode, filepath.Join(outDir, k8sResourcesDir), expectedOutputDir, synTest.name)
}

func addDebugFiles(t *testing.T, rc *collector.ResourcesContainerModel, abstractModel *AbstractModelSyn, outDir string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,42 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
description: All Connections from (group = DumbledoreNoSly) to (group != Slytherin)
nsx-id: "9196"
description: All Connections from (group = DumbledoreAll) to (*)
nsx-id: "1925"
creationTimestamp: null
name: policy_1
spec:
egress:
- to:
ingress:
- from:
- podSelector:
matchExpressions:
- key: group__Slytherin
operator: DoesNotExist
podSelector:
matchExpressions:
- key: group__DumbledoreNoSly
operator: Exists
- key: group__DumbledoreAll
operator: Exists
podSelector: {}
policyTypes:
- Egress
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
description: All Connections from (group = DumbledoreAll) to (*)
nsx-id: "1925"
description: All Connections from (group = DumbledoreNoSly) to (group != Slytherin)
nsx-id: "9196"
creationTimestamp: null
name: policy_2
spec:
ingress:
- from:
egress:
- to:
- podSelector:
matchExpressions:
- key: group__DumbledoreAll
operator: Exists
podSelector: {}
- key: group__Slytherin
operator: DoesNotExist
podSelector:
matchExpressions:
- key: group__DumbledoreNoSly
operator: Exists
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
Expand Down
Loading

0 comments on commit 268daed

Please sign in to comment.