diff --git a/pkg/model/analyzer.go b/pkg/model/analyzer.go index e1df649..cebdb0c 100644 --- a/pkg/model/analyzer.go +++ b/pkg/model/analyzer.go @@ -21,7 +21,7 @@ func configFromResourcesContainer(recourses *collector.ResourcesContainerModel, config := parser.GetConfig() // in debug/verbose mode -- print the parsed config - logging.Debugf("the parsed config details: %s", config.getConfigInfoStr()) + logging.Debugf("the parsed config details: %s", config.GetConfigInfoStr()) // compute connectivity map from the parsed config config.ComputeConnectivity(vmsFilter) diff --git a/pkg/model/config.go b/pkg/model/config.go index 32380cf..ac606b2 100644 --- a/pkg/model/config.go +++ b/pkg/model/config.go @@ -11,9 +11,9 @@ import ( // config captures nsx config type config struct { - vms []*endpoints.VM // list of all vms + Vms []*endpoints.VM // list of all Vms vmsMap map[string]*endpoints.VM // map from uid to vm objects - fw *dfw.DFW // currently assuming one DFW only (todo: rename pkg dfw) + Fw *dfw.DFW // currently assuming one DFW only (todo: rename pkg dfw) analyzedConnectivity connMap // the resulting connectivity map from analyzing this configuration analysisDone bool } @@ -29,14 +29,14 @@ func (c *config) ComputeConnectivity(vmsFilter []string) { logging.Debugf("compute connectivity on parsed config") res := connMap{} // make sure all vm pairs are in the result, by init with global default - res.initPairs(c.fw.GlobalDefaultAllow(), c.vms, vmsFilter) + res.initPairs(c.Fw.GlobalDefaultAllow(), 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 := c.fw.AllowedConnections(src, dst) + conn := c.Fw.AllowedConnections(src, dst) res.add(src, dst, conn) } } @@ -44,22 +44,22 @@ func (c *config) ComputeConnectivity(vmsFilter []string) { c.analysisDone = true } -// getConfigInfoStr returns string describing the captured configuration content -func (c *config) getConfigInfoStr() string { +// GetConfigInfoStr returns string describing the captured configuration content +func (c *config) GetConfigInfoStr() string { var sb strings.Builder sb.WriteString(common.OutputSectionSep) sb.WriteString("VMs:\n") - for _, vm := range c.vms { + for _, vm := range c.Vms { sb.WriteString(vm.Name() + "\n") } sb.WriteString(common.OutputSectionSep) sb.WriteString("DFW:\n") - sb.WriteString(c.fw.OriginalRulesStrFormatted()) + sb.WriteString(c.Fw.OriginalRulesStrFormatted()) sb.WriteString(common.ShortSep) - sb.WriteString(c.fw.String()) + sb.WriteString(c.Fw.String()) sb.WriteString(common.ShortSep) - sb.WriteString(c.fw.AllEffectiveRules()) + sb.WriteString(c.Fw.AllEffectiveRules()) sb.WriteString(common.OutputSectionSep) return sb.String() diff --git a/pkg/model/connectivity_test.go b/pkg/model/connectivity_test.go index 3b1808b..41a6b5e 100644 --- a/pkg/model/connectivity_test.go +++ b/pkg/model/connectivity_test.go @@ -25,13 +25,13 @@ var dfwAllowAllByDefault = dfw.NewEmptyDFW(true) // no rules and global def // basic test var config1 = &config{ - vms: allVms, - fw: dfwAllowNothingByDefault, + Vms: allVms, + Fw: dfwAllowNothingByDefault, } var config2 = &config{ - vms: allVms, - fw: dfwAllowAllByDefault, + Vms: allVms, + Fw: dfwAllowAllByDefault, } func sumPairs(c connMap) int { diff --git a/pkg/model/dfw/category.go b/pkg/model/dfw/category.go index 7ca5445..61d2b3a 100644 --- a/pkg/model/dfw/category.go +++ b/pkg/model/dfw/category.go @@ -75,30 +75,30 @@ var categoriesList = []DfwCategory{ ethernetCategory, emergencyCategory, infrastructureCategory, envCategory, appCategoty, emptyCategory, } -// effectiveRules are built from original rules, split to separate inbound & outbound rules +// EffectiveRules are built from original rules, split to separate Inbound & Outbound rules // consider already the scope from the original rules -type effectiveRules struct { - inbound []*FwRule - outbound []*FwRule +type EffectiveRules struct { + Inbound []*FwRule + Outbound []*FwRule } -func (e *effectiveRules) addInboundRule(r *FwRule) { +func (e *EffectiveRules) addInboundRule(r *FwRule) { if r != nil { - e.inbound = append(e.inbound, r) + e.Inbound = append(e.Inbound, r) } } -func (e *effectiveRules) addOutboundRule(r *FwRule) { +func (e *EffectiveRules) addOutboundRule(r *FwRule) { if r != nil { - e.outbound = append(e.outbound, r) + e.Outbound = append(e.Outbound, r) } } -type categorySpec struct { - category DfwCategory +type CategorySpec struct { + Category DfwCategory rules []*FwRule // ordered list of rules - defaultAction ruleAction - processedRules *effectiveRules // ordered list of effective rules + defaultAction RuleAction + ProcessedRules *EffectiveRules // ordered list of effective rules dfwRef *DFW } @@ -110,16 +110,16 @@ type categorySpec struct { // todo: may possibly eliminate jumpToAppConns and unify them with notDeterminedConns // //nolint:gocritic // for now keep commentedOutCode -func (c *categorySpec) analyzeCategory(src, dst *endpoints.VM, isIngress bool, +func (c *CategorySpec) analyzeCategory(src, dst *endpoints.VM, isIngress bool, ) (allowedConns, jumpToAppConns, deniedConns, nonDet *netset.TransportSet) { allowedConns, jumpToAppConns, deniedConns = netset.NoTransports(), netset.NoTransports(), netset.NoTransports() - rules := c.processedRules.inbound // inbound effective rules + rules := c.ProcessedRules.Inbound // Inbound effective rules if !isIngress { - rules = c.processedRules.outbound // outbound effective rules + rules = c.ProcessedRules.Outbound // Outbound effective rules } for _, rule := range rules /*c.rules*/ { if rule.processedRuleCapturesPair(src, dst) /*rule.capturesPair(src, dst, isIngress)*/ { - switch rule.action { + switch rule.Action { case actionAllow: addedAllowedConns := rule.conn.Subtract(deniedConns).Subtract(jumpToAppConns) allowedConns = allowedConns.Union(addedAllowedConns) @@ -147,7 +147,7 @@ func (c *categorySpec) analyzeCategory(src, dst *endpoints.VM, isIngress bool, return allowedConns, jumpToAppConns, deniedConns, nonDet } -func (c *categorySpec) originalRulesStr() []string { +func (c *CategorySpec) originalRulesStr() []string { rulesStr := make([]string, len(c.rules)) for i := range c.rules { rulesStr[i] = c.rules[i].originalRuleStr() @@ -155,68 +155,68 @@ func (c *categorySpec) originalRulesStr() []string { return rulesStr } -func (c *categorySpec) string() string { +func (c *CategorySpec) string() string { rulesStr := make([]string, len(c.rules)+1) rulesStr[0] = "rules:" for i := range c.rules { rulesStr[i+1] = c.rules[i].string() } - return fmt.Sprintf("category: %s\n%s\ndefault action: %s", c.category.string(), + return fmt.Sprintf("category: %s\n%s\ndefault action: %s", c.Category.string(), strings.Join(rulesStr, lineSeparatorStr), string(c.defaultAction)) } -func (c *categorySpec) inboundEffectiveRules() string { - rulesStr := make([]string, len(c.processedRules.inbound)) - for i := range c.processedRules.inbound { - rulesStr[i] = c.processedRules.inbound[i].effectiveRuleStr() +func (c *CategorySpec) inboundEffectiveRules() string { + rulesStr := make([]string, len(c.ProcessedRules.Inbound)) + for i := range c.ProcessedRules.Inbound { + rulesStr[i] = c.ProcessedRules.Inbound[i].effectiveRuleStr() } return strings.Join(rulesStr, lineSeparatorStr) } -func (c *categorySpec) outboundEffectiveRules() string { - rulesStr := make([]string, len(c.processedRules.outbound)) - for i := range c.processedRules.outbound { - rulesStr[i] = c.processedRules.outbound[i].effectiveRuleStr() +func (c *CategorySpec) outboundEffectiveRules() string { + rulesStr := make([]string, len(c.ProcessedRules.Outbound)) + for i := range c.ProcessedRules.Outbound { + rulesStr[i] = c.ProcessedRules.Outbound[i].effectiveRuleStr() } return strings.Join(rulesStr, lineSeparatorStr) } -func (c *categorySpec) addRule(src, dst []*endpoints.VM, conn *netset.TransportSet, +func (c *CategorySpec) addRule(src, dst []*endpoints.VM, conn *netset.TransportSet, action, direction string, ruleID int, origRule *collector.Rule, scope []*endpoints.VM, secPolicyName string, origDefaultRule *collector.FirewallRule) { newRule := &FwRule{ srcVMs: src, dstVMs: dst, conn: conn, - action: actionFromString(action), + Action: actionFromString(action), direction: direction, ruleID: ruleID, - origRuleObj: origRule, - origDefaultRuleObj: origDefaultRule, + OrigRuleObj: origRule, + OrigDefaultRuleObj: origDefaultRule, scope: scope, secPolicyName: secPolicyName, - secPolicyCategory: c.category.string(), + secPolicyCategory: c.Category.string(), categoryRef: c, dfwRef: c.dfwRef, - symbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp - symbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp } c.rules = append(c.rules, newRule) inbound, outbound := newRule.effectiveRules() - if c.category != ethernetCategory { - c.processedRules.addInboundRule(inbound) - c.processedRules.addOutboundRule(outbound) + if c.Category != ethernetCategory { + c.ProcessedRules.addInboundRule(inbound) + c.ProcessedRules.addOutboundRule(outbound) } else { logging.Debugf("rule %d in ethernet category is ignored and not added to list of effective rules", ruleID) } } -func newEmptyCategory(c DfwCategory, d *DFW) *categorySpec { - return &categorySpec{ - category: c, +func newEmptyCategory(c DfwCategory, d *DFW) *CategorySpec { + return &CategorySpec{ + Category: c, dfwRef: d, defaultAction: actionNone, - processedRules: &effectiveRules{}, + ProcessedRules: &EffectiveRules{}, } } diff --git a/pkg/model/dfw/dfw.go b/pkg/model/dfw/dfw.go index cd4a641..7d338d9 100644 --- a/pkg/model/dfw/dfw.go +++ b/pkg/model/dfw/dfw.go @@ -13,8 +13,8 @@ import ( ) type DFW struct { - categoriesSpecs []*categorySpec // ordered list of categories - defaultAction ruleAction // global default (?) + CategoriesSpecs []*CategorySpec // ordered list of categories + DefaultAction RuleAction // global default (?) pathsToDisplayNames map[string]string // map from printing paths references as display names instead } @@ -36,8 +36,8 @@ func (d *DFW) AllowedConnectionsIngressOrEgress(src, dst *endpoints.VM, isIngres allDeniedConns := netset.NoTransports() allNotDeterminedConns := netset.NoTransports() - for _, dfwCategory := range d.categoriesSpecs { - if dfwCategory.category == ethernetCategory { + for _, dfwCategory := range d.CategoriesSpecs { + if dfwCategory.Category == ethernetCategory { continue // cuurently skip L2 rules } // get analyzed conns from this category @@ -62,7 +62,7 @@ func (d *DFW) AllowedConnectionsIngressOrEgress(src, dst *endpoints.VM, isIngres allAllowedConns).Subtract(allDeniedConns) } - if d.defaultAction == actionAllow { + if d.DefaultAction == actionAllow { // if the last category has no default, use the "global" default (todo: check where this value is configured in the api) allAllowedConns = allAllowedConns.Union(allNotDeterminedConns) } @@ -75,7 +75,7 @@ func (d *DFW) OriginalRulesStrFormatted() string { writer := tabwriter.NewWriter(&builder, 1, 1, 1, ' ', tabwriter.Debug) fmt.Fprintln(writer, "original rules:") fmt.Fprintln(writer, getRulesFormattedHeaderLine()) - for _, c := range d.categoriesSpecs { + for _, c := range d.CategoriesSpecs { for _, ruleStr := range c.originalRulesStr() { if ruleStr == "" { continue @@ -89,9 +89,9 @@ func (d *DFW) OriginalRulesStrFormatted() string { // return a string rep that shows the fw-rules in all categories func (d *DFW) String() string { - categoriesStrings := make([]string, len(d.categoriesSpecs)) - for i := range d.categoriesSpecs { - categoriesStrings[i] = d.categoriesSpecs[i].string() + categoriesStrings := make([]string, len(d.CategoriesSpecs)) + for i := range d.CategoriesSpecs { + categoriesStrings[i] = d.CategoriesSpecs[i].string() } return strings.Join(categoriesStrings, lineSeparatorStr) } @@ -99,12 +99,12 @@ func (d *DFW) String() string { func (d *DFW) AllEffectiveRules() string { inboundRes := []string{} outboundRes := []string{} - for i := range d.categoriesSpecs { - if len(d.categoriesSpecs[i].processedRules.inbound) > 0 { - inboundRes = append(inboundRes, d.categoriesSpecs[i].inboundEffectiveRules()) + for i := range d.CategoriesSpecs { + if len(d.CategoriesSpecs[i].ProcessedRules.Inbound) > 0 { + inboundRes = append(inboundRes, d.CategoriesSpecs[i].inboundEffectiveRules()) } - if len(d.categoriesSpecs[i].processedRules.outbound) > 0 { - outboundRes = append(outboundRes, d.categoriesSpecs[i].outboundEffectiveRules()) + if len(d.CategoriesSpecs[i].ProcessedRules.Outbound) > 0 { + outboundRes = append(outboundRes, d.CategoriesSpecs[i].outboundEffectiveRules()) } } inbound := fmt.Sprintf("\nInbound effective rules only:%s%s\n", common.ShortSep, strings.Join(inboundRes, lineSeparatorStr)) @@ -116,32 +116,32 @@ func (d *DFW) AllEffectiveRules() string { func (d *DFW) AddRule(src, dst []*endpoints.VM, conn *netset.TransportSet, categoryStr, actionStr, direction string, ruleID int, origRule *collector.Rule, scope []*endpoints.VM, secPolicyName string, origDefaultRule *collector.FirewallRule) { - for _, fwCategory := range d.categoriesSpecs { - if fwCategory.category.string() == categoryStr { + for _, fwCategory := range d.CategoriesSpecs { + if fwCategory.Category.string() == categoryStr { fwCategory.addRule(src, dst, conn, actionStr, direction, ruleID, origRule, scope, secPolicyName, origDefaultRule) } } } /*func (d *DFW) AddRule(src, dst []*endpoints.VM, conn *netset.TransportSet, categoryStr string, actionStr string) { - var categoryObj *categorySpec - for _, c := range d.categoriesSpecs { - if c.category.string() == categoryStr { + var categoryObj *CategorySpec + for _, c := range d.CategoriesSpecs { + if c.Category.string() == categoryStr { categoryObj = c } } - if categoryObj == nil { // create new category if missing - categoryObj = &categorySpec{ - category: dfwCategoryFromString(categoryStr), + if categoryObj == nil { // create new Category if missing + categoryObj = &CategorySpec{ + Category: dfwCategoryFromString(categoryStr), } - d.categoriesSpecs = append(d.categoriesSpecs, categoryObj) + d.CategoriesSpecs = append(d.CategoriesSpecs, categoryObj) } newRule := &FwRule{ srcVMs: src, dstVMs: dst, conn: netset.All(), // todo: change - action: actionFromString(actionStr), + Action: actionFromString(actionStr), } categoryObj.rules = append(categoryObj.rules, newRule) }*/ @@ -149,19 +149,19 @@ func (d *DFW) AddRule(src, dst []*endpoints.VM, conn *netset.TransportSet, categ // NewEmptyDFW returns new DFW with global default as from input func NewEmptyDFW(globalDefaultAllow bool) *DFW { res := &DFW{ - defaultAction: actionDeny, + DefaultAction: actionDeny, } if globalDefaultAllow { - res.defaultAction = actionAllow + res.DefaultAction = actionAllow } for _, c := range categoriesList { - res.categoriesSpecs = append(res.categoriesSpecs, newEmptyCategory(c, res)) + res.CategoriesSpecs = append(res.CategoriesSpecs, newEmptyCategory(c, res)) } return res } func (d *DFW) GlobalDefaultAllow() bool { - return d.defaultAction == actionAllow + return d.DefaultAction == actionAllow } func (d *DFW) SetPathsToDisplayNames(m map[string]string) { diff --git a/pkg/model/dfw/rule.go b/pkg/model/dfw/rule.go index afbfba6..4558ceb 100644 --- a/pkg/model/dfw/rule.go +++ b/pkg/model/dfw/rule.go @@ -15,7 +15,7 @@ import ( nsx "github.com/np-guard/vmware-analyzer/pkg/model/generated" ) -type ruleAction string +type RuleAction string const ( listSeparatorStr = "," @@ -26,13 +26,13 @@ const ( var ingressDirections = []string{"IN", "IN_OUT"}*/ const ( - actionAllow ruleAction = "allow" - actionDeny ruleAction = "deny" // currently not differentiating between "reject" and "drop" - actionJumpToApp ruleAction = "jump_to_application" - actionNone ruleAction = "none" // to mark that a default rule is not configured + actionAllow RuleAction = "allow" + actionDeny RuleAction = "deny" // currently not differentiating between "reject" and "drop" + actionJumpToApp RuleAction = "jump_to_application" + actionNone RuleAction = "none" // to mark that a default rule is not configured ) -/*func actionFromString(input string) ruleAction { +/*func actionFromString(input string) RuleAction { switch input { case string(actionAllow): return actionAllow @@ -44,7 +44,7 @@ const ( return actionDeny }*/ -func actionFromString(s string) ruleAction { +func actionFromString(s string) RuleAction { switch strings.ToLower(s) { case string(actionAllow): return actionAllow @@ -62,20 +62,20 @@ type FwRule struct { dstVMs []*endpoints.VM scope []*endpoints.VM conn *netset.TransportSet - action ruleAction + Action RuleAction direction string // "IN","OUT", "IN_OUT" - origRuleObj *collector.Rule - origDefaultRuleObj *collector.FirewallRule + OrigRuleObj *collector.Rule + OrigDefaultRuleObj *collector.FirewallRule ruleID int secPolicyName string secPolicyCategory string - categoryRef *categorySpec + categoryRef *CategorySpec dfwRef *DFW // clause of symbolic src abd symbolic dst // todo: in order to compute these will have to maintain and use the (not yet exported) synthesis.AbstractModelSyn.atomics // keep it there? - symbolicSrc []*symbolicexpr.SymbolicPath - symbolicDst []*symbolicexpr.SymbolicPath + SymbolicSrc []*symbolicexpr.SymbolicPath + SymbolicDst []*symbolicexpr.SymbolicPath // srcRuleObj ... todo: add a reference to the original rule retrieved from api } @@ -117,13 +117,13 @@ func (f *FwRule) getInboundRule() *FwRule { srcVMs: f.srcVMs, dstVMs: newDest, conn: f.conn, - action: f.action, + Action: f.Action, direction: string(nsx.RuleDirectionIN), - origRuleObj: f.origRuleObj, + OrigRuleObj: f.OrigRuleObj, ruleID: f.ruleID, secPolicyName: f.secPolicyName, - symbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp - symbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp } } @@ -153,13 +153,13 @@ func (f *FwRule) getOutboundRule() *FwRule { srcVMs: newSrc, dstVMs: f.dstVMs, conn: f.conn, - action: f.action, + Action: f.Action, direction: string(nsx.RuleDirectionOUT), - origRuleObj: f.origRuleObj, + OrigRuleObj: f.OrigRuleObj, ruleID: f.ruleID, secPolicyName: f.secPolicyName, - symbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp - symbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicSrc: []*symbolicexpr.SymbolicPath{}, // todo tmp + SymbolicDst: []*symbolicexpr.SymbolicPath{}, // todo tmp } } @@ -192,14 +192,14 @@ func vmsString(vms []*endpoints.VM) string { // return a string representation of a single rule // groups are interpreted to VM members in this representation func (f *FwRule) string() string { - _, _ = f.symbolicSrc, f.symbolicDst // todo tmp for line + _, _ = f.SymbolicSrc, f.SymbolicDst // todo tmp for line return fmt.Sprintf("ruleID: %d, src: %s, dst: %s, conn: %s, action: %s, direction: %s, scope: %s, sec-policy: %s", - f.ruleID, vmsString(f.srcVMs), vmsString(f.dstVMs), f.conn.String(), string(f.action), f.direction, vmsString(f.scope), f.secPolicyName) + f.ruleID, vmsString(f.srcVMs), vmsString(f.dstVMs), f.conn.String(), string(f.Action), f.direction, vmsString(f.scope), f.secPolicyName) } func (f *FwRule) effectiveRuleStr() string { return fmt.Sprintf("ruleID: %d, src: %s, dst: %s, conn: %s, action: %s, direction: %s, sec-policy: %s", - f.ruleID, vmsString(f.srcVMs), vmsString(f.dstVMs), f.conn.String(), string(f.action), f.direction, f.secPolicyName) + f.ruleID, vmsString(f.srcVMs), vmsString(f.dstVMs), f.conn.String(), string(f.Action), f.direction, f.secPolicyName) } func getDefaultRuleScope(r *collector.FirewallRule) string { @@ -247,11 +247,11 @@ func getRulesFormattedHeaderLine() string { "src", "dst", "conn", - "action", + "Action", "direction", "scope", "sec-policy", - "category", + "Category", } return fmt.Sprintf("%s%s%s", common.Red, @@ -265,26 +265,26 @@ func (f *FwRule) originalRuleStr() string { anyStr = "ANY" ) - if f.origRuleObj == nil && f.origDefaultRuleObj == nil { + if f.OrigRuleObj == nil && f.OrigDefaultRuleObj == nil { logging.Debugf("warning: rule %d has no origRuleObj or origDefaultRuleObj", f.ruleID) return "" } // 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 fmt.Sprintf("%s%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s%s", common.Yellow, - *f.origDefaultRuleObj.Id, - *f.origDefaultRuleObj.DisplayName, + *f.OrigDefaultRuleObj.Id, + *f.OrigDefaultRuleObj.DisplayName, // The default rule that gets created will be a any-any rule and applied // to entities specified in the scope of the security policy. anyStr, anyStr, anyStr, - *f.origDefaultRuleObj.Action, - f.origDefaultRuleObj.Direction, - getDefaultRuleScope(f.origDefaultRuleObj), + *f.OrigDefaultRuleObj.Action, + f.OrigDefaultRuleObj.Direction, + getDefaultRuleScope(f.OrigDefaultRuleObj), f.secPolicyName, f.secPolicyCategory, common.Reset, @@ -292,19 +292,19 @@ func (f *FwRule) originalRuleStr() string { } name := "" - if f.origRuleObj.DisplayName != nil { - name = *f.origRuleObj.DisplayName + if f.OrigRuleObj.DisplayName != nil { + name = *f.OrigRuleObj.DisplayName } return fmt.Sprintf("%s%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s%s", common.Yellow, f.ruleID, name, - f.getShortPathsString(f.origRuleObj.SourceGroups), - f.getShortPathsString(f.origRuleObj.DestinationGroups), - // todo: origRuleObj.Services is not always the services, can also be service_entries - f.getShortPathsString(f.origRuleObj.Services), - string(f.action), f.direction, - strings.Join(f.origRuleObj.Scope, listSeparatorStr), + f.getShortPathsString(f.OrigRuleObj.SourceGroups), + f.getShortPathsString(f.OrigRuleObj.DestinationGroups), + // todo: OrigRuleObj.Services is not always the services, can also be service_entries + f.getShortPathsString(f.OrigRuleObj.Services), + string(f.Action), f.direction, + strings.Join(f.OrigRuleObj.Scope, listSeparatorStr), f.secPolicyName, f.secPolicyCategory, common.Reset, diff --git a/pkg/model/parser.go b/pkg/model/parser.go index 26e7128..ec0b9f8 100644 --- a/pkg/model/parser.go +++ b/pkg/model/parser.go @@ -71,7 +71,7 @@ func (p *NSXConfigParser) AddPathsToDisplayNames() { for sPath, sObj := range p.servicePathsToObjects { res[sPath] = *sObj.DisplayName } - p.configRes.fw.SetPathsToDisplayNames(res) + p.configRes.Fw.SetPathsToDisplayNames(res) } // getVMs assigns the parsed VM objects from the NSX resources container into the res config object @@ -92,13 +92,13 @@ func (p *NSXConfigParser) getVMs() { logging.Debugf("warning: ignoring tag scope for VM %s, tag: %s, scope: %s", *vm.DisplayName, tag.Tag, tag.Scope) } } - p.configRes.vms = append(p.configRes.vms, vmObj) + p.configRes.Vms = append(p.configRes.Vms, vmObj) p.configRes.vmsMap[vmObj.ID()] = vmObj } } func (p *NSXConfigParser) getDFW() { - p.configRes.fw = dfw.NewEmptyDFW(false) // TODO: what is global default? + p.configRes.Fw = dfw.NewEmptyDFW(false) // TODO: what is global default? for i := range p.rc.DomainList { domainRsc := p.rc.DomainList[i].Resources for j := range domainRsc.SecurityPolicyList { @@ -147,7 +147,7 @@ func (p *NSXConfigParser) getDFW() { } func (p *NSXConfigParser) addFWRule(r *parsedRule, category string, origRule *collector.Rule) { - p.configRes.fw.AddRule(r.srcVMs, r.dstVMs, r.conn, category, r.action, r.direction, r.ruleID, + p.configRes.Fw.AddRule(r.srcVMs, r.dstVMs, r.conn, category, r.action, r.direction, r.ruleID, origRule, r.scope, r.secPolicyName, r.defaultRuleObj) } diff --git a/pkg/model/parser_test.go b/pkg/model/parser_test.go index 4d62949..8b849e4 100644 --- a/pkg/model/parser_test.go +++ b/pkg/model/parser_test.go @@ -18,7 +18,7 @@ func TestParser(t *testing.T) { t.Fatal(err.Error()) } config := parser.GetConfig() - fmt.Println(config.getConfigInfoStr()) + fmt.Println(config.GetConfigInfoStr()) config.ComputeConnectivity() fmt.Println("analyzed Connectivity") diff --git a/pkg/synthesis/model.go b/pkg/synthesis/model.go index 2e6f106..057754e 100644 --- a/pkg/synthesis/model.go +++ b/pkg/synthesis/model.go @@ -52,13 +52,3 @@ type Segments map[string]*collector.Segment // VMs map from VM name to the VM type VMs map[string]*endpoints.VM - -// ComputeSymbolicRules computes abstract rules in model for synthesis -// todo: will have to combine different categories into a single list of inbound, outbound -// -//nolint:all // todo: tmp for defs without implementation -func computeSymbolicRules(fireWall dfw.DFW) symbolicRules { - _ = fireWall - symbolicexpr.ComputeAllowGivenDenies(&symbolicexpr.SymbolicPaths{}, &symbolicexpr.SymbolicPaths{}) - return symbolicRules{nil, nil} -} diff --git a/pkg/synthesis/symbolicRules.go b/pkg/synthesis/symbolicRules.go new file mode 100644 index 0000000..ec04910 --- /dev/null +++ b/pkg/synthesis/symbolicRules.go @@ -0,0 +1,16 @@ +package synthesis + +import ( + "github.com/np-guard/vmware-analyzer/pkg/model/dfw" + "github.com/np-guard/vmware-analyzer/pkg/symbolicexpr" +) + +// ComputeSymbolicRules computes abstract rules in model for synthesis +// todo: will have to combine different categories into a single list of inbound, outbound +// +//nolint:all // todo: tmp for defs without implementation +func computeSymbolicRules(fireWall dfw.DFW) symbolicRules { + _ = fireWall + symbolicexpr.ComputeAllowGivenDenies(&symbolicexpr.SymbolicPaths{}, &symbolicexpr.SymbolicPaths{}) + return symbolicRules{nil, nil} +} diff --git a/pkg/synthesis/synthesis.go b/pkg/synthesis/synthesis.go new file mode 100644 index 0000000..fedd380 --- /dev/null +++ b/pkg/synthesis/synthesis.go @@ -0,0 +1,56 @@ +package synthesis + +import ( + "fmt" + + "github.com/np-guard/vmware-analyzer/pkg/collector" + "github.com/np-guard/vmware-analyzer/pkg/model" + "github.com/np-guard/vmware-analyzer/pkg/model/dfw" +) + +func NSXSynthesis(recourses *collector.ResourcesContainerModel, params model.OutputParameters) (string, error) { + parser := model.NewNSXConfigParserFromResourcesContainer(recourses) + err := parser.RunParser() + if err != nil { + return "", err + } + config := parser.GetConfig() + + // in debug/verbose mode -- print the parsed config + // logging.Debugf("the parsed config details: %s", config.GetConfigInfoStr()) + + // the following code is temp; just access relevant data + fmt.Println("list of VMs\n===========") + for i, vm := range config.Vms { + fmt.Printf("\t%v. %v\n", i, vm.Name()) + } + + fmt.Println("\nlist of categories\n==============") + for _, category := range config.Fw.CategoriesSpecs { + if len(category.ProcessedRules.Outbound)+len(category.ProcessedRules.Inbound) == 0 { + fmt.Printf("no rules in category %v\n", category.Category) + continue + } + fmt.Printf("\ncategory: %v\n===============\n", category.Category) + tmpPrintRules(category.ProcessedRules.Outbound) + tmpPrintRules(category.ProcessedRules.Inbound) + } + return "", nil +} + +func tmpPrintRules(rules []*dfw.FwRule) { + for _, rule := range rules { + origRule := rule.OrigRuleObj + fmt.Printf("\nruleId %v action %v\n~~~~~~~~~~~~~~~~~~~~~~\nsourceGroups: \n", *origRule.RuleId, rule.Action) + tmpPrintGroup(origRule.SourceGroups) + fmt.Println("\nDestinationGroups:") + tmpPrintGroup(origRule.DestinationGroups) + fmt.Println() + } +} + +func tmpPrintGroup(group []string) { + for _, destinationGroup := range group { + fmt.Printf("\t\t%v ", destinationGroup) + } +} diff --git a/pkg/synthesis/synthesis_test.go b/pkg/synthesis/synthesis_test.go new file mode 100644 index 0000000..0030599 --- /dev/null +++ b/pkg/synthesis/synthesis_test.go @@ -0,0 +1,42 @@ +package synthesis + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/np-guard/vmware-analyzer/pkg/collector/data" + "github.com/np-guard/vmware-analyzer/pkg/logging" + "github.com/np-guard/vmware-analyzer/pkg/model" +) + +type synthesisTest struct { + name string + exData data.Example +} + +var allTests = []synthesisTest{ + { + name: "ExampleDumb", + exData: data.ExampleDumb, + }, +} + +func (a *synthesisTest) run(t *testing.T) { + params := model.OutputParameters{ + Format: "txt", + } + rc := data.ExamplesGeneration(a.exData) + res, err := NSXSynthesis(rc, params) + require.Nil(t, err) + fmt.Println(res) +} + +func TestSynthesis(t *testing.T) { + logging.Init(logging.HighVerbosity) + for i := range allTests { + test := &allTests[i] + test.run(t) + } +}