Skip to content

Commit

Permalink
aws public subnet explainability (#775)
Browse files Browse the repository at this point in the history
* add explainability

* mock

* IsPrivate

* not public

* small i
  • Loading branch information
haim-kermany authored Aug 14, 2024
1 parent 62a3ab7 commit de56336
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 39 deletions.
4 changes: 2 additions & 2 deletions pkg/awsvpc/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func (rc *AWSresourcesContainer) getSubnetsConfig(
if err != nil {
return nil, err
}
subnet.SetIsPublic(*subnetObj.MapPublicIpOnLaunch)
subnet.SetIsPrivate(!*subnetObj.MapPublicIpOnLaunch)
}
return vpcInternalAddressRange, nil
}
Expand Down Expand Up @@ -398,7 +398,7 @@ func (rc *AWSresourcesContainer) getIgwConfig(
subnets := vpc.Subnets()
// only public subnets can be a subnet of igw:
subnets = slices.DeleteFunc(subnets, func(s *commonvpc.Subnet) bool {
return !s.IsPublic()
return s.IsPrivate()
})

if len(subnets) == 0 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/commonvpc/drawioGenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *Subnet) GenerateDrawioTreeNode(gen *vpcmodel.DrawioGenerator) drawio.Tr
zone, _ := s.Zone()
zoneTn := gen.TreeNode(zone).(*drawio.ZoneTreeNode)
subnetTn := drawio.NewSubnetTreeNode(zoneTn, s.Name(), s.Cidr, "")
subnetTn.SetIsPublic(s.isPublic)
subnetTn.SetIsPrivate(s.IsPrivate())
return subnetTn
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/commonvpc/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ type Subnet struct {
VPCnodes []vpcmodel.Node `json:"-"`
Cidr string `json:"-"`
IPblock *ipblock.IPBlock `json:"-"`
// isPublic is relevant only for aws, the user set for each subnet if it public (i.e. - has access to the internet)
isPublic bool `json:"-"`
// isPrivate is relevant only for aws, the user set for each subnet if it public (i.e. - has access to the internet)
isPrivate bool `json:"-"`
}

