Skip to content

Commit

Permalink
Fix cache config for https origins
Browse files Browse the repository at this point in the history
  • Loading branch information
rob05c committed Aug 13, 2021
1 parent f6b71a5 commit 2b42366
Show file tree
Hide file tree
Showing 5 changed files with 936 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#5981](https://github.com/apache/trafficcontrol/issues/5891) - `/deliveryservices/{{ID}}/safe` returns incorrect response for the requested API version
- [#5984](https://github.com/apache/trafficcontrol/issues/5894) - `/servers/{{ID}}/deliveryservices` returns incorrect response for the requested API version
- [#6027](https://github.com/apache/trafficcontrol/issues/6027) - Collapsed DB migrations
- [#6091](https://github.com/apache/trafficcontrol/issues/6091) - Fixed cache config of internal cache communication for https origins
- [#6066](https://github.com/apache/trafficcontrol/issues/6066) - Fixed missing/incorrect indices on some tables
- [#5576](https://github.com/apache/trafficcontrol/issues/5576) - Inconsistent Profile Name restrictions

Expand Down
42 changes: 29 additions & 13 deletions lib/go-atscfg/parentdotconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,15 @@ func MakeParentDotConfig(
parentQStr = "consider"
}

orgURI, orgWarns, err := getOriginURI(*ds.OrgServerFQDN)
orgFQDNStr := *ds.OrgServerFQDN
// if this cache isn't the last tier, i.e. we're not going to the origin, use http not https
if isLastCacheTier := noTopologyServerIsLastCacheForDS(server, &ds); !isLastCacheTier {
orgFQDNStr = strings.Replace(orgFQDNStr, `https://`, `http://`, -1)
}
orgURI, orgWarns, err := getOriginURI(orgFQDNStr)
warnings = append(warnings, orgWarns...)
if err != nil {
warnings = append(warnings, "DS '"+*ds.XMLID+"' has malformed origin URI: '"+*ds.OrgServerFQDN+"': skipping!"+err.Error())
warnings = append(warnings, "DS '"+*ds.XMLID+"' has malformed origin URI: '"+orgFQDNStr+"': skipping!"+err.Error())
continue
}

Expand Down Expand Up @@ -381,14 +386,21 @@ func MakeParentDotConfig(
warnings = append(warnings, parentWarns...)

text := ""
orgURI, orgWarns, err := getOriginURI(*ds.OrgServerFQDN)

orgFQDNStr := *ds.OrgServerFQDN
// if this cache isn't the last tier, i.e. we're not going to the origin, use http not https
if isLastCacheTier := noTopologyServerIsLastCacheForDS(server, &ds); !isLastCacheTier {
orgFQDNStr = strings.Replace(orgFQDNStr, `https://`, `http://`, -1)
}
orgURI, orgWarns, err := getOriginURI(orgFQDNStr)
warnings = append(warnings, orgWarns...)
if err != nil {
warnings = append(warnings, "DS '"+*ds.XMLID+"' had malformed origin URI: '"+*ds.OrgServerFQDN+"': skipping!"+err.Error())
continue
}

text += makeParentComment(opt.AddComments, *ds.XMLID, "")

// TODO encode this in a DSType func, IsGoDirect() ?
if *ds.Type == tc.DSTypeHTTPNoCache || *ds.Type == tc.DSTypeHTTPLive || *ds.Type == tc.DSTypeDNSLive {
text += `dest_domain=` + orgURI.Hostname() + ` port=` + orgURI.Port() + ` go_direct=true` + "\n"
Expand Down Expand Up @@ -757,28 +769,32 @@ func getTopologyParentConfigLine(
return "", warnings, nil
}

orgURI, orgWarns, err := getOriginURI(*ds.OrgServerFQDN)
warnings = append(warnings, orgWarns...)
if err != nil {
return "", warnings, errors.New("DS '" + *ds.XMLID + "' has malformed origin URI: '" + *ds.OrgServerFQDN + "': skipping!" + err.Error())
}

topology := nameTopologies[TopologyName(*ds.Topology)]
if topology.Name == "" {
return "", warnings, errors.New("DS " + *ds.XMLID + " topology '" + *ds.Topology + "' not found in Topologies!")
}

txt += makeParentComment(addComments, *ds.XMLID, *ds.Topology)
txt += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port()

serverPlacement, err := getTopologyPlacement(tc.CacheGroupName(*server.Cachegroup), topology, cacheGroups, ds)
if err != nil {
return "", warnings, errors.New("getting topology placement: " + err.Error())
}
if !serverPlacement.InTopology {
return "", warnings, nil // server isn't in topology, no error
}
// TODO add Topology/Capabilities to remap.config

orgFQDNStr := *ds.OrgServerFQDN
// if this cache isn't the last tier, i.e. we're not going to the origin, use http not https
if !serverPlacement.IsLastCacheTier {
orgFQDNStr = strings.Replace(orgFQDNStr, `https://`, `http://`, -1)
}
orgURI, orgWarns, err := getOriginURI(orgFQDNStr)
warnings = append(warnings, orgWarns...)
if err != nil {
return "", warnings, errors.New("DS '" + *ds.XMLID + "' has malformed origin URI: '" + *ds.OrgServerFQDN + "': skipping!" + err.Error())
}

txt += makeParentComment(addComments, *ds.XMLID, *ds.Topology)
txt += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port()

parents, secondaryParents, parentWarnings, err := getTopologyParents(server, ds, servers, parentConfigParams, topology, serverPlacement.IsLastTier, serverCapabilities, dsRequiredCapabilities, dsOrigins)
warnings = append(warnings, parentWarnings...)
Expand Down
258 changes: 258 additions & 0 deletions lib/go-atscfg/parentdotconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2619,6 +2619,264 @@ func TestMakeParentDotConfigCommentTopology(t *testing.T) {
}
}

func TestMakeParentDotConfigHTTPSOrigin(t *testing.T) {
hdr := &ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}

ds0 := makeParentDS()
ds0Type := tc.DSTypeHTTP
ds0.Type = &ds0Type
ds0.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
ds0.OrgServerFQDN = util.StrPtr("https://ds0.example.net")

ds1 := makeParentDS()
ds1.ID = util.IntPtr(43)
ds1Type := tc.DSTypeDNS
ds1.Type = &ds1Type
ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")

dses := []DeliveryService{*ds0, *ds1}

parentConfigParams := []tc.Parameter{
tc.Parameter{
Name: ParentConfigParamQStringHandling,
ConfigFile: "parent.config",
Value: "myQStringHandlingParam",
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamAlgorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamQString,
ConfigFile: "parent.config",
Value: "myQstringParam",
Profiles: []byte(`["serverprofile"]`),
},
}

serverParams := []tc.Parameter{
tc.Parameter{
Name: "trafficserver",
ConfigFile: "package",
Value: "7",
Profiles: []byte(`["global"]`),
},
}

server := makeTestParentServer()

mid0 := makeTestParentServer()
mid0.Cachegroup = util.StrPtr("midCG")
mid0.HostName = util.StrPtr("mymid0")
mid0.ID = util.IntPtr(45)
setIP(mid0, "192.168.2.2")

mid1 := makeTestParentServer()
mid1.Cachegroup = util.StrPtr("midCG")
mid1.HostName = util.StrPtr("mymid1")
mid1.ID = util.IntPtr(46)
setIP(mid1, "192.168.2.3")

servers := []Server{*server, *mid0, *mid1}

topologies := []tc.Topology{}
serverCapabilities := map[int]map[ServerCapability]struct{}{}
dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}

eCG := &tc.CacheGroupNullable{}
eCG.Name = server.Cachegroup
eCG.ID = server.CachegroupID
eCG.ParentName = mid0.Cachegroup
eCG.ParentCachegroupID = mid0.CachegroupID
eCGType := tc.CacheGroupEdgeTypeName
eCG.Type = &eCGType

mCG := &tc.CacheGroupNullable{}
mCG.Name = mid0.Cachegroup
mCG.ID = mid0.CachegroupID
mCGType := tc.CacheGroupMidTypeName
mCG.Type = &mCGType

cgs := []tc.CacheGroupNullable{*eCG, *mCG}

dss := []DeliveryServiceServer{
DeliveryServiceServer{
Server: *server.ID,
DeliveryService: *ds0.ID,
},
DeliveryServiceServer{
Server: *server.ID,
DeliveryService: *ds1.ID,
},
}
cdn := &tc.CDN{
DomainName: "cdndomain.example",
Name: "my-cdn-name",
}

cfg, err := MakeParentDotConfig(dses, server, servers, topologies, serverParams, parentConfigParams, serverCapabilities, dsRequiredCapabilities, cgs, dss, cdn, hdr)
if err != nil {
t.Fatal(err)
}
txt := cfg.Text

testComment(t, txt, hdr.HdrComment)

if !strings.Contains(txt, "dest_domain=ds0.example.net port=80") {
t.Errorf("expected edge parent.config of https origin to use internal http port 80 (not https/443), actual: '%v'", txt)
}
}

func TestMakeParentDotConfigHTTPSOriginTopology(t *testing.T) {
hdr := &ParentConfigOpts{AddComments: true, HdrComment: "myHeaderComment"}

ds0 := makeParentDS()
ds0Type := tc.DSTypeHTTP
ds0.Type = &ds0Type
ds0.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
ds0.OrgServerFQDN = util.StrPtr("https://ds0.example.net")
ds0.ProfileID = util.IntPtr(311)
ds0.ProfileName = util.StrPtr("ds0Profile")

ds1 := makeParentDS()
ds1.ID = util.IntPtr(43)
ds1Type := tc.DSTypeDNS
ds1.Type = &ds1Type
ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
ds1.Topology = util.StrPtr("t0")
ds1.ProfileID = util.IntPtr(312)
ds1.ProfileName = util.StrPtr("ds1Profile")

dses := []DeliveryService{*ds0, *ds1}

parentConfigParams := []tc.Parameter{
{
Name: ParentConfigParamQStringHandling,
ConfigFile: "parent.config",
Value: "myQStringHandlingParam",
Profiles: []byte(`["serverprofile"]`),
},
{
Name: ParentConfigParamAlgorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
},
{
Name: ParentConfigParamQString,
ConfigFile: "parent.config",
Value: "myQstringParam",
Profiles: []byte(`["serverprofile"]`),
},
}

serverParams := []tc.Parameter{
{
Name: "trafficserver",
ConfigFile: "package",
Value: "8",
Profiles: []byte(`["global"]`),
},
}

server := makeTestParentServer()
server.Cachegroup = util.StrPtr("edgeCG")
server.CachegroupID = util.IntPtr(400)

mid0 := makeTestParentServer()
mid0.Cachegroup = util.StrPtr("midCG")
mid0.CachegroupID = util.IntPtr(500)
mid0.HostName = util.StrPtr("mymid")
mid0.ID = util.IntPtr(45)
setIP(mid0, "192.168.2.2")

mid1 := makeTestParentServer()
mid1.Cachegroup = util.StrPtr("midCG2")
mid1.CachegroupID = util.IntPtr(501)
mid1.HostName = util.StrPtr("mymid1")
mid1.ID = util.IntPtr(46)
setIP(mid1, "192.168.2.3")

servers := []Server{*server, *mid0, *mid1}

topologies := []tc.Topology{
{
Name: "t0",
Nodes: []tc.TopologyNode{
{
Cachegroup: "edgeCG",
Parents: []int{1, 2},
},
{
Cachegroup: "midCG",
},
{
Cachegroup: "midCG2",
},
},
},
}

serverCapabilities := map[int]map[ServerCapability]struct{}{}
dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}

eCG := &tc.CacheGroupNullable{}
eCG.Name = server.Cachegroup
eCG.ID = server.CachegroupID
eCG.ParentName = mid0.Cachegroup
eCG.ParentCachegroupID = mid0.CachegroupID
eCG.SecondaryParentName = mid1.Cachegroup
eCG.SecondaryParentCachegroupID = mid1.CachegroupID
eCGType := tc.CacheGroupEdgeTypeName
eCG.Type = &eCGType

mCG := &tc.CacheGroupNullable{}
mCG.Name = mid0.Cachegroup
mCG.ID = mid0.CachegroupID
mCGType := tc.CacheGroupMidTypeName
mCG.Type = &mCGType

mCG2 := &tc.CacheGroupNullable{}
mCG2.Name = mid1.Cachegroup
mCG2.ID = mid1.CachegroupID
mCGType2 := tc.CacheGroupMidTypeName
mCG2.Type = &mCGType2

cgs := []tc.CacheGroupNullable{*eCG, *mCG, *mCG2}

dss := []DeliveryServiceServer{
{
Server: *server.ID,
DeliveryService: *ds0.ID,
},
{
Server: *server.ID,
DeliveryService: *ds1.ID,
},
}
cdn := &tc.CDN{
DomainName: "cdndomain.example",
Name: "my-cdn-name",
}

cfg, err := MakeParentDotConfig(dses, server, servers, topologies, serverParams, parentConfigParams, serverCapabilities, dsRequiredCapabilities, cgs, dss, cdn, hdr)
if err != nil {
t.Fatal(err)
}
txt := cfg.Text

testComment(t, txt, hdr.HdrComment)

if !strings.Contains(txt, "dest_domain=ds0.example.net port=80") {
t.Errorf("expected topology parent.config of https origin to be http/80 not https/443, actual: '%v'", txt)
}
}

func makeTestParentServer() *Server {
server := &Server{}
server.ProfileID = util.IntPtr(42)
Expand Down
Loading

0 comments on commit 2b42366

Please sign in to comment.