This is an automated email from the ASF dual-hosted git repository.
ocket8888 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 89fdc0e Updates to the tm-health-client (#6147)
89fdc0e is described below
commit 89fdc0e30c1adb4e8b86b4d98fd744d5b5b569f5
Author: John J. Rushford <[email protected]>
AuthorDate: Tue Aug 31 14:46:49 2021 -0600
Updates to the tm-health-client (#6147)
- fix to ensure marking parents up or down is only done using
the configured reason code.
- fixes an issue where available parents reported by TM are
not marked up when 'enable-active-markdowns' disabled.
- checks for updates to the config file applying new updates.
- reloads the available traffic monitors list with a config
file update.
- reloads the available traffic monitors list if there are
any errors encountered when polling a traffic monitor.
- added a configuration parameter 'tm-update-cycles' to set
a periodic refresh on the available traffic monitors list.
- added a util module and renamed tmutil to tmagent
- refactored unit tests.
---
cache-config/tm-health-client/README.md | 21 +++-
cache-config/tm-health-client/config/config.go | 87 ++++++++++----
.../tm-health-client/config/config_test.go | 14 ++-
.../tm-health-client/tm-health-client-logrotate | 2 +-
cache-config/tm-health-client/tm-health-client.go | 4 +-
.../tm-health-client/tm-health-client.json | 3 +-
.../{tmutil => tmagent}/test_files/bin/traffic_ctl | 0
.../test_files/etc/parent.config | 0
.../test_files/etc/strategies.yaml | 0
.../test_files/tm-health-client.json | 0
.../{tmutil/tmutil.go => tmagent/tmagent.go} | 126 ++++++++++++---------
.../tmutil_test.go => tmagent/tmagent_test.go} | 57 +++++++---
.../{tm-health-client.go => util/util.go} | 36 +++---
13 files changed, 233 insertions(+), 117 deletions(-)
diff --git a/cache-config/tm-health-client/README.md
b/cache-config/tm-health-client/README.md
index 6acb20e..d3a2ea8 100644
--- a/cache-config/tm-health-client/README.md
+++ b/cache-config/tm-health-client/README.md
@@ -58,6 +58,17 @@ otherwise unavailable, the tm-health-client will utilize the
**Traffic Server**
and **Traffic Monitor** has determined that the marked down host is now
available,
the client will then utilize the **Traffic Server** tool to mark the host back
up.
+Also on each polling cycle the configuration file, **tm-health-client.json**
is
+checked and a new config is reloaded if the file has changed since the last
+polling cycle. The **Traffic Monitors** list is refreshed from **Traffic
Ops**.
+
+If errors are encountered while polling a Traffic Monitor, the error is logged
+and the **Traffic Monitors** list is refreshed from **Traffic Ops**.
+
+# REQUIREMENTS
+
+Requires Apache TrafficServer 8.1.0 or later.
+
# OPTIONS
-f, -\-config-file=config-file
@@ -97,6 +108,7 @@ Sample configuarion file:
"to-url": "https://tp.cdn.com:443",
"to-request-timeout-seconds": "5s",
"tm-poll-interval-seconds": "60s",
+ "tm-update-cycles": 5,
"trafficserver-config-dir": "/opt/trafficserver/etc/trafficserver",
"trafficserver-bin-dir": "/opt/trafficserver/bin",
}
@@ -110,7 +122,8 @@ Sample configuarion file:
When enabled, the client will actively mark down Traffic Server parents.
When disabled, the client will only log that it would have marked down
- Traffic Server parents
+ Traffic Server parents. Down Parents are always marked UP if Traffic Monitor
+ reports them available irregardless of this setting.
### reason-code
@@ -140,6 +153,12 @@ Sample configuarion file:
The polling interval in seconds used to update **Traffic Server** parent
status.
+### tm-update-cycles
+
+ Each time a polling cycle completes a count is incremented. When the count
+ reaches **tm-update-cycles**, TrafficOps is polled for a new list of
available
+ TrafficMonitors for the CDN and the poll count is reset to 0.
+
### trafficserver-config-dir
The location on the host where **Traffic Server** configuration files are
diff --git a/cache-config/tm-health-client/config/config.go
b/cache-config/tm-health-client/config/config.go
index 5c5d8a8..f46d618 100644
--- a/cache-config/tm-health-client/config/config.go
+++ b/cache-config/tm-health-client/config/config.go
@@ -30,6 +30,7 @@ import (
"strings"
"time"
+ "github.com/apache/trafficcontrol/cache-config/tm-health-client/util"
"github.com/apache/trafficcontrol/lib/go-log"
toclient "github.com/apache/trafficcontrol/traffic_ops/v3-client"
@@ -45,6 +46,7 @@ const (
DefaultLogFile = "tm-health-client.log"
DefaultTrafficServerConfigDir = "/opt/trafficserver/etc/trafficserver"
DefaultTrafficServerBinDir = "/opt/trafficserver/bin"
+ DefaultTmUpdateCycles = 10
)
type Cfg struct {
@@ -57,9 +59,11 @@ type Cfg struct {
TOUrl string
TOUser string
TmPollIntervalSeconds string
`json:"tm-poll-interval-seconds"`
+ TmUpdateCycles int `json:"tm-update-cycles"`
TrafficServerConfigDir string
`json:"trafficserver-config-dir"`
TrafficServerBinDir string `json:"trafficserver-bin-dir"`
TrafficMonitors map[string]bool
`json:"trafficmonitors,omitempty"`
+ HealthClientConfigFile util.ConfigFile
}
type LogCfg struct {
@@ -75,7 +79,7 @@ func (lcfg LogCfg) InfoLog() log.LogLocation { return
log.LogLocation(lcfg.Lo
func (lcfg LogCfg) DebugLog() log.LogLocation { return
log.LogLocation(lcfg.LogLocationDebug) }
func (lcfg LogCfg) EventLog() log.LogLocation { return
log.LogLocation(log.LogLocationNull) } // not used
-func readCredentials(cfg *Cfg) error {
+func ReadCredentials(cfg *Cfg) error {
fn := cfg.TOCredentialFile
f, err := os.Open(fn)
@@ -179,19 +183,24 @@ func GetConfig() (Cfg, error, bool) {
return Cfg{}, errors.New("Initializing loggers: " + err.Error()
+ "\n"), false
}
+ cf := util.ConfigFile{
+ Filename: configFile,
+ LastModifyTime: 0,
+ }
+
cfg := Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
- if err = LoadConfig(&cfg, configFile); err != nil {
+ if _, err = LoadConfig(&cfg); err != nil {
return Cfg{}, errors.New(err.Error() + "\n"), false
}
- if err = readCredentials(&cfg); err != nil {
+ if err = ReadCredentials(&cfg); err != nil {
return cfg, err, false
}
- err = GetTrafficMonitorsStatus(&cfg)
+ err = GetTrafficMonitors(&cfg)
if err != nil {
return cfg, err, false
}
@@ -199,7 +208,7 @@ func GetConfig() (Cfg, error, bool) {
return cfg, nil, false
}
-func GetTrafficMonitorsStatus(cfg *Cfg) error {
+func GetTrafficMonitors(cfg *Cfg) error {
u, err := url.Parse(cfg.TOUrl)
if err != nil {
return errors.New("error parsing TOURL parameters: " +
err.Error())
@@ -215,6 +224,7 @@ func GetTrafficMonitorsStatus(cfg *Cfg) error {
return errors.New("error fetching Trafficmonitor server list: "
+ err.Error())
}
+ cfg.TrafficMonitors = make(map[string]bool, 0)
for _, v := range srvs {
if v.CDNName == cfg.CDNName && v.Status == "ONLINE" {
hostname := v.HostName + "." + v.DomainName
@@ -233,26 +243,65 @@ func GetRequestTimeout() time.Duration {
return toRequestTimeout
}
-func LoadConfig(cfg *Cfg, configFile string) error {
- content, err := ioutil.ReadFile(configFile)
+func LoadConfig(cfg *Cfg) (bool, error) {
+ updated := false
+ configFile := cfg.HealthClientConfigFile.Filename
+ modTime, err := util.GetFileModificationTime(configFile)
if err != nil {
- return errors.New(err.Error())
+ return updated, errors.New(err.Error())
}
- if err = json.Unmarshal(content, cfg); err == nil {
- tmPollingInterval, err =
time.ParseDuration(cfg.TmPollIntervalSeconds)
- if err != nil {
- return errors.New("parsing TMPollingIntervalSeconds: "
+ err.Error())
- }
- toRequestTimeout, err =
time.ParseDuration(cfg.TORequestTimeOutSeconds)
+
+ if modTime > cfg.HealthClientConfigFile.LastModifyTime {
+ log.Infoln("Loading a new config file.")
+ content, err := ioutil.ReadFile(configFile)
if err != nil {
- return errors.New("parsing TORequestTimeOutSeconds: " +
err.Error())
+ return updated, errors.New(err.Error())
}
- if cfg.ReasonCode != "active" && cfg.ReasonCode != "local" {
- return errors.New("invalid reason-code: " +
cfg.ReasonCode + ", valid reason codes are 'active' or 'local'")
+ if err = json.Unmarshal(content, cfg); err == nil {
+ tmPollingInterval, err =
time.ParseDuration(cfg.TmPollIntervalSeconds)
+ if err != nil {
+ return updated, errors.New("parsing
TMPollingIntervalSeconds: " + err.Error())
+ }
+ toRequestTimeout, err =
time.ParseDuration(cfg.TORequestTimeOutSeconds)
+ if err != nil {
+ return updated, errors.New("parsing
TORequestTimeOutSeconds: " + err.Error())
+ }
+ if cfg.ReasonCode != "active" && cfg.ReasonCode !=
"local" {
+ return updated, errors.New("invalid
reason-code: " + cfg.ReasonCode + ", valid reason codes are 'active' or
'local'")
+ }
+ if cfg.TrafficServerConfigDir == "" {
+ cfg.TrafficServerConfigDir =
DefaultTrafficServerConfigDir
+ }
+ if cfg.TrafficServerBinDir == "" {
+ cfg.TrafficServerBinDir =
DefaultTrafficServerBinDir
+ }
+ if cfg.TmUpdateCycles == 0 {
+ cfg.TmUpdateCycles = DefaultTmUpdateCycles
+ }
}
+
+ cfg.HealthClientConfigFile.LastModifyTime = modTime
+ updated = true
}
+ return updated, nil
+}
- return err
+func UpdateConfig(cfg *Cfg, newCfg *Cfg) {
+ log.Infoln("Installing config updates")
+ cfg.CDNName = newCfg.CDNName
+ cfg.EnableActiveMarkdowns = newCfg.EnableActiveMarkdowns
+ cfg.ReasonCode = newCfg.ReasonCode
+ cfg.TOCredentialFile = newCfg.TOCredentialFile
+ cfg.TORequestTimeOutSeconds = newCfg.TORequestTimeOutSeconds
+ cfg.TOPass = newCfg.TOPass
+ cfg.TOUrl = newCfg.TOUrl
+ cfg.TOUser = newCfg.TOUser
+ cfg.TmPollIntervalSeconds = newCfg.TmPollIntervalSeconds
+ cfg.TmUpdateCycles = newCfg.TmUpdateCycles
+ cfg.TrafficServerConfigDir = newCfg.TrafficServerConfigDir
+ cfg.TrafficServerBinDir = newCfg.TrafficServerBinDir
+ cfg.TrafficMonitors = newCfg.TrafficMonitors
+ cfg.HealthClientConfigFile = newCfg.HealthClientConfigFile
}
func Usage() {
diff --git a/cache-config/tm-health-client/config/config_test.go
b/cache-config/tm-health-client/config/config_test.go
index 385439d..2bafe09 100644
--- a/cache-config/tm-health-client/config/config_test.go
+++ b/cache-config/tm-health-client/config/config_test.go
@@ -21,6 +21,8 @@ package config
import (
"testing"
+
+ "github.com/apache/trafficcontrol/cache-config/tm-health-client/util"
)
const (
@@ -28,11 +30,17 @@ const (
)
func TestLoadConfig(t *testing.T) {
+ cf := util.ConfigFile{
+ Filename: test_config_file,
+ LastModifyTime: 0,
+ }
+
cfg := Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
- err := LoadConfig(&cfg, test_config_file)
+ _, err := LoadConfig(&cfg)
if err != nil {
t.Fatalf("failed to load %s: %s\n", test_config_file,
err.Error())
}
@@ -61,7 +69,7 @@ func TestLoadConfig(t *testing.T) {
t.Fatalf("expected '%s', got %s\n", expect, creds)
}
- readCredentials(&cfg)
+ ReadCredentials(&cfg)
expect = "https://tp.cdn.com:443"
tourl := cfg.TOUrl
diff --git a/cache-config/tm-health-client/tm-health-client-logrotate
b/cache-config/tm-health-client/tm-health-client-logrotate
index a3bfd30..9e97f3b 100644
--- a/cache-config/tm-health-client/tm-health-client-logrotate
+++ b/cache-config/tm-health-client/tm-health-client-logrotate
@@ -24,5 +24,5 @@
nomail
notifempty
rotate 10
- size 100M
+ size 5M
}
diff --git a/cache-config/tm-health-client/tm-health-client.go
b/cache-config/tm-health-client/tm-health-client.go
index b84bc61..b886e26 100644
--- a/cache-config/tm-health-client/tm-health-client.go
+++ b/cache-config/tm-health-client/tm-health-client.go
@@ -23,7 +23,7 @@ import (
"os"
"github.com/apache/trafficcontrol/cache-config/tm-health-client/config"
- "github.com/apache/trafficcontrol/cache-config/tm-health-client/tmutil"
+ "github.com/apache/trafficcontrol/cache-config/tm-health-client/tmagent"
"github.com/apache/trafficcontrol/lib/go-log"
)
@@ -44,7 +44,7 @@ func main() {
os.Exit(Success)
}
- tmInfo, err := tmutil.NewParentInfo(cfg)
+ tmInfo, err := tmagent.NewParentInfo(cfg)
if err != nil {
log.Errorf("startup could not initialize ATS parent info:
%s\n", err.Error())
}
diff --git a/cache-config/tm-health-client/tm-health-client.json
b/cache-config/tm-health-client/tm-health-client.json
index 3523cda..8df62f6 100644
--- a/cache-config/tm-health-client/tm-health-client.json
+++ b/cache-config/tm-health-client/tm-health-client.json
@@ -6,6 +6,7 @@
"to-url": "https://tp.cdn.com:443",
"to-request-timeout-seconds": "5s",
"tm-poll-interval-seconds": "15s",
+ "tm-update-cycles": 5,
"trafficserver-config-dir": "/opt/trafficserver/etc/trafficserver",
- "trafficserver-bin-dir": "/opt/trafficserver/bin",
+ "trafficserver-bin-dir": "/opt/trafficserver/bin"
}
diff --git a/cache-config/tm-health-client/tmutil/test_files/bin/traffic_ctl
b/cache-config/tm-health-client/tmagent/test_files/bin/traffic_ctl
similarity index 100%
rename from cache-config/tm-health-client/tmutil/test_files/bin/traffic_ctl
rename to cache-config/tm-health-client/tmagent/test_files/bin/traffic_ctl
diff --git a/cache-config/tm-health-client/tmutil/test_files/etc/parent.config
b/cache-config/tm-health-client/tmagent/test_files/etc/parent.config
similarity index 100%
rename from cache-config/tm-health-client/tmutil/test_files/etc/parent.config
rename to cache-config/tm-health-client/tmagent/test_files/etc/parent.config
diff --git
a/cache-config/tm-health-client/tmutil/test_files/etc/strategies.yaml
b/cache-config/tm-health-client/tmagent/test_files/etc/strategies.yaml
similarity index 100%
rename from cache-config/tm-health-client/tmutil/test_files/etc/strategies.yaml
rename to cache-config/tm-health-client/tmagent/test_files/etc/strategies.yaml
diff --git
a/cache-config/tm-health-client/tmutil/test_files/tm-health-client.json
b/cache-config/tm-health-client/tmagent/test_files/tm-health-client.json
similarity index 100%
rename from
cache-config/tm-health-client/tmutil/test_files/tm-health-client.json
rename to cache-config/tm-health-client/tmagent/test_files/tm-health-client.json
diff --git a/cache-config/tm-health-client/tmutil/tmutil.go
b/cache-config/tm-health-client/tmagent/tmagent.go
similarity index 86%
rename from cache-config/tm-health-client/tmutil/tmutil.go
rename to cache-config/tm-health-client/tmagent/tmagent.go
index 45cb3d7..85329d8 100644
--- a/cache-config/tm-health-client/tmutil/tmutil.go
+++ b/cache-config/tm-health-client/tmagent/tmagent.go
@@ -1,4 +1,4 @@
-package tmutil
+package tmagent
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -33,6 +33,7 @@ import (
"time"
"github.com/apache/trafficcontrol/cache-config/tm-health-client/config"
+ "github.com/apache/trafficcontrol/cache-config/tm-health-client/util"
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/traffic_monitor/datareq"
@@ -48,22 +49,15 @@ const (
)
type ParentAvailable interface {
- available() bool
-}
-
-// the necessary fields of a trafficserver parents config file needed to
-// read the file and keep track of it's modification time.
-type ParentConfigFile struct {
- Filename string
- LastModifyTime int64
+ available(reasonCode string) bool
}
// the necessary data required to keep track of trafficserver config
// files, lists of parents a trafficserver instance uses, and directory
// locations used for configuration and trafficserver executables.
type ParentInfo struct {
- ParentDotConfig ParentConfigFile
- StrategiesDotYaml ParentConfigFile
+ ParentDotConfig util.ConfigFile
+ StrategiesDotYaml util.ConfigFile
TrafficServerBinDir string
TrafficServerConfigDir string
Parents map[string]ParentStatus
@@ -93,15 +87,18 @@ type ParentStatus struct {
// used to get the overall parent availablity from the
// HostStatus markdown reasons. all markdown reasons
// must be true for a parent to be considered available.
-func (p ParentStatus) available() bool {
- if !p.ActiveReason {
- return false
- } else if !p.LocalReason {
- return false
- } else if !p.ManualReason {
- return false
- }
- return true
+func (p ParentStatus) available(reasonCode string) bool {
+ rc := false
+
+ switch reasonCode {
+ case "active":
+ rc = p.ActiveReason
+ case "local":
+ rc = p.LocalReason
+ case "manual":
+ rc = p.ManualReason
+ }
+ return rc
}
// used to log that a parent's status is either UP or
@@ -184,22 +181,22 @@ type Strategies struct {
func NewParentInfo(cfg config.Cfg) (*ParentInfo, error) {
parentConfig := filepath.Join(cfg.TrafficServerConfigDir, ParentsFile)
- modTime, err := getFileModificationTime(parentConfig)
+ modTime, err := util.GetFileModificationTime(parentConfig)
if err != nil {
return nil, errors.New("error reading " + ParentsFile + ": " +
err.Error())
}
- parents := ParentConfigFile{
+ parents := util.ConfigFile{
Filename: parentConfig,
LastModifyTime: modTime,
}
stratyaml := filepath.Join(cfg.TrafficServerConfigDir, StrategiesFile)
- modTime, err = getFileModificationTime(stratyaml)
+ modTime, err = util.GetFileModificationTime(stratyaml)
if err != nil {
return nil, errors.New("error reading " + StrategiesFile + ": "
+ err.Error())
}
- strategies := ParentConfigFile{
+ strategies := util.ConfigFile{
Filename: filepath.Join(cfg.TrafficServerConfigDir,
StrategiesFile),
LastModifyTime: modTime,
}
@@ -259,10 +256,35 @@ func (c *ParentInfo) GetCacheStatuses()
(map[tc.CacheName]datareq.CacheStatus, e
// down in the trafficserver subsystem based upon that hosts current status and
// the status that trafficmonitor health protocol has determined for a parent.
func (c *ParentInfo) PollAndUpdateCacheStatus() {
+ cycleCount := 0
pollingInterval := config.GetTMPollingInterval()
log.Infoln("polling started")
for {
+ // check for config file updates
+ newCfg := config.Cfg{
+ HealthClientConfigFile: c.Cfg.HealthClientConfigFile,
+ }
+ isNew, err := config.LoadConfig(&newCfg)
+ if err != nil {
+ log.Errorf("error reading changed config file %s:
%s\n", c.Cfg.HealthClientConfigFile.Filename, err.Error())
+ }
+ if isNew {
+ if err = config.ReadCredentials(&newCfg); err != nil {
+ log.Errorln("could not load credentials for
config updates, keeping the old config")
+ } else {
+ if err = config.GetTrafficMonitors(&newCfg);
err != nil {
+ log.Errorln("could not update the list
of trafficmonitors, keeping the old config")
+ } else {
+ config.UpdateConfig(&c.Cfg, &newCfg)
+ log.Infof("the configuration has been
successfully updated")
+ }
+ }
+ }
+
+ // check for parent and strategies config file updates, and
trafficserver
+ // host status changes. If an error is encountered reading
data the current
+ // parents lists and hoststatus remains unchanged.
if err := c.UpdateParentInfo(); err != nil {
log.Errorf("could not load new ATS parent info: %s\n",
err.Error())
} else {
@@ -272,7 +294,14 @@ func (c *ParentInfo) PollAndUpdateCacheStatus() {
// read traffic manager cache statuses.
caches, err := c.GetCacheStatuses()
if err != nil {
- log.Errorln(err.Error())
+ log.Errorf("error in TrafficMonitor polling: %s\n",
err.Error())
+ if err = config.GetTrafficMonitors(&c.Cfg); err != nil {
+ log.Errorln("could not update the list of
trafficmonitors, keeping the old config")
+ } else {
+ log.Infoln("Updated TrafficMonitor statuses
from TrafficOps")
+ }
+ time.Sleep(pollingInterval)
+ continue
}
for k, v := range caches {
@@ -280,13 +309,10 @@ func (c *ParentInfo) PollAndUpdateCacheStatus() {
cs, ok := c.Parents[hostName]
if ok {
tmAvailable := *v.CombinedAvailable
- if cs.available() != tmAvailable {
- if !c.Cfg.EnableActiveMarkdowns {
- if !tmAvailable {
- log.Infof("TM reports
that %s is not available and should be marked DOWN but, mark downs are disabled
by configuration", hostName)
- } else {
- log.Infof("TM reports
that %s is available and should be marked UP but, mark up is disabled by
configuration", hostName)
- }
+ if cs.available(c.Cfg.ReasonCode) !=
tmAvailable {
+ // do not mark down if the
configuration disables mark downs.
+ if !c.Cfg.EnableActiveMarkdowns &&
!tmAvailable {
+ log.Infof("TM reports that %s
is not available and should be marked DOWN but, mark downs are disabled by
configuration", hostName)
} else {
if err = c.markParent(cs.Fqdn,
*v.Status, tmAvailable); err != nil {
log.Errorln(err.Error())
@@ -296,6 +322,18 @@ func (c *ParentInfo) PollAndUpdateCacheStatus() {
}
}
+ // periodically update the TrafficMonitor list and statuses
+ if cycleCount == c.Cfg.TmUpdateCycles {
+ cycleCount = 0
+ if err = config.GetTrafficMonitors(&c.Cfg); err != nil {
+ log.Errorln("could not update the list of
trafficmonitors, keeping the old config")
+ } else {
+ log.Infoln("Updated TrafficMonitor statuses
from TrafficOps")
+ }
+ } else {
+ cycleCount++
+ }
+
time.Sleep(pollingInterval)
}
}
@@ -305,11 +343,11 @@ func (c *ParentInfo) PollAndUpdateCacheStatus() {
// availability is also updated to reflect the current state from
// the trafficserver HostStatus subsystem.
func (c *ParentInfo) UpdateParentInfo() error {
- ptime, err := getFileModificationTime(c.ParentDotConfig.Filename)
+ ptime, err := util.GetFileModificationTime(c.ParentDotConfig.Filename)
if err != nil {
return errors.New("error reading " + ParentsFile + ": " +
err.Error())
}
- stime, err := getFileModificationTime(c.StrategiesDotYaml.Filename)
+ stime, err := util.GetFileModificationTime(c.StrategiesDotYaml.Filename)
if err != nil {
return errors.New("error reading " + StrategiesFile + ": " +
err.Error())
}
@@ -372,22 +410,6 @@ func (c *ParentInfo) findATrafficMonitor() (string, error)
{
return tmHostname, nil
}
-// get the file modification times for a trafficserver configuration
-// file.
-func getFileModificationTime(fn string) (int64, error) {
- f, err := os.Open(fn)
- if err != nil {
- return 0, errors.New("opening " + fn + ": " + err.Error())
- }
- defer f.Close()
-
- finfo, err := f.Stat()
- if err != nil {
- return 0, errors.New("unable to get file status for " + fn + ":
" + err.Error())
- }
- return finfo.ModTime().UnixNano(), nil
-}
-
// parse out the hostname of a parent listed in parents.config
// or 'strategies.yaml'. the hostname can be an IP address.
func parseFqdn(fqdn string) string {
@@ -507,8 +529,8 @@ func (c *ParentInfo) readHostStatus(parentStatus
map[string]ParentStatus) error
parentStatus[hostName] = pstat
log.Infof("added Host '%s' from
ATS Host Status to the parents map\n", hostName)
} else {
- available := pstat.available()
- if pv.available() != available {
+ available :=
pstat.available(c.Cfg.ReasonCode)
+ if
pv.available(c.Cfg.ReasonCode) != available {
log.Infof("host status
for '%s' has changed to %s\n", hostName, pstat.Status())
parentStatus[hostName]
= pstat
}
diff --git a/cache-config/tm-health-client/tmutil/tmutil_test.go
b/cache-config/tm-health-client/tmagent/tmagent_test.go
similarity index 81%
rename from cache-config/tm-health-client/tmutil/tmutil_test.go
rename to cache-config/tm-health-client/tmagent/tmagent_test.go
index 417612d..f3ea96c 100644
--- a/cache-config/tm-health-client/tmutil/tmutil_test.go
+++ b/cache-config/tm-health-client/tmagent/tmagent_test.go
@@ -1,4 +1,4 @@
-package tmutil
+package tmagent
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -22,6 +22,7 @@ package tmutil
import (
"fmt"
"github.com/apache/trafficcontrol/cache-config/tm-health-client/config"
+ "github.com/apache/trafficcontrol/cache-config/tm-health-client/util"
"testing"
)
@@ -30,11 +31,17 @@ const (
)
func TestReadParentDotConfig(t *testing.T) {
+ cf := util.ConfigFile{
+ Filename: test_config_file,
+ LastModifyTime: 0,
+ }
+
cfg := config.Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
- parentDotConfig := ParentConfigFile{
+ parentDotConfig := util.ConfigFile{
Filename: "test_files/etc/parent.config",
LastModifyTime: 1,
}
@@ -44,7 +51,7 @@ func TestReadParentDotConfig(t *testing.T) {
Cfg: cfg,
}
- err := config.LoadConfig(&cfg, test_config_file)
+ _, err := config.LoadConfig(&cfg)
if err != nil {
t.Fatalf("failed to load %s: %s\n", test_config_file,
err.Error())
}
@@ -61,11 +68,17 @@ func TestReadParentDotConfig(t *testing.T) {
}
func TestReadStrategiesDotYaml(t *testing.T) {
+ cf := util.ConfigFile{
+ Filename: test_config_file,
+ LastModifyTime: 0,
+ }
+
cfg := config.Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
- strategiesDotYaml := ParentConfigFile{
+ strategiesDotYaml := util.ConfigFile{
Filename: "test_files/etc/strategies.yaml",
LastModifyTime: 1,
}
@@ -75,7 +88,7 @@ func TestReadStrategiesDotYaml(t *testing.T) {
Cfg: cfg,
}
- err := config.LoadConfig(&cfg, test_config_file)
+ _, err := config.LoadConfig(&cfg)
if err != nil {
t.Fatalf("failed to load %s: %s\n", test_config_file,
err.Error())
}
@@ -92,8 +105,14 @@ func TestReadStrategiesDotYaml(t *testing.T) {
}
func TestReadHostStatus(t *testing.T) {
+ cf := util.ConfigFile{
+ Filename: test_config_file,
+ LastModifyTime: 0,
+ }
+
cfg := config.Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
pi := ParentInfo{
@@ -101,7 +120,7 @@ func TestReadHostStatus(t *testing.T) {
Cfg: cfg,
}
- err := config.LoadConfig(&cfg, test_config_file)
+ _, err := config.LoadConfig(&cfg)
if err != nil {
t.Fatalf("failed to load %s: %s\n", test_config_file,
err.Error())
}
@@ -119,15 +138,21 @@ func TestReadHostStatus(t *testing.T) {
}
func TestFindATrafficMonitor(t *testing.T) {
+ cf := util.ConfigFile{
+ Filename: test_config_file,
+ LastModifyTime: 0,
+ }
+
cfg := config.Cfg{
- TrafficMonitors: make(map[string]bool, 0),
+ TrafficMonitors: make(map[string]bool, 0),
+ HealthClientConfigFile: cf,
}
pi := ParentInfo{
Cfg: cfg,
}
- err := config.LoadConfig(&cfg, test_config_file)
+ _, err := config.LoadConfig(&cfg)
if err != nil {
t.Fatalf("failed to load %s: %s\n", test_config_file,
err.Error())
}
@@ -154,7 +179,7 @@ func TestParentStatus(t *testing.T) {
ManualReason: false,
}
- available := pstat.available()
+ available := pstat.available("manual")
if available {
t.Fatalf("expected parent status for %s to be false, got %v\n",
pstat.Fqdn, available)
@@ -164,7 +189,7 @@ func TestParentStatus(t *testing.T) {
t.Fatalf("expected status 'DOWN' got %s\n", status)
}
pstat.ManualReason = true
- available = pstat.available()
+ available = pstat.available("active")
if !available {
t.Fatalf("expected parent status for %s to be true, got %v\n",
pstat.Fqdn, available)
@@ -174,7 +199,7 @@ func TestParentStatus(t *testing.T) {
t.Fatalf("expected status 'UP' got %s\n", status)
}
pstat.LocalReason = false
- available = pstat.available()
+ available = pstat.available("local")
if available {
t.Fatalf("expected parent status for %s to be false, got %v\n",
pstat.Fqdn, available)
@@ -186,7 +211,7 @@ func TestParentStatus(t *testing.T) {
pstat.LocalReason = true
pstat.ActiveReason = false
- available = pstat.available()
+ available = pstat.available("active")
if available {
t.Fatalf("expected parent status for %s to be false, got %v\n",
pstat.Fqdn, available)
@@ -196,7 +221,7 @@ func TestParentStatus(t *testing.T) {
t.Fatalf("expected status 'DOWN' got %s\n", status)
}
pstat.ActiveReason = true
- available = pstat.available()
+ available = pstat.available("active")
if !available {
t.Fatalf("expected parent status for %s to be false, got %v\n",
pstat.Fqdn, available)
diff --git a/cache-config/tm-health-client/tm-health-client.go
b/cache-config/tm-health-client/util/util.go
similarity index 57%
copy from cache-config/tm-health-client/tm-health-client.go
copy to cache-config/tm-health-client/util/util.go
index b84bc61..951c701 100644
--- a/cache-config/tm-health-client/tm-health-client.go
+++ b/cache-config/tm-health-client/util/util.go
@@ -1,4 +1,4 @@
-package main
+package util
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,34 +20,26 @@ package main
*/
import (
+ "errors"
"os"
-
- "github.com/apache/trafficcontrol/cache-config/tm-health-client/config"
- "github.com/apache/trafficcontrol/cache-config/tm-health-client/tmutil"
- "github.com/apache/trafficcontrol/lib/go-log"
)
-const (
- Success = 0
- ConfigError = 166
-)
+type ConfigFile struct {
+ Filename string
+ LastModifyTime int64
+}
-func main() {
- cfg, err, helpflag := config.GetConfig()
+// get the file modification times for a configuration file.
+func GetFileModificationTime(fn string) (int64, error) {
+ f, err := os.Open(fn)
if err != nil {
- log.Errorln(err.Error())
- os.Exit(ConfigError)
- } else {
- log.Infoln("startup complete, the config has been loaded")
- }
- if helpflag { // user used --help option
- os.Exit(Success)
+ return 0, errors.New("opening " + fn + ": " + err.Error())
}
+ defer f.Close()
- tmInfo, err := tmutil.NewParentInfo(cfg)
+ finfo, err := f.Stat()
if err != nil {
- log.Errorf("startup could not initialize ATS parent info:
%s\n", err.Error())
+ return 0, errors.New("unable to get file status for " + fn + ":
" + err.Error())
}
-
- tmInfo.PollAndUpdateCacheStatus()
+ return finfo.ModTime().UnixNano(), nil
}