You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ra...@apache.org on 2021/01/05 17:45:20 UTC

[trafficcontrol] branch master updated: Add atscfg ipallow topology children (#5401)

This is an automated email from the ASF dual-hosted git repository.

rawlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new a1061ab  Add atscfg ipallow topology children (#5401)
a1061ab is described below

commit a1061abf2b690badd63f2658da4f118db0c50566
Author: Robert O Butts <ro...@users.noreply.github.com>
AuthorDate: Tue Jan 5 10:45:07 2021 -0700

    Add atscfg ipallow topology children (#5401)
---
 lib/go-atscfg/atscfg.go                      |  30 ++++
 lib/go-atscfg/ipallowdotconfig.go            |  12 +-
 lib/go-atscfg/ipallowdotconfig_test.go       | 196 ++++++++++++++++++++++-----
 traffic_ops_ort/atstccfg/cfgfile/wrappers.go |   1 +
 4 files changed, 202 insertions(+), 37 deletions(-)

diff --git a/lib/go-atscfg/atscfg.go b/lib/go-atscfg/atscfg.go
index e69db8c..c1c9e42 100644
--- a/lib/go-atscfg/atscfg.go
+++ b/lib/go-atscfg/atscfg.go
@@ -366,6 +366,36 @@ func makeTopologyNameMap(topologies []tc.Topology) map[TopologyName]tc.Topology
 	return topoNames
 }
 
+// getTopologyDirectChildren returns the cachegroups which are immediate children of the given cachegroup in any topology.
+func getTopologyDirectChildren(
+	cg tc.CacheGroupName,
+	topologies []tc.Topology,
+) map[tc.CacheGroupName]struct{} {
+	children := map[tc.CacheGroupName]struct{}{}
+
+	for _, topo := range topologies {
+		svNodeI := -1
+		for nodeI, node := range topo.Nodes {
+			if node.Cachegroup == string(cg) {
+				svNodeI = nodeI
+				break
+			}
+		}
+		if svNodeI < 0 {
+			continue // this cg wasn't in the topology
+		}
+		for _, node := range topo.Nodes {
+			for _, parent := range node.Parents {
+				if parent == svNodeI {
+					children[tc.CacheGroupName(node.Cachegroup)] = struct{}{}
+					break
+				}
+			}
+		}
+	}
+	return children
+}
+
 type parameterWithProfiles struct {
 	tc.Parameter
 	ProfileNames []string
diff --git a/lib/go-atscfg/ipallowdotconfig.go b/lib/go-atscfg/ipallowdotconfig.go
index 40fc5e2..9313b97 100644
--- a/lib/go-atscfg/ipallowdotconfig.go
+++ b/lib/go-atscfg/ipallowdotconfig.go
@@ -52,6 +52,7 @@ func MakeIPAllowDotConfig(
 	server *Server,
 	servers []Server,
 	cacheGroups []tc.CacheGroupNullable,
+	topologies []tc.Topology,
 	hdrComment string,
 ) (Cfg, error) {
 	warnings := []string{}
@@ -168,7 +169,13 @@ func MakeIPAllowDotConfig(
 			return Cfg{}, makeErr(warnings, "server cachegroup not in cachegroups!")
 		}
 
+		childCGNames := getTopologyDirectChildren(tc.CacheGroupName(*server.Cachegroup), topologies)
+
 		childCGs := map[string]tc.CacheGroupNullable{}
+		for cgName, _ := range childCGNames {
+			childCGs[string(cgName)] = cgMap[string(cgName)]
+		}
+
 		for cgName, cg := range cgMap {
 			if (cg.ParentName != nil && *cg.ParentName == *serverCG.Name) || (cg.SecondaryParentName != nil && *cg.SecondaryParentName == *serverCG.Name) {
 				childCGs[cgName] = cg
@@ -190,11 +197,6 @@ func MakeIPAllowDotConfig(
 			// - all children of this server
 			// - all monitors, if this server is a Mid
 			//
-			// TODO: handle Topologies. Mids currently block everything but Edges
-			//       We should decide how to handle that in a post-edge-mid world.
-			//       That probably means adding all child and monitor IPs, and blocking everything else,
-			//       for all non-first-tier caches.
-			//
 			_, isChild := childCGs[*childServer.Cachegroup]
 			if !isChild && (!strings.HasPrefix(server.Type, tc.MidTypePrefix) || (string(childServer.Type) != tc.MonitorTypeName)) {
 				continue
diff --git a/lib/go-atscfg/ipallowdotconfig_test.go b/lib/go-atscfg/ipallowdotconfig_test.go
index ed6dc0a..64880e5 100644
--- a/lib/go-atscfg/ipallowdotconfig_test.go
+++ b/lib/go-atscfg/ipallowdotconfig_test.go
@@ -39,15 +39,15 @@ func TestMakeIPAllowDotConfig(t *testing.T) {
 	})
 
 	svs := []Server{
-		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64"),
-		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64"),
-		*makeIPAllowChild("child2", "192.168.2.150", ""),
-		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64"),
-		*makeIPAllowChild("child4", "", "192.168.2.155/32"),
-		*makeIPAllowChild("child5", "", "2001:DB8:3::1"),
-		*makeIPAllowChild("child6", "", "2001:DB8:2::3"),
-		*makeIPAllowChild("child7", "", "2001:DB8:2::4"),
-		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64"),
+		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child2", "192.168.2.150", "", tc.MonitorTypeName),
+		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child4", "", "192.168.2.155/32", tc.MonitorTypeName),
+		*makeIPAllowChild("child5", "", "2001:DB8:3::1", tc.MonitorTypeName),
+		*makeIPAllowChild("child6", "", "2001:DB8:2::3", tc.MonitorTypeName),
+		*makeIPAllowChild("child7", "", "2001:DB8:2::4", tc.MonitorTypeName),
+		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64", tc.MonitorTypeName),
 	}
 
 	expecteds := []string{
@@ -76,7 +76,9 @@ func TestMakeIPAllowDotConfig(t *testing.T) {
 	sv.Cachegroup = cgs[0].Name
 	svs = append(svs, *sv)
 
-	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, hdr)
+	topologies := []tc.Topology{}
+
+	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, topologies, hdr)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -137,15 +139,15 @@ func TestMakeIPAllowDotConfigEdge(t *testing.T) {
 	})
 
 	svs := []Server{
-		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64"),
-		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64"),
-		*makeIPAllowChild("child2", "192.168.2.150", ""),
-		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64"),
-		*makeIPAllowChild("child4", "", "192.168.2.155/32"),
-		*makeIPAllowChild("child5", "", "2001:DB8:3::1"),
-		*makeIPAllowChild("child6", "", "2001:DB8:2::3"),
-		*makeIPAllowChild("child7", "", "2001:DB8:2::4"),
-		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64"),
+		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child2", "192.168.2.150", "", tc.MonitorTypeName),
+		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child4", "", "192.168.2.155/32", tc.MonitorTypeName),
+		*makeIPAllowChild("child5", "", "2001:DB8:3::1", tc.MonitorTypeName),
+		*makeIPAllowChild("child6", "", "2001:DB8:2::3", tc.MonitorTypeName),
+		*makeIPAllowChild("child7", "", "2001:DB8:2::4", tc.MonitorTypeName),
+		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64", tc.MonitorTypeName),
 	}
 
 	expecteds := []string{
@@ -172,7 +174,9 @@ func TestMakeIPAllowDotConfigEdge(t *testing.T) {
 	sv.Cachegroup = cgs[0].Name
 	svs = append(svs, *sv)
 
-	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, hdr)
+	topologies := []tc.Topology{}
+
+	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, topologies, hdr)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -219,15 +223,15 @@ func TestMakeIPAllowDotConfigNonDefaultV6Number(t *testing.T) {
 	})
 
 	svs := []Server{
-		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64"),
-		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64"),
-		*makeIPAllowChild("child2", "192.168.2.150", ""),
-		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64"),
-		*makeIPAllowChild("child4", "", "192.168.2.155/32"),
-		*makeIPAllowChild("child5", "", "2001:DB8:3::1"),
-		*makeIPAllowChild("child6", "", "2001:DB8:2::3"),
-		*makeIPAllowChild("child7", "", "2001:DB8:2::4"),
-		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64"),
+		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child2", "192.168.2.150", "", tc.MonitorTypeName),
+		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64", tc.MonitorTypeName),
+		*makeIPAllowChild("child4", "", "192.168.2.155/32", tc.MonitorTypeName),
+		*makeIPAllowChild("child5", "", "2001:DB8:3::1", tc.MonitorTypeName),
+		*makeIPAllowChild("child6", "", "2001:DB8:2::3", tc.MonitorTypeName),
+		*makeIPAllowChild("child7", "", "2001:DB8:2::4", tc.MonitorTypeName),
+		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64", tc.MonitorTypeName),
 	}
 
 	expecteds := []string{
@@ -256,7 +260,9 @@ func TestMakeIPAllowDotConfigNonDefaultV6Number(t *testing.T) {
 	sv.Cachegroup = cgs[0].Name
 	svs = append(svs, *sv)
 
-	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, hdr)
+	topologies := []tc.Topology{}
+
+	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, topologies, hdr)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -286,11 +292,137 @@ func TestMakeIPAllowDotConfigNonDefaultV6Number(t *testing.T) {
 	}
 }
 
-func makeIPAllowChild(name string, ip string, ip6 string) *Server {
+func TestMakeIPAllowDotConfigTopologies(t *testing.T) {
+	hdr := "myHeaderComment"
+
+	params := makeParamsFromMapArr("serverProfile", IPAllowConfigFileName, map[string][]string{
+		"purge_allow_ip":       []string{"192.168.2.99"},
+		ParamCoalesceMaskLenV4: []string{"24"},
+		ParamCoalesceNumberV4:  []string{"3"},
+		ParamCoalesceMaskLenV6: []string{"48"},
+		ParamCoalesceNumberV6:  []string{"4"},
+	})
+
+	// make children all MID types, because MIDs would never normally be parented to MIDs with pre-topologies
+	svs := []Server{
+		*makeIPAllowChild("child0", "192.168.2.1", "2001:DB8:1::1/64", tc.MidTypePrefix),
+		*makeIPAllowChild("child1", "192.168.2.100/30", "2001:DB8:2::1/64", tc.MidTypePrefix),
+		*makeIPAllowChild("child2", "192.168.2.150", "", tc.MidTypePrefix),
+		*makeIPAllowChild("child3", "", "2001:DB8:2::2/64", tc.MidTypePrefix),
+		*makeIPAllowChild("child4", "", "192.168.2.155/32", tc.MidTypePrefix),
+		*makeIPAllowChild("child5", "", "2001:DB8:3::1", tc.MidTypePrefix),
+		*makeIPAllowChild("child6", "", "2001:DB8:2::3", tc.MidTypePrefix),
+		*makeIPAllowChild("child7", "", "2001:DB8:2::4", tc.MidTypePrefix),
+		*makeIPAllowChild("child8", "", "2001:DB8:2::5/64", tc.MidTypePrefix),
+	}
+
+	expecteds := []string{
+		"127.0.0.1",
+		"::1",
+		"0.0.0.0-255.255.255.255",
+		"::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+		"172.16.0.0-172.31.255.255",
+		"10.0.0.0-10.255.255.255",
+		"2001:db8:3::1",
+		"192.168.2.0-192.168.2.255",
+		"192.168.2.99",
+		"2001:db8:1::-2001:db8:1:0:ffff:ffff:ffff:ffff",
+		"2001:db8:2::-2001:db8:2:ffff:ffff:ffff:ffff:ffff",
+	}
+
+	cgs := []tc.CacheGroupNullable{
+		tc.CacheGroupNullable{
+			Name: util.StrPtr("midcg"),
+		},
+		tc.CacheGroupNullable{
+			Name: util.StrPtr("midcg2"),
+		},
+		tc.CacheGroupNullable{
+			Name: util.StrPtr("childcg"),
+		},
+	}
+
+	topologies := []tc.Topology{
+		tc.Topology{
+			Name: "t0",
+			Nodes: []tc.TopologyNode{
+				tc.TopologyNode{
+					Cachegroup: "childcg",
+					Parents:    []int{1, 2},
+				},
+				tc.TopologyNode{
+					Cachegroup: "midcg",
+				},
+				tc.TopologyNode{
+					Cachegroup: "midcg2",
+				},
+			},
+		},
+	}
+
+	sv := &Server{}
+	sv.HostName = util.StrPtr("server0")
+	sv.Type = string(tc.CacheTypeMid)
+	sv.Cachegroup = cgs[1].Name
+	svs = append(svs, *sv)
+
+	//	topologies := []tc.Topology{}
+
+	cfg, err := MakeIPAllowDotConfig(params, sv, svs, cgs, topologies, hdr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	txt := cfg.Text
+
+	lines := strings.Split(txt, "\n")
+
+	if len(lines) == 0 {
+		t.Fatalf("expected: lines actual: no lines\n")
+	}
+
+	commentLine := lines[0]
+	commentLine = strings.TrimSpace(commentLine)
+	if !strings.HasPrefix(commentLine, "#") {
+		t.Errorf("expected: comment line starting with '#', actual: '%v'\n", commentLine)
+	}
+	if !strings.Contains(commentLine, hdr) {
+		t.Errorf("expected: comment line containing header comment '%v', actual: '%v'\n", hdr, commentLine)
+	}
+
+	lines = lines[1:] // remove comment line
+
+	/* Test that PUSH and PURGE are denied ere the allowance of anything else. */
+	{
+		ip4deny := false
+		ip6deny := false
+	eachLine:
+		for i, line := range lines {
+			switch {
+			case strings.Contains(line, `0.0.0.0-255.255.255.255`) && strings.Contains(line, `ip_deny`) && strings.Contains(line, `PUSH`) && strings.Contains(line, `PURGE`):
+				ip4deny = true
+			case strings.Contains(line, `::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`) && strings.Contains(line, `ip_deny`) && strings.Contains(line, `PUSH`) && strings.Contains(line, `PURGE`):
+				ip6deny = true
+			case strings.Contains(line, `ip_allow`):
+				if !(ip4deny && ip6deny) {
+					t.Errorf("Expected denies for PUSH and PURGE before any ips are allowed; pre-denial allowance on line %d.", i+1)
+				}
+				break eachLine
+			}
+		}
+	}
+
+	for _, expected := range expecteds {
+		if !strings.Contains(txt, expected) {
+			t.Errorf("expected %+v actual '%v'\n", expected, txt)
+		}
+	}
+}
+
+func makeIPAllowChild(name string, ip string, ip6 string, serverType string) *Server {
 	sv := &Server{}
 	sv.Cachegroup = util.StrPtr("childcg")
 	sv.HostName = util.StrPtr("child0")
-	sv.Type = tc.MonitorTypeName
+	sv.Type = serverType
 	setIPInfo(sv, "eth0", ip, ip6)
 	return sv
 }
diff --git a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
index b189b5b..ff049e4 100644
--- a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
+++ b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
@@ -93,6 +93,7 @@ func MakeIPAllowDotConfig(toData *config.TOData, fileName string, hdrCommentTxt
 		toData.Server,
 		toData.Servers,
 		toData.CacheGroups,
+		toData.Topologies,
 		hdrCommentTxt,
 	)
 }