func (s *Subnet) CIDR() string {
Expand All @@ -144,11 +144,11 @@ func (s *Subnet) Nodes() []vpcmodel.Node {
func (s *Subnet) AddressRange() *ipblock.IPBlock {
return s.IPblock
}
func (s *Subnet) IsPublic() bool {
return s.isPublic
func (s *Subnet) IsPrivate() bool {
return s.isPrivate
}
func (s *Subnet) SetIsPublic(isPublic bool) {
s.isPublic = isPublic
func (s *Subnet) SetIsPrivate(isPrivate bool) {
s.isPrivate = isPrivate
}

type Vsi struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/drawio/drawio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ func createNetworkAws() SquareTreeNodeInterface {
for i := 0; i < len(nis); i++ {
zone := NewZoneTreeNode(vpc, "zone1")
subnet := NewSubnetTreeNode(zone, "subnet2", "cidr1", "acl1")
subnet.SetIsPublic(i <= 1)
subnet.SetIsPrivate(i > 1)
nis[i] = NewNITreeNode(subnet, "ni20")
sg.AddIcon(nis[i])
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/drawio/squareTreeNode.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ type SubnetTreeNode struct {
groupSquares []SquareTreeNodeInterface
cidr string
acl string
isPublic bool
isPrivate bool
}

func NewSubnetTreeNode(parent *ZoneTreeNode, name, cidr, acl string) *SubnetTreeNode {
Expand Down Expand Up @@ -273,8 +273,8 @@ func (tn *SubnetTreeNode) nonGroupingIcons() []IconTreeNodeInterface {
}
return nis
}
func (tn *SubnetTreeNode) IsPublic() bool { return tn.isPublic }
func (tn *SubnetTreeNode) SetIsPublic(isPublic bool) { tn.isPublic = isPublic }
func (tn *SubnetTreeNode) IsPrivate() bool { return tn.isPrivate }
func (tn *SubnetTreeNode) SetIsPrivate(isPrivate bool) { tn.isPrivate = isPrivate }

// /////////////////////////////////////////////////////////////////////////////////////
// GroupSquareTreeNode is a tree node that represents a group of icons that share the same connectivity
Expand Down
6 changes: 3 additions & 3 deletions pkg/drawio/styles.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ func (stl *templateStyles) representingType(tn TreeNodeInterface) reflect.Type {
if stl.provider != common.AWS || reflect.TypeOf(tn).Elem() != reflect.TypeOf(SubnetTreeNode{}) {
return reflect.TypeOf(tn).Elem()
}
if tn.(*SubnetTreeNode).IsPublic() {
return reflect.TypeOf(publicSubnetTreeNode{})
if tn.(*SubnetTreeNode).IsPrivate() {
return reflect.TypeOf(privateSubnetTreeNode{})
}
return reflect.TypeOf(privateSubnetTreeNode{})
return reflect.TypeOf(publicSubnetTreeNode{})
}

func (stl *templateStyles) Image(tn TreeNodeInterface) string {
Expand Down
1 change: 1 addition & 0 deletions pkg/vpcmodel/abstractVPC.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ type VPC interface {
type Subnet interface {
NodeSet
CIDR() string
IsPrivate() bool
}

// LoadBalancer is elaboration of a NodeSet - the nodes are the private IPs of the load balancer
Expand Down
13 changes: 13 additions & 0 deletions pkg/vpcmodel/explainabilityPrint.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ func respondDetailsHeader(d *detailedConn) string {
}
}

func isAtPrivateSubnet(endpoint EndpointElem) bool {
if internalNode, ok := endpoint.(InternalNodeIntf); ok {
return internalNode.Subnet().IsPrivate()
}
return false
}

// after all data is gathered, generates the actual string to be printed
func (g *groupedConnLine) explainPerCaseStr(c *VPCConfig, src, dst EndpointElem,
connQuery, crossVpcConnection *connection.Set, ingressBlocking, egressBlocking, loadBalancerBlocking bool,
Expand All @@ -206,6 +213,12 @@ func (g *groupedConnLine) explainPerCaseStr(c *VPCConfig, src, dst EndpointElem,
case crossVpcRouterRequired(src, dst) && crossVpcRouter != nil && crossVpcConnection.IsEmpty():
return fmt.Sprintf("%vAll connections will be blocked since transit gateway denies route from source to destination"+tripleNLVars,
noConnection, headerPlusPath, details)
case isAtPrivateSubnet(dst) && src.IsExternal():
return fmt.Sprintf("%v\tthe subnet of %v is not public and does not enable inbound external connectivity\n",
noConnection, dst.Name())
case isAtPrivateSubnet(src) && dst.IsExternal():
return fmt.Sprintf("%v\tThe dst is external but the subnet of %v is not public\n",
noConnection, src.Name())
case externalRouter == nil && src.IsExternal():
return fmt.Sprintf("%v\tThere is no resource enabling inbound external connectivity\n", noConnection)
case externalRouter == nil && dst.IsExternal():
Expand Down
17 changes: 10 additions & 7 deletions pkg/vpcmodel/grouping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ func (mockVPC *mockVPCIntf) GenerateDrawioTreeNode(gen *DrawioGenerator) drawio.
func (mockVPC *mockVPCIntf) ShowOnSubnetMode() bool { return true }

type mockNetIntf struct {
cidr string
isPublic bool
name string
subnet Subnet
cidr string
isExternal bool
name string
subnet Subnet
}

func (m *mockNetIntf) CidrOrAddress() string {
Expand All @@ -49,10 +49,10 @@ func (m *mockNetIntf) Subnet() Subnet {
}

func (m *mockNetIntf) IsInternal() bool {
return !m.isPublic
return !m.isExternal
}
func (m *mockNetIntf) IsPublicInternet() bool {
return m.isPublic
return m.isExternal
}
func (m *mockNetIntf) AbstractedToNodeSet() NodeSet {
return nil
Expand Down Expand Up @@ -84,7 +84,7 @@ func (m *mockNetIntf) RegionName() string {
func (m *mockNetIntf) GenerateDrawioTreeNode(gen *DrawioGenerator) drawio.TreeNodeInterface {
return nil
}
func (m *mockNetIntf) IsExternal() bool { return m.isPublic }
func (m *mockNetIntf) IsExternal() bool { return m.isExternal }
func (m *mockNetIntf) ShowOnSubnetMode() bool { return false }

func (m *mockNetIntf) VPC() VPCResourceIntf {
Expand Down Expand Up @@ -123,6 +123,9 @@ func (m *mockSubnet) AddressRange() *ipblock.IPBlock {
func (m *mockSubnet) CIDR() string {
return m.cidr
}
func (m *mockSubnet) IsPrivate() bool {
return true
}
func (m *mockSubnet) Connectivity() *ConnectivityResult {
return nil
}
Expand Down
32 changes: 16 additions & 16 deletions pkg/vpcmodel/semanticDiff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,17 @@ func configSimpleIPAndSubnetDiff() (subnetConfigConn1, subnetConfigConn2 *config
cfg1.Subnets = append(cfg1.Subnets, &mockSubnet{nil, "10.1.20.0/22", "subnet1", nil},
&mockSubnet{nil, "10.2.20.0/22", "subnet2", nil})
cfg1.Nodes = append(cfg1.Nodes,
&mockNetIntf{cidr: "1.2.3.0/30", name: "public1-1", isPublic: true},
&mockNetIntf{cidr: "250.2.4.0/24", name: "public1-2", isPublic: true},
&mockNetIntf{cidr: "200.2.4.0/24", name: "public1-3", isPublic: true})
&mockNetIntf{cidr: "1.2.3.0/30", name: "public1-1", isExternal: true},
&mockNetIntf{cidr: "250.2.4.0/24", name: "public1-2", isExternal: true},
&mockNetIntf{cidr: "200.2.4.0/24", name: "public1-3", isExternal: true})

cfg2 := &VPCConfig{}
cfg2.Subnets = append(cfg2.Subnets, &mockSubnet{nil, "10.1.20.0/22", "subnet1", nil},
&mockSubnet{nil, "10.2.20.0/22", "subnet2", nil})
cfg2.Nodes = append(cfg2.Nodes,
&mockNetIntf{cidr: "1.2.3.0/26", name: "public2-1", isPublic: true},
&mockNetIntf{cidr: "250.2.4.0/30", name: "public2-2", isPublic: true},
&mockNetIntf{cidr: "200.2.4.0/24", name: "public1-3", isPublic: true})
&mockNetIntf{cidr: "1.2.3.0/26", name: "public2-1", isExternal: true},
&mockNetIntf{cidr: "250.2.4.0/30", name: "public2-2", isExternal: true},
&mockNetIntf{cidr: "200.2.4.0/24", name: "public1-3", isExternal: true})

// cfg1 cfg2
// <subnet2, public1-1> and <subnet2, public2-1> are comparable
Expand Down Expand Up @@ -272,22 +272,22 @@ func TestSimpleIPAndSubnetDiffGrouping(t *testing.T) {
func configSimpleVsisDiff() (configConn1, configConn2 *configConnectivity) {
cfg1 := &VPCConfig{}
cfg1.Nodes = append(cfg1.Nodes,
&mockNetIntf{name: "vsi0", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi1", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi2", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi3", isPublic: false, cidr: ""},
&mockNetIntf{cidr: "1.2.3.0/30", name: "public1-1", isPublic: true})
&mockNetIntf{name: "vsi0", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi1", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi2", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi3", isExternal: false, cidr: ""},
&mockNetIntf{cidr: "1.2.3.0/30", name: "public1-1", isExternal: true})

cfg1.Subnets = append(cfg1.Subnets, &mockSubnet{nil, "10.0.20.0/22", "subnet0", []Node{cfg1.Nodes[0], cfg1.Nodes[1],
cfg1.Nodes[2], cfg1.Nodes[3]}})

cfg2 := &VPCConfig{}
cfg2.Nodes = append(cfg2.Nodes,
&mockNetIntf{name: "vsi1", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi2", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi3", isPublic: false, cidr: ""},
&mockNetIntf{name: "vsi4", isPublic: false, cidr: ""},
&mockNetIntf{cidr: "1.2.3.0/26", name: "public2-1", isPublic: true})
&mockNetIntf{name: "vsi1", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi2", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi3", isExternal: false, cidr: ""},
&mockNetIntf{name: "vsi4", isExternal: false, cidr: ""},
&mockNetIntf{cidr: "1.2.3.0/26", name: "public2-1", isExternal: true})

cfg2.Subnets = append(cfg2.Subnets, &mockSubnet{nil, "10.0.20.0/22", "subnet0", []Node{cfg2.Nodes[0], cfg2.Nodes[1],
cfg2.Nodes[2], cfg2.Nodes[3]}})
Expand Down

0 comments on commit de56336

Please sign in to comment.