Skip to content

Commit

Permalink
t3c add support for anycast on http routed delivery services (#7323)
Browse files Browse the repository at this point in the history
* adding toData.Servers to routines for anycast

* added servers to support anycast

* updated to add remap lines for http services using anycast

* updated esisting, and added testing for anycast feature

* added CHANGELOG entry

* fixed formatting errors

* fixed config error in tests

* added blank line after func, also made servers empty set when not needed.

* removed 7309
  • Loading branch information
jpappa200 authored Feb 3, 2023
1 parent d4199db commit 709fd18
Show file tree
Hide file tree
Showing 8 changed files with 445 additions and 98 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#7273](https://github.com/apache/trafficcontrol/pull/7273) *Traffic Ops* Adds SSL-KEY-EXPIRATION:READ permission to operations, portal, read-only, federation and steering roles
- [#7296](https://github.com/apache/trafficcontrol/pull/7296) *Traffic Portal* New configuration option in `traffic_portal_properties.json` at `deliveryServices.exposeInactive` controls exposing APIv5 DS Active State options in the TP UI.
- [#7332](https://github.com/apache/trafficcontrol/pull/7332) *Traffic Ops* Creates new role needed for TR to watch TO resources.
- [#7322](https://github.com/apache/trafficcontrol/issues/7322) *t3c Adds support for anycast on http routed edges.

### Changed
- [#7224](https://github.com/apache/trafficcontrol/pull/7224) *Traffic Ops* Required Capabilities are now a part of the `DeliveryService` structure.
Expand Down
3 changes: 3 additions & 0 deletions cache-config/t3c-generate/cfgfile/wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ func MakeLoggingDotYAML(toData *t3cutil.ConfigData, fileName string, hdrCommentT
func MakeSSLServerNameYAML(toData *t3cutil.ConfigData, fileName string, hdrCommentTxt string, cfg config.Cfg) (atscfg.Cfg, error) {
return atscfg.MakeSSLServerNameYAML(
toData.Server,
toData.Servers,
toData.DeliveryServices,
toData.DeliveryServiceServers,
toData.DeliveryServiceRegexes,
Expand All @@ -155,6 +156,7 @@ func MakeSSLServerNameYAML(toData *t3cutil.ConfigData, fileName string, hdrComme
func MakeSNIDotYAML(toData *t3cutil.ConfigData, fileName string, hdrCommentTxt string, cfg config.Cfg) (atscfg.Cfg, error) {
return atscfg.MakeSNIDotYAML(
toData.Server,
toData.Servers,
toData.DeliveryServices,
toData.DeliveryServiceServers,
toData.DeliveryServiceRegexes,
Expand Down Expand Up @@ -232,6 +234,7 @@ func MakeRemapDotConfig(toData *t3cutil.ConfigData, fileName string, hdrCommentT
remapAndCacheKeyParams = append(remapAndCacheKeyParams, toData.CacheKeyConfigParams...)
return atscfg.MakeRemapDotConfig(
toData.Server,
toData.Servers,
toData.DeliveryServices,
toData.DeliveryServiceServers,
toData.DeliveryServiceRegexes,
Expand Down
85 changes: 69 additions & 16 deletions lib/go-atscfg/remapdotconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ type RemapDotConfigOpts struct {

func MakeRemapDotConfig(
server *Server,
servers []Server,
unfilteredDSes []DeliveryService,
dss []DeliveryServiceServer,
dsRegexArr []tc.DeliveryServiceRegexes,
Expand Down Expand Up @@ -173,14 +174,15 @@ func MakeRemapDotConfig(
}

nameTopologies := makeTopologyNameMap(topologies)
anyCastPartners := getAnyCastPartners(server, servers)

hdr := makeHdrComment(opt.HdrComment)
txt := ""
typeWarns := []string{}
if tc.CacheTypeFromString(server.Type) == tc.CacheTypeMid {
txt, typeWarns, err = getServerConfigRemapDotConfigForMid(atsMajorVersion, dsProfilesConfigParams, dses, dsRegexes, hdr, server, nameTopologies, cacheGroups, serverCapabilities, dsRequiredCapabilities, configDir, opt)
} else {
txt, typeWarns, err = getServerConfigRemapDotConfigForEdge(dsProfilesConfigParams, serverPackageParamData, dses, dsRegexes, atsMajorVersion, hdr, server, nameTopologies, cacheGroups, serverCapabilities, dsRequiredCapabilities, cdnDomain, configDir, opt)
txt, typeWarns, err = getServerConfigRemapDotConfigForEdge(dsProfilesConfigParams, serverPackageParamData, dses, dsRegexes, atsMajorVersion, hdr, server, anyCastPartners, nameTopologies, cacheGroups, serverCapabilities, dsRequiredCapabilities, cdnDomain, configDir, opt)
}
warnings = append(warnings, typeWarns...)
if err != nil {
Expand Down Expand Up @@ -501,6 +503,7 @@ func getServerConfigRemapDotConfigForEdge(
atsMajorVersion uint,
header string,
server *Server,
anyCastPartners map[string][]string,
nameTopologies map[TopologyName]tc.Topology,
cacheGroups map[tc.CacheGroupName]tc.CacheGroupNullable,
serverCapabilities map[int]map[ServerCapability]struct{},
Expand Down Expand Up @@ -540,7 +543,7 @@ func getServerConfigRemapDotConfigForEdge(
continue
}

requestFQDNs, err := getDSRequestFQDNs(&ds, dsRegexes[tc.DeliveryServiceName(*ds.XMLID)], server, cdnDomain)
requestFQDNs, err := getDSRequestFQDNs(&ds, dsRegexes[tc.DeliveryServiceName(*ds.XMLID)], server, anyCastPartners, cdnDomain)
if err != nil {
warnings = append(warnings, "error getting ds '"+*ds.XMLID+"' request fqdns, skipping! Error: "+err.Error())
continue
Expand Down Expand Up @@ -1059,6 +1062,32 @@ func makeDSRegexMap(regexes []tc.DeliveryServiceRegexes) map[tc.DeliveryServiceN
return dsRegexMap
}

func getAnyCastPartners(server *Server, servers []Server) map[string][]string {
anyCastIPs := make(map[string][]string)
for _, int := range server.Interfaces {
if int.Name == "lo" {
for _, addr := range int.IPAddresses {
anyCastIPs[addr.Address] = []string{}
}
}
}
for _, srv := range servers {
if *server.HostName == *srv.HostName {
continue
}
for _, int := range srv.Interfaces {
if int.Name == "lo" {
for _, address := range int.IPAddresses {
if _, ok := anyCastIPs[address.Address]; ok && address.ServiceAddress {
anyCastIPs[address.Address] = append(anyCastIPs[address.Address], *srv.HostName)
}
}
}
}
}
return anyCastIPs
}

type keyVal struct {
Key string
Val string
Expand All @@ -1076,12 +1105,13 @@ func (ks keyVals) Less(i, j int) bool {
}

// getDSRequestFQDNs returns the FQDNs that clients will request from the edge.
func getDSRequestFQDNs(ds *DeliveryService, regexes []tc.DeliveryServiceRegex, server *Server, cdnDomain string) ([]string, error) {
func getDSRequestFQDNs(ds *DeliveryService, regexes []tc.DeliveryServiceRegex, server *Server, anyCastPartners map[string][]string, cdnDomain string) ([]string, error) {
if server.HostName == nil {
return nil, errors.New("server missing hostname")
}

fqdns := []string{}
seenFQDNs := map[string]struct{}{}
for _, dsRegex := range regexes {
if tc.DSMatchType(dsRegex.Type) != tc.DSMatchTypeHostRegex || ds.OrgServerFQDN == nil || *ds.OrgServerFQDN == "" {
continue
Expand All @@ -1097,28 +1127,51 @@ func getDSRequestFQDNs(ds *DeliveryService, regexes []tc.DeliveryServiceRegex, s
}

hostRegex := dsRegex.Pattern
fqdn := hostRegex

if strings.HasSuffix(hostRegex, `.*`) {
re := hostRegex
re = strings.Replace(re, `\`, ``, -1)
re = strings.Replace(re, `.*`, ``, -1)
fqdn, err := makeFQDN(hostRegex, ds, *server.HostName, cdnDomain)
if err != nil {
return nil, err
}
fqdns = append(fqdns, fqdn)

hName := *server.HostName
if ds.Type.IsDNS() {
if ds.RoutingName == nil {
return nil, errors.New("ds is dns, but missing routing name")
if ds.Type.IsHTTP() && strings.HasSuffix(hostRegex, `.*`) {
for _, ip := range anyCastPartners {
for _, hn := range ip {
fqdn, err := makeFQDN(hostRegex, ds, hn, cdnDomain)
if err != nil {
return nil, err
}
if _, ok := seenFQDNs[fqdn]; ok {
continue
}
seenFQDNs[fqdn] = struct{}{}
fqdns = append(fqdns, fqdn)
}
hName = *ds.RoutingName
}

fqdn = hName + re + cdnDomain
}
fqdns = append(fqdns, fqdn)
}
return fqdns, nil
}

func makeFQDN(hostRegex string, ds *DeliveryService, server string, cdnDomain string) (string, error) {
fqdn := hostRegex
if strings.HasSuffix(hostRegex, `.*`) {
re := hostRegex
re = strings.Replace(re, `\`, ``, -1)
re = strings.Replace(re, `.*`, ``, -1)

hName := server
if ds.Type.IsDNS() {
if ds.RoutingName == nil {
return "", errors.New("ds is dns, but missing routing name")
}
hName = *ds.RoutingName
}
fqdn = hName + re + cdnDomain
}
return fqdn, nil
}

func serverIsLastCacheForDS(server *Server, ds *DeliveryService, topologies map[TopologyName]tc.Topology, cacheGroups map[tc.CacheGroupName]tc.CacheGroupNullable) (bool, error) {
if ds.Topology != nil && strings.TrimSpace(*ds.Topology) != "" {
if server.Cachegroup == nil {
Expand Down
Loading

0 comments on commit 709fd18

Please sign in to comment.