Skip to content

Commit

Permalink
subnet-grouping2 (#245)
Browse files Browse the repository at this point in the history
* init

* go 20

* go 20

* not 1.2

* ShowOnSubnetMode for tgw

* use go-version-file

* CR from Ziv

* removing subnetMode flag

* does not work

* another try

* change subnetmode Location

* test

* lint

* code review

* documenting

* using maps from golang 21

* code review

* not use pointer to map

* handle pointers to string

* adding tests to main
  • Loading branch information
haim-kermany authored Jan 1, 2024
1 parent 5e8359e commit 1f34021
Show file tree
Hide file tree
Showing 19 changed files with 1,279 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe
with:
go-version: 1.21
go-version-file: ./go.mod

- name: Build
env:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
name: golangci-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe
with:
go-version: 1.21
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
go-version-file: ./go.mod
- uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc
23 changes: 23 additions & 0 deletions cmd/analyzer/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"strings"
"testing"
)

func Test_main(t *testing.T) {
tests := []struct {
name string
args string
}{
{"drawio_multi_vpc", "-output-file aaa.drawio -vpc-config ../../pkg/ibmvpc/examples/input_multiple_vpcs.json -format drawio"},
{"txt_multi_vpc", "-output-file aaa.txt -vpc-config ../../pkg/ibmvpc/examples/input_multiple_vpcs.json -format txt"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := _main(strings.Split(tt.args, " ")); err != nil {
t.Errorf("_main(), name %s, error = %v", tt.name, err)
}
})
}
}
53 changes: 53 additions & 0 deletions pkg/common/genericSet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package common

import (
"fmt"
"reflect"
"sort"
"strings"
)

// //////////////////////////////////////////////////////////////////////////////////////////////

// a genericSet is a generic implementation of a set.
// the main functionality of genericSet is asKey() - conversion to a string.
// asKey() is needed for using genericSet as a key of a map
// //////////////////////////////////////////////////////////////////////////////////////////////

type GenericSet[T comparable] map[T]bool
type SetAsKey string

func (s GenericSet[T]) AsKey() SetAsKey {
ss := []string{}
for i := range s {
key := ""
rv := reflect.ValueOf(i)
if rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface {
key = fmt.Sprintf("%x", rv.Pointer())
} else {
key = fmt.Sprint(i)
}
ss = append(ss, key)
}
sort.Strings(ss)
return SetAsKey(strings.Join(ss, ","))
}

func (s GenericSet[T]) AsList() []T {
keys := make([]T, len(s))
i := 0
for k := range s {
keys[i] = k
i++
}
return keys
}

func (s GenericSet[T]) IsIntersect(s2 GenericSet[T]) bool {
for i := range s {
if (s2)[i] {
return true
}
}
return false
}
20 changes: 11 additions & 9 deletions pkg/drawio/abstractTreeNode.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ const (
)

type abstractTreeNode struct {
id uint
x int
y int
name string
width int
height int
parent TreeNodeInterface
location *Location
id uint
x int
y int
name string
width int
height int
parent TreeNodeInterface
location *Location
doNotShowInDrawio bool
}

