rob05c commented on a change in pull request #4790:
URL: https://github.com/apache/trafficcontrol/pull/4790#discussion_r451798876
##########
File path: lib/go-atscfg/parentdotconfig.go
##########
@@ -331,13 +345,270 @@ func MakeParentDotConfig(
defaultDestText += ` qstring=` + qStr
}
defaultDestText += "\n"
-
- sort.Sort(sort.StringSlice(textArr))
- text = hdr + strings.Join(textArr, "") + defaultDestText
}
+
+ sort.Sort(sort.StringSlice(textArr))
+ text := hdr + strings.Join(textArr, "") + defaultDestText
return text
}
+func GetTopologyParentConfigLine(
+ server tc.Server,
+ servers []tc.Server,
+ ds ParentConfigDSTopLevel,
+ serverParams map[string]string,
+ parentConfigParams []ParameterWithProfilesMap, // all params with
configFile parent.config
+ topologies []tc.Topology,
+ serverCapabilities map[int]map[ServerCapability]struct{},
+) (string, error) {
+ txt := ""
+
+ if !HasRequiredCapabilities(serverCapabilities[server.ID],
ds.RequiredCapabilities) {
+ return "", nil
+ }
+
+ orgURI, err := GetOriginURI(ds.OriginFQDN)
+ if err != nil {
+ return "", errors.New("Malformed ds '" + string(ds.Name) + "'
origin URI: '" + ds.OriginFQDN + "': skipping!" + err.Error())
+ }
+
+ // This could be put in a map beforehand to only iterate once, if
performance mattered
+ topology := tc.Topology{}
+ for _, to := range topologies {
+ if to.Name == ds.Topology {
+ topology = to
+ break
+ }
+ }
+ if topology.Name == "" {
+ return "", errors.New("DS " + string(ds.Name) + " topology '" +
ds.Topology + "' not found in Topologies!")
+ }
+
+ txt += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port()
+
+ serverIsLastTier, serverInTopology := serverTopologyTier(server,
topology)
+ if !serverInTopology {
+ return "", nil // server isn't in topology, no error
+ }
+ // TODO omit server and parents without necessary Capabilities
+ // TODO add Topology/Capabilities to remap.config
+
+ parents, secondaryParents, err := GetTopologyParents(server, ds,
serverParams, servers, parentConfigParams, topology, serverIsLastTier,
serverCapabilities)
+ if err != nil {
+ return "", errors.New("getting topology parents for '" +
string(ds.Name) + "': skipping! " + err.Error())
+ }
+ txt += ` parent="` + strings.Join(parents, `;`) + `"`
+ if len(secondaryParents) > 0 {
+ txt += ` secondary_parent="` + strings.Join(secondaryParents,
`;`) + `"`
+ }
+ txt += ` round_robin=` + getTopologyRoundRobin(server, ds, topology,
serverParams, serverIsLastTier)
+ txt += ` go_direct=` + getTopologyGoDirect(server, ds, topology,
serverIsLastTier)
+ txt += ` qstring=` + getTopologyQueryString(server, ds, topology,
serverParams, serverIsLastTier)
+ txt += getTopologyParentIsProxyStr(serverIsLastTier)
+ txt += " # topology"
+ txt += "\n"
+ return txt, nil
+}
+
+func getTopologyParentIsProxyStr(serverIsLastTier bool) string {
+ if serverIsLastTier { // && ds.MultiSiteOrigin
+ return ` parent_is_proxy=false`
+ }
+ return ""
+}
+
+func getTopologyRoundRobin(server tc.Server, ds ParentConfigDSTopLevel,
topology tc.Topology, serverParams map[string]string, serverIsLastTier bool)
string {
+ roundRobinConsistentHash := "consistent_hash"
+ if !serverIsLastTier {
+ return roundRobinConsistentHash
+ }
+ if parentSelectAlg := serverParams[ParentConfigParamAlgorithm];
ds.OriginShield != "" && strings.TrimSpace(parentSelectAlg) != "" {
+ return parentSelectAlg
+ }
+ if ds.MultiSiteOrigin {
+ return ds.MSOAlgorithm
+ }
+ return roundRobinConsistentHash
+}
+
+func getTopologyGoDirect(server tc.Server, ds ParentConfigDSTopLevel, topology
tc.Topology, serverIsLastTier bool) string {
+ if !serverIsLastTier {
+ // TODO make sure this is correct for DSTypeHTTPNoCache ||
DSTypeHTTPLive || DSTypeDNSLive
+ return "false"
+ }
+ if ds.OriginShield != "" {
+ return "true"
+ }
+ if ds.MultiSiteOrigin {
+ return "false"
+ }
+ // TODO make sure this is correct. If we're the last tier, we should go
direct to the origin, right?
+ return "true"
+}
+
+func getTopologyQueryString(server tc.Server, ds ParentConfigDSTopLevel,
topology tc.Topology, serverParams map[string]string, serverIsLastTier bool)
string {
+ if serverIsLastTier {
+ if ds.MultiSiteOrigin && ds.QStringHandling == "" &&
ds.MSOAlgorithm == tc.AlgorithmConsistentHash && ds.QStringIgnore ==
tc.QStringIgnoreUseInCacheKeyAndPassUp {
+ return "consider"
+ }
+ return "ignore"
+ }
+
+ if param := serverParams[ParentConfigParamQStringHandling]; param != ""
{
+ return param
+ }
+ if ds.QStringHandling != "" {
+ return ds.QStringHandling
+ }
+ if ds.QStringIgnore == tc.QStringIgnoreUseInCacheKeyAndPassUp {
+ return "consider"
+ }
+ return "ignore"
+}
+
+// serverParentageParams gets the Parameters used for parent= line, or
defaults if they don't exist
+// Returns the Parameters used for parent= lines, for the given server.
+func serverParentageParams(sv tc.Server, params []ParameterWithProfilesMap)
ProfileCache {
+ // TODO deduplicate with atstccfg/parentdotconfig.go
+ profileCache := DefaultProfileCache()
+ profileCache.Port = sv.TCPPort
+ for _, param := range params {
+ if _, ok := param.ProfileNames[sv.Profile]; !ok {
+ continue
+ }
+ switch param.Name {
+ case ParentConfigCacheParamWeight:
+ profileCache.Weight = param.Value
+ case ParentConfigCacheParamPort:
+ i, err := strconv.ParseInt(param.Value, 10, 64)
+ if err != nil {
+ log.Errorln("parent.config generation: port
param is not an integer, skipping! : " + err.Error())
+ } else {
+ profileCache.Port = int(i)
+ }
+ case ParentConfigCacheParamUseIP:
+ profileCache.UseIP = param.Value == "1"
+ case ParentConfigCacheParamRank:
+ i, err := strconv.ParseInt(param.Value, 10, 64)
+ if err != nil {
+ log.Errorln("parent.config generation: rank
param is not an integer, skipping! : " + err.Error())
+ } else {
+ profileCache.Rank = int(i)
+ }
+ case ParentConfigCacheParamNotAParent:
+ profileCache.NotAParent = param.Value != "false"
+ }
+ }
+ return profileCache
+}
+
+func serverParentStr(sv tc.Server, params []ParameterWithProfilesMap) string {
+ svParams := serverParentageParams(sv, params)
+ if svParams.NotAParent {
+ return ""
+ }
+ host := ""
+ if svParams.UseIP {
+ host = sv.IPAddress
+ } else {
+ host = sv.HostName + "." + sv.DomainName
+ }
+ return host + ":" + strconv.Itoa(svParams.Port) + "|" + svParams.Weight
+}
+
+func GetTopologyParents(
+ server tc.Server,
+ ds ParentConfigDSTopLevel,
+ serverParams map[string]string,
+ servers []tc.Server,
+ parentConfigParams []ParameterWithProfilesMap, // all params with
configFile parent.confign
+ topology tc.Topology,
+ serverIsLastTier bool,
+ serverCapabilities map[int]map[ServerCapability]struct{},
+) ([]string, []string, error) {
+ // If it's the last tier, then the parent is the origin.
+ // Note this doesn't include MSO, whose final tier cachegroup points to
the origin cachegroup.
+ if serverIsLastTier {
+ orgURI, err := GetOriginURI(ds.OriginFQDN) // TODO pass,
instead of calling again
+ if err != nil {
+ return nil, nil, err
+ }
+ return []string{orgURI.Host}, nil, nil
+ }
+
+ svNode := tc.TopologyNode{}
+ for _, node := range topology.Nodes {
+ if node.Cachegroup == server.Cachegroup {
+ svNode = node
+ break
+ }
+ }
+ if svNode.Cachegroup == "" {
+ return nil, nil, errors.New("This server '" + server.HostName +
"' not in DS " + string(ds.Name) + " topology, skipping")
+ }
+
+ if len(svNode.Parents) == 0 {
+ return nil, nil, errors.New("DS " + string(ds.Name) + "
topology '" + ds.Topology + "' is last tier, but NonLastTier called! Should
never happen")
+ }
+ if numParents := len(svNode.Parents); numParents > 2 {
+ log.Errorln("DS " + string(ds.Name) + " topology '" +
ds.Topology + "' has " + strconv.Itoa(numParents) + " parent nodes, but Apache
Traffic Server only supports Primary and Secondary (2) lists of parents.
CacheGroup nodes after the first 2 will be ignored!")
+ }
+ if len(topology.Nodes) < svNode.Parents[0] {
Review comment:
Ah, yes, the panic. I'll fix.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]