Skip to content

Commit

Permalink
Refactor config and analyzer (#287)
Browse files Browse the repository at this point in the history
* refactor config and analysis pkgs 
* rename pkg endpoints -> topology, rename interface EP -> Endpoint
---------

Signed-off-by: adisos <adisos@il.ibm.com>
  • Loading branch information
adisos authored Mar 2, 2025
1 parent fcbe9e9 commit 3f2749e
Show file tree
Hide file tree
Showing 26 changed files with 411 additions and 400 deletions.
56 changes: 30 additions & 26 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
package model
package analyzer

import (
"github.com/np-guard/vmware-analyzer/internal/common"
"github.com/np-guard/vmware-analyzer/pkg/analyzer/connectivity"
"github.com/np-guard/vmware-analyzer/pkg/collector"
"github.com/np-guard/vmware-analyzer/pkg/configuration"
"github.com/np-guard/vmware-analyzer/pkg/logging"
)

func NSXConnectivityFromResourcesContainer(recourses *collector.ResourcesContainerModel, params common.OutputParameters) (
configuration.ParsedNSXConfig, string, error) {
config, err := ConfigFromResourcesContainer(recourses, params)
if err != nil {
return nil, "", err
func computeConnectivity(c *configuration.Config, vmsFilter []string) connectivity.ConnMap {
logging.Debugf("compute connectivity on parsed config")
res := connectivity.ConnMap{}
// make sure all vm pairs are in the result, by init with global default
res.InitPairs(false, c.Vms, vmsFilter)
// iterate over all vm pairs in the initialized map at res, get the analysis result per pair
for src, srcMap := range res {
for dst := range srcMap {
if src == dst {
continue
}
conn := dfwAllowedConnections(c.Fw, src, dst)
res.Add(src, dst, conn)
}
}
return res
}

res, err := config.Connectivity.GenConnectivityOutput(params)
func NSXConnectivityFromResourcesContainer(resources *collector.ResourcesContainerModel, params common.OutputParameters) (
configuration.ParsedNSXConfig,
connectivity.ConnMap,
string,
error) {
config, err := configuration.ConfigFromResourcesContainer(resources, params.Color)
if err != nil {
return nil, nil, "", err
}
connMap := computeConnectivity(config, params.VMs)
res, err := connMap.GenConnectivityOutput(params)

//nolint:gocritic // temporarily keep commented-out code
/*allowed, denied := config.analyzedConnectivity.GetDisjointExplanationsPerEndpoints("A", "B")
Expand All @@ -37,23 +59,5 @@ func NSXConnectivityFromResourcesContainer(recourses *collector.ResourcesContain
)
}*/

return config, res, err
}

func ConfigFromResourcesContainer(recourses *collector.ResourcesContainerModel,
params common.OutputParameters) (*configuration.Config, error) {
parser := configuration.NewNSXConfigParserFromResourcesContainer(recourses)
err := parser.RunParser()
if err != nil {
return nil, err
}
config := parser.GetConfig()

// in debug/verbose mode -- print the parsed config
logging.Debugf("the parsed config details: %s", config.GetConfigInfoStr(params.Color))

// compute connectivity map from the parsed config
config.ComputeConnectivity(params.VMs)

return config, nil
return config, connMap, res, err
}
2 changes: 1 addition & 1 deletion pkg/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package model_test
package analyzer_test

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package dfw
package analyzer

import (
"fmt"
"slices"

"github.com/np-guard/models/pkg/netset"
"github.com/np-guard/vmware-analyzer/internal/common"
"github.com/np-guard/vmware-analyzer/pkg/analyzer/connectivity"
"github.com/np-guard/vmware-analyzer/pkg/configuration/endpoints"
"github.com/np-guard/vmware-analyzer/pkg/configuration/dfw"
"github.com/np-guard/vmware-analyzer/pkg/configuration/topology"
)

// analyzeCategory returns sets of connections w.r.t their determining rule action from this category rules,
// for VM connectivity from src to dst
// todo: may possibly eliminate jumpToAppConns and unify them with notDeterminedConns
//
//nolint:gocritic // temporarily keep commented-out code
func (c *CategorySpec) analyzeCategory(src, dst endpoints.EP, isIngress bool,
func analyzeCategory(c *dfw.CategorySpec, src, dst topology.Endpoint, isIngress bool,
) (allowedConns, // allowedConns are the set of connections between src to dst, which are allowed by this category rules.
jumpToAppConns, // jumpToAppConns are the set of connections between src to dst, for which this category applies the
// rule action jump_to_app.
Expand All @@ -31,25 +30,25 @@ func (c *CategorySpec) analyzeCategory(src, dst endpoints.EP, isIngress bool,
}
// logging.Debugf("num of rules: %d", len(rules))
for _, rule := range rules {
if rule.evaluatedRuleCapturesPair(src, dst) {
if evaluatedRuleCapturesPair(rule, src, dst) {
switch rule.Action {
case ActionAllow:
case dfw.ActionAllow:
addedAllowedConns := rule.Conn.Subtract(deniedConns.accumulatedConns).Subtract(jumpToAppConns.accumulatedConns)
rulePartition := &connectivity.RuleAndConn{RuleID: rule.RuleID, Conn: addedAllowedConns.Subtract(allowedConns.accumulatedConns)}
allowedConns.accumulatedConns = allowedConns.accumulatedConns.Union(addedAllowedConns)
if !rulePartition.Conn.IsEmpty() {
allowedConns.partitionsByRules = append(allowedConns.partitionsByRules, rulePartition)
}

case ActionDeny:
case dfw.ActionDeny:
addedDeniedConns := rule.Conn.Subtract(allowedConns.accumulatedConns).Subtract(jumpToAppConns.accumulatedConns)
rulePartition := &connectivity.RuleAndConn{RuleID: rule.RuleID, Conn: addedDeniedConns.Subtract(deniedConns.accumulatedConns)}
deniedConns.accumulatedConns = deniedConns.accumulatedConns.Union(addedDeniedConns)
if !rulePartition.Conn.IsEmpty() {
deniedConns.partitionsByRules = append(deniedConns.partitionsByRules, rulePartition)
}

case ActionJumpToApp:
case dfw.ActionJumpToApp:
addedJumpToAppConns := rule.Conn.Subtract(allowedConns.accumulatedConns).Subtract(deniedConns.accumulatedConns)
rulePartition := &connectivity.RuleAndConn{RuleID: rule.RuleID, Conn: addedJumpToAppConns.Subtract(jumpToAppConns.accumulatedConns)}
jumpToAppConns.accumulatedConns = jumpToAppConns.accumulatedConns.Union(addedJumpToAppConns)
Expand All @@ -66,16 +65,6 @@ func (c *CategorySpec) analyzeCategory(src, dst endpoints.EP, isIngress bool,
return allowedConns, jumpToAppConns, deniedConns, nonDet
}

type connectionsAndRules struct {
accumulatedConns *netset.TransportSet
partitionsByRules []*connectivity.RuleAndConn
}

func (cr *connectionsAndRules) String() string {
partitionsByRulesStr := common.JoinStringifiedSlice(cr.partitionsByRules, ";")
return fmt.Sprintf("accumulatedConns: %s, partitionsByRules: %s", cr.accumulatedConns.String(), partitionsByRulesStr)
}

func (cr *connectionsAndRules) removeHigherPrioConnections(higherPrioConns *netset.TransportSet) {
// complete deletion for those fully contained in higher prio conns:
cr.partitionsByRules = slices.DeleteFunc(cr.partitionsByRules, func(n *connectivity.RuleAndConn) bool {
Expand All @@ -98,13 +87,8 @@ func (cr *connectionsAndRules) removeHigherPrioConnections(higherPrioConns *nets
cr.accumulatedConns = cr.accumulatedConns.Subtract(higherPrioConns)
}

func (cr *connectionsAndRules) union(cr2 *connectionsAndRules) {
cr.accumulatedConns = cr.accumulatedConns.Union(cr2.accumulatedConns)
cr.partitionsByRules = append(cr.partitionsByRules, cr2.partitionsByRules...)
}

func emptyConnectionsAndRules() *connectionsAndRules {
return &connectionsAndRules{
accumulatedConns: netset.NoTransports(),
}
func evaluatedRuleCapturesPair(f *dfw.FwRule, src, dst topology.Endpoint) bool {
// in evaluated rule the src/dst vms already consider the original scope rule
// and the separation to inound/outbound is done in advance
return slices.Contains(f.SrcVMs, src) && slices.Contains(f.DstVMs, dst)
}
30 changes: 30 additions & 0 deletions pkg/analyzer/connections_and_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package analyzer

import (
"fmt"

"github.com/np-guard/models/pkg/netset"
"github.com/np-guard/vmware-analyzer/internal/common"
"github.com/np-guard/vmware-analyzer/pkg/analyzer/connectivity"
)

type connectionsAndRules struct {
accumulatedConns *netset.TransportSet
partitionsByRules []*connectivity.RuleAndConn
}

func emptyConnectionsAndRules() *connectionsAndRules {
return &connectionsAndRules{
accumulatedConns: netset.NoTransports(),
}
}

func (cr *connectionsAndRules) union(cr2 *connectionsAndRules) {
cr.accumulatedConns = cr.accumulatedConns.Union(cr2.accumulatedConns)
cr.partitionsByRules = append(cr.partitionsByRules, cr2.partitionsByRules...)
}

func (cr *connectionsAndRules) String() string {
partitionsByRulesStr := common.JoinStringifiedSlice(cr.partitionsByRules, ";")
return fmt.Sprintf("accumulatedConns: %s, partitionsByRules: %s", cr.accumulatedConns.String(), partitionsByRulesStr)
}
12 changes: 6 additions & 6 deletions pkg/analyzer/connectivity/connectivity.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ package connectivity
import (
"slices"

"github.com/np-guard/vmware-analyzer/pkg/configuration/endpoints"
"github.com/np-guard/vmware-analyzer/pkg/configuration/topology"
"github.com/np-guard/vmware-analyzer/pkg/logging"
)

// ConnMap captures permitted connections between endpoints in the input config
type ConnMap map[endpoints.EP]map[endpoints.EP]*DetailedConnection
type ConnMap map[topology.Endpoint]map[topology.Endpoint]*DetailedConnection

// Add func adds a given pair with specified permitted connection
func (c ConnMap) Add(src, dst endpoints.EP, conn *DetailedConnection) {
func (c ConnMap) Add(src, dst topology.Endpoint, conn *DetailedConnection) {
if _, ok := c[src]; !ok {
c[src] = map[endpoints.EP]*DetailedConnection{}
c[src] = map[topology.Endpoint]*DetailedConnection{}
}
c[src][dst] = conn
}

// InitPairs adds all possible pairs with allow-all or deny-all, based on initAllow
func (c ConnMap) InitPairs(initAllow bool, vms []endpoints.EP, vmsFilter []string) {
func (c ConnMap) InitPairs(initAllow bool, vms []topology.Endpoint, vmsFilter []string) {
vmsToaAnalyze := map[string]bool{}
if len(vmsFilter) > 0 {
for _, vmName := range vmsFilter {
Expand Down Expand Up @@ -60,7 +60,7 @@ func (c ConnMap) filter(vms []string) ConnMap {

// connMapEntry captures one entry in ConnMap
type connMapEntry struct {
Src, Dst endpoints.EP
Src, Dst topology.Endpoint
DetailedConn *DetailedConnection
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/analyzer/connectivity/explain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (

"github.com/np-guard/models/pkg/netset"
"github.com/np-guard/vmware-analyzer/internal/common"
"github.com/np-guard/vmware-analyzer/pkg/configuration/endpoints"
"github.com/np-guard/vmware-analyzer/pkg/configuration/topology"
)

func newVM(name string) endpoints.EP {
return endpoints.NewVM(name, name)
func newVM(name string) topology.Endpoint {
return topology.NewVM(name, name)
}

// todo: improve test
Expand All @@ -24,7 +24,7 @@ func TestDisjointExplanationsPerEndpoints(t *testing.T) {
detailedConn := &DetailedConnection{Conn: netset.AllTransports(), ExplanationObj: exp}

cmap := ConnMap{}
cmap.InitPairs(false, []endpoints.EP{vmA, vmB}, nil)
cmap.InitPairs(false, []topology.Endpoint{vmA, vmB}, nil)
cmap.Add(vmA, vmB, detailedConn)

res := cmap.GetDisjointConnecionSetsPerExplanationsForEndpoints(vmA.Name(), vmB.Name())
Expand Down
Loading

0 comments on commit 3f2749e

Please sign in to comment.