func (tn *abstractTreeNode) Label() string { return tn.name }
Expand Down Expand Up @@ -51,7 +52,8 @@ func (tn *abstractTreeNode) DrawioParent() TreeNodeInterface { return tn.parent

func (tn *abstractTreeNode) setLocation(location *Location) { tn.location = location }
func (tn *abstractTreeNode) setParent(p TreeNodeInterface) { tn.parent = p }
func (tn *abstractTreeNode) NotShownInDrawio() bool { return false }
func (tn *abstractTreeNode) NotShownInDrawio() bool { return tn.doNotShowInDrawio }
func (tn *abstractTreeNode) SetNotShownInDrawio() { tn.doNotShowInDrawio = true }

var idCounter uint = minID

Expand Down
13 changes: 9 additions & 4 deletions pkg/drawio/createMapFile.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@ func (data *drawioData) ElementComment(tn TreeNodeInterface) string {
// (the last in the file will be on top in the canvas)
// 1. we put the lines at the top so they will overlap the icons
// 2. we put the icons above the squares so we can mouse over it for tooltips
// 3. we put the sgs in the bottom. if a sg is above a square, it will block the the tooltip of the children of the square.
// 3. we put the sgs and the gs in the bottom.
// (if a sg ot a gs is above a square, it will block the the tooltip of the children of the square.)
func orderNodesForDrawio(nodes []TreeNodeInterface) []TreeNodeInterface {
var sg, sq, ln, ic, orderedNodes []TreeNodeInterface
var sg, sq, ln, ic, gs, orderedNodes []TreeNodeInterface
for _, tn := range nodes {
switch {
case reflect.TypeOf(tn).Elem() == reflect.TypeOf(PartialSGTreeNode{}):
sg = append(sg, tn)
case tn.IsSquare() && tn.(SquareTreeNodeInterface).IsGroupingSquare(),
tn.IsSquare() && tn.(SquareTreeNodeInterface).IsGroupSubnetsSquare():
gs = append(gs, tn)
case tn.IsSquare():
sq = append(sq, tn)
case tn.IsIcon():
Expand All @@ -57,15 +61,16 @@ func orderNodesForDrawio(nodes []TreeNodeInterface) []TreeNodeInterface {
ln = append(ln, tn)
}
}
orderedNodes = append(orderedNodes, gs...)
orderedNodes = append(orderedNodes, sg...)
orderedNodes = append(orderedNodes, sq...)
orderedNodes = append(orderedNodes, ic...)
orderedNodes = append(orderedNodes, ln...)
return orderedNodes
}

func CreateDrawioConnectivityMapFile(network SquareTreeNodeInterface, outputFile string) error {
newLayout(network).layout()
func CreateDrawioConnectivityMapFile(network SquareTreeNodeInterface, outputFile string, subnetMode bool) error {
newLayout(network, subnetMode).layout()

return writeDrawioFile(NewDrawioData(network), outputFile)
}
Expand Down
69 changes: 64 additions & 5 deletions pkg/drawio/drawio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,37 @@ import (

func TestWithParsing(t *testing.T) {
n := createNetwork()
err := CreateDrawioConnectivityMapFile(n, "fake.drawio")
err := CreateDrawioConnectivityMapFile(n, "fake.drawio", false)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}
n = createNetwork2()
err = CreateDrawioConnectivityMapFile(n, "fake2.drawio")
err = CreateDrawioConnectivityMapFile(n, "fake2.drawio", false)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}
n = createNetworkGrouping()
err = CreateDrawioConnectivityMapFile(n, "grouping.drawio")
err = CreateDrawioConnectivityMapFile(n, "grouping.drawio", false)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}
n = createNetworkSubnetGrouping()
err = CreateDrawioConnectivityMapFile(n, "subnetGrouping.drawio", true)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}

n2 := NewNetworkTreeNode()
NewCloudTreeNode(n2, "empty Cloud")
NewPublicNetworkTreeNode(n2)
NewCloudTreeNode(n2, "empty cloud2")
err = CreateDrawioConnectivityMapFile(n2, "fake3.drawio")
err = CreateDrawioConnectivityMapFile(n2, "fake3.drawio", false)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}

n = createNetworkAllTypes()
err = CreateDrawioConnectivityMapFile(n, "all.drawio")
err = CreateDrawioConnectivityMapFile(n, "all.drawio", false)
if err != nil {
fmt.Println("Error when calling CreateDrawioConnectivityMapFile():", err)
}
Expand Down Expand Up @@ -278,6 +284,59 @@ func createNetworkAllTypes() SquareTreeNodeInterface {
return network
}

func createZone(zones *[][]SquareTreeNodeInterface, vpc *VpcTreeNode, size int, name string) {
zone := NewZoneTreeNode(vpc, name)
subnets := make([]SquareTreeNodeInterface, size)
*zones = append(*zones, subnets)
for i := 0; i < size; i++ {
sname := fmt.Sprint(name, i)
subnets[i] = NewSubnetTreeNode(zone, sname, "", "")
}
}
func createGroup(zones *[][]SquareTreeNodeInterface, vpc *VpcTreeNode, i1, i2, j1, j2 int) SquareTreeNodeInterface {
gr := []SquareTreeNodeInterface{}
for i := i1; i <= i2; i++ {
for j := j1; j <= j2; j++ {
gr = append(gr, (*zones)[i][j])
}
}
g := GroupedSubnetsSquare(vpc, gr)
g.(*GroupSubnetsSquareTreeNode).name = fmt.Sprintf("%d-%d,%d,%d", i1, i2, j1, j2)
return g
}

func createNetworkSubnetGrouping() SquareTreeNodeInterface {
network := NewNetworkTreeNode()
zones := &[][]SquareTreeNodeInterface{}
cloud1 := NewCloudTreeNode(network, "IBM Cloud")
publicNetwork := NewPublicNetworkTreeNode(network)
vpc1 := NewVpcTreeNode(cloud1, "vpc1")
for i := 0; i < 10; i++ {
createZone(zones, vpc1, 8, fmt.Sprintf("z%d", i))
}
groups := []SquareTreeNodeInterface{
createGroup(zones, vpc1, 0, 0, 0, 1),
createGroup(zones, vpc1, 1, 1, 0, 1),
createGroup(zones, vpc1, 0, 2, 0, 6),
createGroup(zones, vpc1, 0, 2, 4, 6),
createGroup(zones, vpc1, 3, 3, 1, 2),
createGroup(zones, vpc1, 2, 3, 1, 2),
createGroup(zones, vpc1, 0, 4, 0, 3),
createGroup(zones, vpc1, 0, 5, 0, 3),

createGroup(zones, vpc1, 6, 7, 0, 1),
createGroup(zones, vpc1, 6, 6, 2, 3),
createGroup(zones, vpc1, 7, 8, 1, 2),
}
NewConnectivityLineTreeNode(network, groups[0], groups[len(groups)-1], true, "gconn")

for _, gr := range groups {
i1 := NewInternetTreeNode(publicNetwork, "I "+gr.Label())
NewConnectivityLineTreeNode(network, gr, i1, true, "gconn "+gr.Label())
}
return network
}

func createNetworkGrouping() SquareTreeNodeInterface {
network := NewNetworkTreeNode()
publicNetwork := NewPublicNetworkTreeNode(network)
Expand Down
Loading

0 comments on commit 1f34021

Please sign in to comment.