You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ne...@apache.org on 2017/04/12 21:43:51 UTC
[01/13] incubator-trafficcontrol git commit: Add TM2 validator for
query interval
Repository: incubator-trafficcontrol
Updated Branches:
refs/heads/master 33fa72c4a -> 43bb5e0b6
Add TM2 validator for query interval
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/0f564553
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/0f564553
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/0f564553
Branch: refs/heads/master
Commit: 0f564553f62acd3a3092ccb4f5809707de7f2f1e
Parents: 095def7
Author: Robert Butts <ro...@gmail.com>
Authored: Thu Mar 30 17:01:53 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tmcheck/peerpoller.go | 29 +------
.../traffic_monitor/tmcheck/queryinterval.go | 85 ++++++++++++++++++++
.../traffic_monitor/tmcheck/tmcheck.go | 22 ++++-
.../tools/nagios-validate-queryinterval.go | 69 ++++++++++++++++
.../traffic_monitor/tools/validator-service.go | 9 ++-
5 files changed, 185 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0f564553/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go b/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
index cdeaf36..999142b 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
@@ -20,44 +20,21 @@
package tmcheck
import (
- "encoding/json"
"fmt"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
- "io/ioutil"
"time"
)
const PeerPollMax = time.Duration(10) * time.Second
-const TrafficMonitorStatsPath = "/publish/Stats"
-
-// TrafficMonitorStatsJSON represents the JSON returned by Traffic Monitor's Stats endpoint. This currently only contains the Oldest Polled Peer Time member, as needed by this library.
-type TrafficMonitorStatsJSON struct {
- Stats TrafficMonitorStats `json:"stats"`
-}
-
-// TrafficMonitorStats represents the internal JSON object returned by Traffic Monitor's Stats endpoint. This currently only contains the Oldest Polled Peer Time member, as needed by this library.
-type TrafficMonitorStats struct {
- OldestPolledPeerTime int `json:"Oldest Polled Peer Time (ms)"`
-}
-
func GetOldestPolledPeerTime(uri string) (time.Duration, error) {
- resp, err := getClient().Get(uri + TrafficMonitorStatsPath)
+ stats, err := GetStats(uri + TrafficMonitorStatsPath)
if err != nil {
- return time.Duration(0), fmt.Errorf("reading reply from %v: %v\n", uri, err)
- }
- respBytes, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return time.Duration(0), fmt.Errorf("reading reply from %v: %v\n", uri, err)
- }
-
- stats := TrafficMonitorStatsJSON{}
- if err := json.Unmarshal(respBytes, &stats); err != nil {
- return time.Duration(0), fmt.Errorf("unmarshalling: %v", err)
+ return time.Duration(0), fmt.Errorf("getting stats: %v", err)
}
- oldestPolledPeerTime := time.Duration(stats.Stats.OldestPolledPeerTime) * time.Millisecond
+ oldestPolledPeerTime := time.Duration(stats.OldestPolledPeerMs) * time.Millisecond
return oldestPolledPeerTime, nil
}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0f564553/traffic_monitor_golang/traffic_monitor/tmcheck/queryinterval.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/queryinterval.go b/traffic_monitor_golang/traffic_monitor/tmcheck/queryinterval.go
new file mode 100644
index 0000000..e302214
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/queryinterval.go
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package tmcheck
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+const QueryIntervalMax = time.Duration(10) * time.Second
+
+// ValidateQueryInterval validates the given monitor has an acceptable Query Interval 95th percentile.
+func ValidateQueryInterval(tmURI string, toClient *to.Session) error {
+ stats, err := GetStats(tmURI + TrafficMonitorStatsPath)
+ if err != nil {
+ return fmt.Errorf("getting Stats: %v", err)
+ }
+ queryInterval := time.Duration(stats.QueryInterval95thPercentile) * time.Millisecond
+
+ if queryInterval > QueryIntervalMax {
+ return fmt.Errorf("Query Interval 95th Percentile %v greater than max %v", queryInterval, QueryIntervalMax)
+ }
+ return nil
+}
+
+// QueryIntervalValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
+func QueryIntervalValidator(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+) {
+ Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, ValidateQueryInterval)
+}
+
+// AllMonitorsQueryIntervalValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
+func AllMonitorsQueryIntervalValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllMonitorsQueryInterval)
+}
+
+// ValidateAllMonitorsQueryInterval validates, for all monitors in the given Traffic Ops, an acceptable query interval 95th percentile.
+func ValidateAllMonitorsQueryInterval(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ servers, err := GetMonitors(toClient, includeOffline)
+ if err != nil {
+ return nil, err
+ }
+
+ errs := map[enum.TrafficMonitorName]error{}
+ for _, server := range servers {
+ uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
+ errs[enum.TrafficMonitorName(server.HostName)] = ValidateQueryInterval(uri, toClient)
+ }
+ return errs, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0f564553/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index 1ef2532..db1c182 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -29,6 +29,7 @@ import (
"time"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/crconfig"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/datareq"
dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/deliveryservicedata"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/peer"
@@ -40,6 +41,7 @@ const RequestTimeout = time.Second * time.Duration(30)
const TrafficMonitorCRStatesPath = "/publish/CrStates"
const TrafficMonitorDSStatsPath = "/publish/DsStats"
const TrafficMonitorConfigDocPath = "/publish/ConfigDoc"
+const TrafficMonitorStatsPath = "/publish/Stats"
func getClient() *http.Client {
return &http.Client{
@@ -89,7 +91,7 @@ func GetCRStates(uri string) (*peer.Crstates, error) {
return &states, nil
}
-// GetCRStates gets the CRStates from the given Traffic Monitor.
+// GetDSStats gets the DSStats from the given Traffic Monitor.
func GetDSStats(uri string) (*dsdata.StatsOld, error) {
resp, err := getClient().Get(uri)
if err != nil {
@@ -107,6 +109,24 @@ func GetDSStats(uri string) (*dsdata.StatsOld, error) {
return &dsStats, nil
}
+// GetStats gets the stats from the given Traffic Monitor.
+func GetStats(uri string) (*datareq.Stats, error) {
+ resp, err := getClient().Get(uri)
+ if err != nil {
+ return nil, fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+ respBytes, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+
+ stats := datareq.JSONStats{}
+ if err := json.Unmarshal(respBytes, &stats); err != nil {
+ return nil, fmt.Errorf("unmarshalling: %v", err)
+ }
+ return &stats.Stats, nil
+}
+
type ValidatorFunc func(
tmURI string,
toClient *to.Session,
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0f564553/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-queryinterval.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-queryinterval.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-queryinterval.go
new file mode 100644
index 0000000..279ea18
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-queryinterval.go
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/nagios"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+const UserAgent = "tm-queryinterval-validator/0.1"
+
+func main() {
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief || *toURI == "" {
+ fmt.Printf("Usage: ./nagios-validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
+ return
+ }
+
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ monitorErrs, err := tmcheck.ValidateAllMonitorsQueryInterval(toClient, *includeOffline)
+
+ if err != nil {
+ nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor offline statuses: %v", err))
+ }
+
+ errStr := ""
+ for monitor, err := range monitorErrs {
+ if err != nil {
+ errStr += fmt.Sprintf("error validating offline status for monitor %v : %v\n", monitor, err.Error())
+ }
+ }
+
+ if errStr != "" {
+ nagios.Exit(nagios.Critical, errStr)
+ }
+
+ nagios.Exit(nagios.Ok, "")
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0f564553/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
index 5dc1e04..20dff82 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
@@ -158,8 +158,9 @@ func main() {
crStatesOfflineLogs := startValidator(tmcheck.AllMonitorsCRStatesOfflineValidator, toClient, *interval, *includeOffline, *grace)
peerPollerLogs := startValidator(tmcheck.PeerPollersAllValidator, toClient, *interval, *includeOffline, *grace)
dsStatsLogs := startValidator(tmcheck.AllMonitorsDSStatsValidator, toClient, *interval, *includeOffline, *grace)
+ queryIntervalLogs := startValidator(tmcheck.AllMonitorsQueryIntervalValidator, toClient, *interval, *includeOffline, *grace)
- if err := serve(*toURI, crStatesOfflineLogs, peerPollerLogs, dsStatsLogs); err != nil {
+ if err := serve(*toURI, crStatesOfflineLogs, peerPollerLogs, dsStatsLogs, queryIntervalLogs); err != nil {
fmt.Printf("Serve error: %v\n", err)
}
}
@@ -199,7 +200,7 @@ func printLogs(logs Logs, w io.Writer) {
fmt.Fprintf(w, `</table>`)
}
-func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs, dsStatsLogs Logs) error {
+func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs, dsStatsLogs Logs, queryIntervalLogs Logs) error {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "text/html")
@@ -226,6 +227,10 @@ func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs, dsStatsL
fmt.Fprintf(w, `<h2>Delivery Services</h2>`)
fmt.Fprintf(w, `<h3>validates all Delivery Services in the CRConfig exist in DsStats</h3>`)
printLogs(dsStatsLogs, w)
+
+ fmt.Fprintf(w, `<h2>Query Interval</h2>`)
+ fmt.Fprintf(w, `<h3>validates all Monitors' Query Interval (95th percentile) is less than %v</h3>`, tmcheck.QueryIntervalMax)
+ printLogs(queryIntervalLogs, w)
})
return http.ListenAndServe(":80", nil)
}
[12/13] incubator-trafficcontrol git commit: Add TM2 nagios
peerpoller checking all TMs in TO
Posted by ne...@apache.org.
Add TM2 nagios peerpoller checking all TMs in TO
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/2fdd9317
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/2fdd9317
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/2fdd9317
Branch: refs/heads/master
Commit: 2fdd9317a407fb6dfe924714630483c8b760c1a3
Parents: 5a6cf95
Author: Robert Butts <ro...@gmail.com>
Authored: Wed Mar 15 11:15:46 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../tools/nagios-validate-offline.go | 19 +++++++
.../tools/nagios-validate-peerpoller.go | 57 +++++++++++++++-----
2 files changed, 64 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/2fdd9317/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
index a54b8c5..ec2b9bd 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package main
import (
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/2fdd9317/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
index 5e9c9fd..6af1a51 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package main
import (
@@ -5,32 +24,46 @@ import (
"fmt"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/nagios"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
)
const UserAgent = "tm-peerpoller-validator/0.1"
func main() {
- tmURI := flag.String("tm", "", "The Traffic Monitor URI, whose Peer Poller to validate")
- // toUser := flag.String("touser", "", "The Traffic Ops user")
- // toPass := flag.String("topass", "", "The Traffic Ops password")
- // includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
help := flag.Bool("help", false, "Usage info")
helpBrief := flag.Bool("h", false, "Usage info")
flag.Parse()
- if *help || *helpBrief {
+ if *help || *helpBrief || *toURI == "" {
fmt.Printf("Usage: ./nagios-validate-peerpoller -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
return
}
- // toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
- // if err != nil {
- // fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
- // return
- // }
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ monitorErrs, err := tmcheck.ValidateAllPeerPollers(toClient, *includeOffline)
- err := tmcheck.ValidatePeerPoller(*tmURI)
if err != nil {
- nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor peer poller: %v", err))
+ nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor peer pollers: %v", err))
}
+
+ errStr := ""
+ for monitor, err := range monitorErrs {
+ if err != nil {
+ errStr += fmt.Sprintf("error validating offline status for monitor %v : %v\n", monitor, err.Error())
+ }
+ }
+
+ if errStr != "" {
+ nagios.Exit(nagios.Critical, errStr)
+ }
+
nagios.Exit(nagios.Ok, "")
}
[04/13] incubator-trafficcontrol git commit: Add TM2 tmcheck
validator for all monitors
Posted by ne...@apache.org.
Add TM2 tmcheck validator for all monitors
Adds tmcheck.ValidateAllMonitorsOfflineStates, which efficiently
checks all monitors in Traffic Ops (i.e. only getting the CRConfig
once).
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/83b58d97
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/83b58d97
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/83b58d97
Branch: refs/heads/master
Commit: 83b58d97fb868309db0db48963a66f85a91caadb
Parents: 33fa72c
Author: Robert Butts <ro...@gmail.com>
Authored: Thu Mar 2 11:29:07 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/enum/enum.go | 3 +
.../traffic_monitor/tmcheck/tmcheck.go | 142 ++++++++++++++++++-
.../traffic_monitor/tools/validate-offline.go | 6 +-
3 files changed, 143 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/83b58d97/traffic_monitor_golang/traffic_monitor/enum/enum.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/enum/enum.go b/traffic_monitor_golang/traffic_monitor/enum/enum.go
index 45546bd..1c06ac8 100644
--- a/traffic_monitor_golang/traffic_monitor/enum/enum.go
+++ b/traffic_monitor_golang/traffic_monitor/enum/enum.go
@@ -32,6 +32,9 @@ import (
"strings"
)
+// CDNName is the name of a CDN in Traffic Control.
+type CDNName string
+
// TrafficMonitorName is the hostname of a Traffic Monitor peer.
type TrafficMonitorName string
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/83b58d97/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index d6a964e..1178721 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -93,8 +93,12 @@ func ValidateOfflineStates(tmURI string, toClient *to.Session) error {
if err != nil {
return fmt.Errorf("getting CDN from Traffic Monitor: %v", err)
}
+ return ValidateOfflineStatesWithCDN(tmURI, cdn, toClient)
+}
- crConfigBytes, err := toClient.CRConfigRaw(cdn)
+// ValidateOfflineStatesWithCDN validates per ValidateOfflineStates, but saves an additional query if the Traffic Monitor's CDN is known.
+func ValidateOfflineStatesWithCDN(tmURI string, tmCDN string, toClient *to.Session) error {
+ crConfigBytes, err := toClient.CRConfigRaw(tmCDN)
if err != nil {
return fmt.Errorf("getting CRConfig: %v", err)
}
@@ -104,19 +108,24 @@ func ValidateOfflineStates(tmURI string, toClient *to.Session) error {
return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
}
+ return ValidateOfflineStatesWithCRConfig(tmURI, &crConfig, toClient)
+}
+
+// ValidateOfflineStatesWithCRConfig validates per ValidateOfflineStates, but saves querying the CRconfig if it's already fetched.
+func ValidateOfflineStatesWithCRConfig(tmURI string, crConfig *crconfig.CRConfig, toClient *to.Session) error {
crStates, err := GetCRStates(tmURI + TrafficMonitorCRStatesPath)
if err != nil {
return fmt.Errorf("getting CRStates: %v", err)
}
- return ValidateCRStates(crStates, &crConfig)
+ return ValidateCRStates(crStates, crConfig)
}
// ValidateCRStates validates that no OFFLINE or ADMIN_DOWN caches in the given CRConfig are marked Available in the given CRStates.
func ValidateCRStates(crstates *peer.Crstates, crconfig *crconfig.CRConfig) error {
for cacheName, cacheInfo := range crconfig.ContentServers {
status := enum.CacheStatusFromString(string(*cacheInfo.Status))
- if status != enum.CacheStatusOffline || status != enum.CacheStatusOffline {
+ if status != enum.CacheStatusAdminDown || status != enum.CacheStatusOffline {
continue
}
@@ -133,8 +142,8 @@ func ValidateCRStates(crstates *peer.Crstates, crconfig *crconfig.CRConfig) erro
return nil
}
-// Validator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
-func Validator(
+// CRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
+func CRStatesOfflineValidator(
tmURI string,
toClient *to.Session,
interval time.Duration,
@@ -170,3 +179,126 @@ func Validator(
time.Sleep(interval)
}
}
+
+// CRConfigOrError contains a CRConfig or an error. Union types? Monads? What are those?
+type CRConfigOrError struct {
+ CRConfig *crconfig.CRConfig
+ Err error
+}
+
+// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
+func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ trafficMonitorType := "RASCAL"
+ monitorTypeQuery := map[string][]string{"type": []string{trafficMonitorType}}
+ servers, err := toClient.ServersByType(monitorTypeQuery)
+ if err != nil {
+ return nil, fmt.Errorf("getting monitors from Traffic Ops: %v", err)
+ }
+
+ if !includeOffline {
+ servers = FilterOfflines(servers)
+ }
+
+ crConfigs := GetCRConfigs(GetCDNs(servers), toClient)
+
+ errs := map[enum.TrafficMonitorName]error{}
+ for _, server := range servers {
+ crConfig := crConfigs[enum.CDNName(server.CDNName)]
+ if err := crConfig.Err; err != nil {
+ errs[enum.TrafficMonitorName(server.HostName)] = fmt.Errorf("getting CRConfig: %v", err)
+ continue
+ }
+
+ fqdn := fmt.Sprintf("%s.%s", server.HostName, server.DomainName)
+ if err := ValidateOfflineStatesWithCRConfig(fqdn, crConfig.CRConfig, toClient); err != nil {
+ errs[enum.TrafficMonitorName(server.HostName)] = err
+ }
+ }
+ return errs, nil
+}
+
+// AllMonitorsCRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
+func AllMonitorsCRStatesOfflineValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ invalid := map[enum.TrafficMonitorName]bool{}
+ invalidStart := map[enum.TrafficMonitorName]time.Time{}
+ for {
+ tmErrs, err := ValidateAllMonitorsOfflineStates(toClient, includeOffline) // []MonitorError {
+ if err != nil {
+ onErr("", fmt.Errorf("Error validating monitors: %v", err))
+ time.Sleep(interval)
+ }
+
+ for name, err := range tmErrs {
+ if err != nil && !invalid[name] {
+ invalid[name] = true
+ invalidStart[name] = time.Now()
+ }
+
+ if err != nil {
+ invalidSpan := time.Now().Sub(invalidStart[name])
+ if invalidSpan > grace {
+ onErr(name, fmt.Errorf("invalid state for %v: %v\n", invalidSpan, err))
+ }
+ }
+
+ onCheck(name, err)
+ }
+
+ for tm, tmInvalid := range invalid {
+ if _, ok := tmErrs[tm]; tmInvalid && !ok {
+ onResumeSuccess(tm)
+ invalid[tm] = false
+ }
+ }
+
+ time.Sleep(interval)
+ }
+}
+
+// FilterOfflines returns only servers which are REPORTED or ONLINE
+func FilterOfflines(servers []to.Server) []to.Server {
+ onlineServers := []to.Server{}
+ for _, server := range servers {
+ status := enum.CacheStatusFromString(server.Status)
+ if status != enum.CacheStatusOnline && status != enum.CacheStatusReported {
+ continue
+ }
+ onlineServers = append(onlineServers, server)
+ }
+ return onlineServers
+}
+
+func GetCDNs(servers []to.Server) map[enum.CDNName]struct{} {
+ cdns := map[enum.CDNName]struct{}{}
+ for _, server := range servers {
+ cdns[enum.CDNName(server.CDNName)] = struct{}{}
+ }
+ return cdns
+}
+
+func GetCRConfigs(cdns map[enum.CDNName]struct{}, toClient *to.Session) map[enum.CDNName]CRConfigOrError {
+ crConfigs := map[enum.CDNName]CRConfigOrError{}
+ for cdn, _ := range cdns {
+ crConfigBytes, err := toClient.CRConfigRaw(string(cdn))
+ if err != nil {
+ crConfigs[cdn] = CRConfigOrError{Err: fmt.Errorf("getting CRConfig: %v", err)}
+ continue
+ }
+
+ crConfig := crconfig.CRConfig{}
+ if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
+ crConfigs[cdn] = CRConfigOrError{Err: fmt.Errorf("unmarshalling CRConfig JSON: %v", err)}
+ }
+
+ crConfigs[cdn] = CRConfigOrError{CRConfig: &crConfig}
+ }
+ return crConfigs
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/83b58d97/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
index 92b17c7..07eee78 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
@@ -117,7 +117,7 @@ func main() {
}
}
- go tmcheck.Validator(*tmURI, toClient, *interval, *grace, onErr, onResumeSuccess, onCheck)
+ go tmcheck.CRStatesOfflineValidator(*tmURI, toClient, *interval, *grace, onErr, onResumeSuccess, onCheck)
if err := serve(log, *toURI, *tmURI); err != nil {
fmt.Printf("Serve error: %v\n", err)
@@ -145,8 +145,8 @@ func serve(log Log, toURI string, tmURI string) error {
fmt.Fprintf(w, `<pre>`)
logCopy := log.Get()
- for i := len(logCopy) - 1; i >= 0; i-- {
- fmt.Fprintf(w, "%s\n", logCopy[i])
+ for _, msg := range logCopy {
+ fmt.Fprintf(w, "%s\n", msg)
}
fmt.Fprintf(w, `</pre>`)
[08/13] incubator-trafficcontrol git commit: Fix TM2 nagios.go
missing license header
Posted by ne...@apache.org.
Fix TM2 nagios.go missing license header
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/4658c510
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/4658c510
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/4658c510
Branch: refs/heads/master
Commit: 4658c510257d70572f45949abbad6ab08cf58403
Parents: 6abf64a
Author: Robert Butts <ro...@gmail.com>
Authored: Fri Mar 3 12:32:36 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
traffic_monitor_golang/common/nagios/nagios.go | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4658c510/traffic_monitor_golang/common/nagios/nagios.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/common/nagios/nagios.go b/traffic_monitor_golang/common/nagios/nagios.go
index 53af782..a8ce6bd 100644
--- a/traffic_monitor_golang/common/nagios/nagios.go
+++ b/traffic_monitor_golang/common/nagios/nagios.go
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package nagios
import (
[09/13] incubator-trafficcontrol git commit: Fix TM2 nagios-validate
without args to show usage
Posted by ne...@apache.org.
Fix TM2 nagios-validate without args to show usage
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/5a6cf95e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/5a6cf95e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/5a6cf95e
Branch: refs/heads/master
Commit: 5a6cf95e3a32d0aa405ec34abb6e9a4972922b02
Parents: d87c8b3
Author: Robert Butts <ro...@gmail.com>
Authored: Wed Mar 15 11:03:41 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tools/nagios-validate-offline.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/5a6cf95e/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
index 6a1ab96..a54b8c5 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
@@ -18,7 +18,7 @@ func main() {
help := flag.Bool("help", false, "Usage info")
helpBrief := flag.Bool("h", false, "Usage info")
flag.Parse()
- if *help || *helpBrief {
+ if *help || *helpBrief || *toURI == "" {
fmt.Printf("Usage: ./nagios-validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
return
}
[07/13] incubator-trafficcontrol git commit: Fix TM2 offline
validator to onResume metafailures
Posted by ne...@apache.org.
Fix TM2 offline validator to onResume metafailures
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/6abf64aa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/6abf64aa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/6abf64aa
Branch: refs/heads/master
Commit: 6abf64aa97f23640cdb659581f0d7e373fa50700
Parents: 667ed34
Author: Robert Butts <ro...@gmail.com>
Authored: Fri Mar 3 12:29:06 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go | 5 +++++
1 file changed, 5 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6abf64aa/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index fa2c533..819c1ab 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -227,11 +227,16 @@ func AllMonitorsCRStatesOfflineValidator(
) {
invalid := map[enum.TrafficMonitorName]bool{}
invalidStart := map[enum.TrafficMonitorName]time.Time{}
+ metaFail := false
for {
tmErrs, err := ValidateAllMonitorsOfflineStates(toClient, includeOffline)
if err != nil {
onErr("", fmt.Errorf("Error validating monitors: %v", err))
time.Sleep(interval)
+ metaFail = true
+ } else if metaFail {
+ onResumeSuccess("")
+ metaFail = false
}
for name, err := range tmErrs {
[10/13] incubator-trafficcontrol git commit: Move TM2 tmcheck
offlinestates funcs to file
Posted by ne...@apache.org.
Move TM2 tmcheck offlinestates funcs to file
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/0dd73c1b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/0dd73c1b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/0dd73c1b
Branch: refs/heads/master
Commit: 0dd73c1b85477085887c9dc0899ded4f7f77f334
Parents: 2fdd931
Author: Robert Butts <ro...@gmail.com>
Authored: Thu Mar 30 08:50:11 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tmcheck/offlinestates.go | 135 +++++++++++++++++++
.../traffic_monitor/tmcheck/tmcheck.go | 104 --------------
2 files changed, 135 insertions(+), 104 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0dd73c1b/traffic_monitor_golang/traffic_monitor/tmcheck/offlinestates.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/offlinestates.go b/traffic_monitor_golang/traffic_monitor/tmcheck/offlinestates.go
new file mode 100644
index 0000000..9226ea1
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/offlinestates.go
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package tmcheck
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/crconfig"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/peer"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
+func ValidateOfflineStates(tmURI string, toClient *to.Session) error {
+ cdn, err := GetCDN(tmURI)
+ if err != nil {
+ return fmt.Errorf("getting CDN from Traffic Monitor: %v", err)
+ }
+ return ValidateOfflineStatesWithCDN(tmURI, cdn, toClient)
+}
+
+// ValidateOfflineStatesWithCDN validates per ValidateOfflineStates, but saves an additional query if the Traffic Monitor's CDN is known.
+func ValidateOfflineStatesWithCDN(tmURI string, tmCDN string, toClient *to.Session) error {
+ crConfigBytes, err := toClient.CRConfigRaw(tmCDN)
+ if err != nil {
+ return fmt.Errorf("getting CRConfig: %v", err)
+ }
+
+ crConfig := crconfig.CRConfig{}
+ if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
+ return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
+ }
+
+ return ValidateOfflineStatesWithCRConfig(tmURI, &crConfig, toClient)
+}
+
+// ValidateOfflineStatesWithCRConfig validates per ValidateOfflineStates, but saves querying the CRconfig if it's already fetched.
+func ValidateOfflineStatesWithCRConfig(tmURI string, crConfig *crconfig.CRConfig, toClient *to.Session) error {
+ crStates, err := GetCRStates(tmURI + TrafficMonitorCRStatesPath)
+ if err != nil {
+ return fmt.Errorf("getting CRStates: %v", err)
+ }
+
+ return ValidateCRStates(crStates, crConfig)
+}
+
+// ValidateCRStates validates that no OFFLINE or ADMIN_DOWN caches in the given CRConfig are marked Available in the given CRStates.
+func ValidateCRStates(crstates *peer.Crstates, crconfig *crconfig.CRConfig) error {
+ for cacheName, cacheInfo := range crconfig.ContentServers {
+ status := enum.CacheStatusFromString(string(*cacheInfo.Status))
+ if status != enum.CacheStatusAdminDown || status != enum.CacheStatusOffline {
+ continue
+ }
+
+ available, ok := crstates.Caches[enum.CacheName(cacheName)]
+ if !ok {
+ return fmt.Errorf("Cache %v in CRConfig but not CRStates", cacheName)
+ }
+
+ if available.IsAvailable {
+ return fmt.Errorf("Cache %v is %v in CRConfig, but available in CRStates", cacheName, status)
+ }
+
+ }
+ return nil
+}
+
+// CRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
+func CRStatesOfflineValidator(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+) {
+ Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, ValidateOfflineStates)
+}
+
+// AllMonitorsCRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
+func AllMonitorsCRStatesOfflineValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllMonitorsOfflineStates)
+}
+
+// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
+func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ servers, err := GetMonitors(toClient, includeOffline)
+ if err != nil {
+ return nil, err
+ }
+
+ crConfigs := GetCRConfigs(GetCDNs(servers), toClient)
+
+ errs := map[enum.TrafficMonitorName]error{}
+ for _, server := range servers {
+ crConfig := crConfigs[enum.CDNName(server.CDNName)]
+ if err := crConfig.Err; err != nil {
+ errs[enum.TrafficMonitorName(server.HostName)] = fmt.Errorf("getting CRConfig: %v", err)
+ continue
+ }
+
+ uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
+ errs[enum.TrafficMonitorName(server.HostName)] = ValidateOfflineStatesWithCRConfig(uri, crConfig.CRConfig, toClient)
+ }
+ return errs, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0dd73c1b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index a6e12ba..9c6016b 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -87,61 +87,6 @@ func GetCRStates(uri string) (*peer.Crstates, error) {
return &states, nil
}
-// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
-func ValidateOfflineStates(tmURI string, toClient *to.Session) error {
- cdn, err := GetCDN(tmURI)
- if err != nil {
- return fmt.Errorf("getting CDN from Traffic Monitor: %v", err)
- }
- return ValidateOfflineStatesWithCDN(tmURI, cdn, toClient)
-}
-
-// ValidateOfflineStatesWithCDN validates per ValidateOfflineStates, but saves an additional query if the Traffic Monitor's CDN is known.
-func ValidateOfflineStatesWithCDN(tmURI string, tmCDN string, toClient *to.Session) error {
- crConfigBytes, err := toClient.CRConfigRaw(tmCDN)
- if err != nil {
- return fmt.Errorf("getting CRConfig: %v", err)
- }
-
- crConfig := crconfig.CRConfig{}
- if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
- return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
- }
-
- return ValidateOfflineStatesWithCRConfig(tmURI, &crConfig, toClient)
-}
-
-// ValidateOfflineStatesWithCRConfig validates per ValidateOfflineStates, but saves querying the CRconfig if it's already fetched.
-func ValidateOfflineStatesWithCRConfig(tmURI string, crConfig *crconfig.CRConfig, toClient *to.Session) error {
- crStates, err := GetCRStates(tmURI + TrafficMonitorCRStatesPath)
- if err != nil {
- return fmt.Errorf("getting CRStates: %v", err)
- }
-
- return ValidateCRStates(crStates, crConfig)
-}
-
-// ValidateCRStates validates that no OFFLINE or ADMIN_DOWN caches in the given CRConfig are marked Available in the given CRStates.
-func ValidateCRStates(crstates *peer.Crstates, crconfig *crconfig.CRConfig) error {
- for cacheName, cacheInfo := range crconfig.ContentServers {
- status := enum.CacheStatusFromString(string(*cacheInfo.Status))
- if status != enum.CacheStatusAdminDown || status != enum.CacheStatusOffline {
- continue
- }
-
- available, ok := crstates.Caches[enum.CacheName(cacheName)]
- if !ok {
- return fmt.Errorf("Cache %v in CRConfig but not CRStates", cacheName)
- }
-
- if available.IsAvailable {
- return fmt.Errorf("Cache %v is %v in CRConfig, but available in CRStates", cacheName, status)
- }
-
- }
- return nil
-}
-
type ValidatorFunc func(
tmURI string,
toClient *to.Session,
@@ -201,19 +146,6 @@ func Validator(
}
}
-// CRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
-func CRStatesOfflineValidator(
- tmURI string,
- toClient *to.Session,
- interval time.Duration,
- grace time.Duration,
- onErr func(error),
- onResumeSuccess func(),
- onCheck func(error),
-) {
- Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, ValidateOfflineStates)
-}
-
// CRConfigOrError contains a CRConfig or an error. Union types? Monads? What are those?
type CRConfigOrError struct {
CRConfig *crconfig.CRConfig
@@ -234,29 +166,6 @@ func GetMonitors(toClient *to.Session, includeOffline bool) ([]to.Server, error)
return servers, nil
}
-// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
-func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
- servers, err := GetMonitors(toClient, includeOffline)
- if err != nil {
- return nil, err
- }
-
- crConfigs := GetCRConfigs(GetCDNs(servers), toClient)
-
- errs := map[enum.TrafficMonitorName]error{}
- for _, server := range servers {
- crConfig := crConfigs[enum.CDNName(server.CDNName)]
- if err := crConfig.Err; err != nil {
- errs[enum.TrafficMonitorName(server.HostName)] = fmt.Errorf("getting CRConfig: %v", err)
- continue
- }
-
- uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
- errs[enum.TrafficMonitorName(server.HostName)] = ValidateOfflineStatesWithCRConfig(uri, crConfig.CRConfig, toClient)
- }
- return errs, nil
-}
-
func AllValidator(
toClient *to.Session,
interval time.Duration,
@@ -308,19 +217,6 @@ func AllValidator(
}
}
-// AllMonitorsCRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
-func AllMonitorsCRStatesOfflineValidator(
- toClient *to.Session,
- interval time.Duration,
- includeOffline bool,
- grace time.Duration,
- onErr func(enum.TrafficMonitorName, error),
- onResumeSuccess func(enum.TrafficMonitorName),
- onCheck func(enum.TrafficMonitorName, error),
-) {
- AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllMonitorsOfflineStates)
-}
-
// FilterOfflines returns only servers which are REPORTED or ONLINE
func FilterOfflines(servers []to.Server) []to.Server {
onlineServers := []to.Server{}
[11/13] incubator-trafficcontrol git commit: Add TM2 validator for
peer pollers
Posted by ne...@apache.org.
Add TM2 validator for peer pollers
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/c9196a12
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/c9196a12
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/c9196a12
Branch: refs/heads/master
Commit: c9196a12e57c381b8ba6de29e2aa4009a27a1f14
Parents: 4658c51
Author: Robert Butts <ro...@gmail.com>
Authored: Fri Mar 3 15:39:10 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tmcheck/peerpoller.go | 112 ++++++++++
.../traffic_monitor/tmcheck/tmcheck.go | 69 +++++-
.../tools/nagios-validate-peerpoller.go | 36 +++
.../tools/service-validate-offline.go | 204 -----------------
.../traffic_monitor/tools/validator-service.go | 222 +++++++++++++++++++
5 files changed, 432 insertions(+), 211 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/c9196a12/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go b/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
new file mode 100644
index 0000000..cdeaf36
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/peerpoller.go
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package tmcheck
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+ "io/ioutil"
+ "time"
+)
+
+const PeerPollMax = time.Duration(10) * time.Second
+
+const TrafficMonitorStatsPath = "/publish/Stats"
+
+// TrafficMonitorStatsJSON represents the JSON returned by Traffic Monitor's Stats endpoint. This currently only contains the Oldest Polled Peer Time member, as needed by this library.
+type TrafficMonitorStatsJSON struct {
+ Stats TrafficMonitorStats `json:"stats"`
+}
+
+// TrafficMonitorStats represents the internal JSON object returned by Traffic Monitor's Stats endpoint. This currently only contains the Oldest Polled Peer Time member, as needed by this library.
+type TrafficMonitorStats struct {
+ OldestPolledPeerTime int `json:"Oldest Polled Peer Time (ms)"`
+}
+
+func GetOldestPolledPeerTime(uri string) (time.Duration, error) {
+ resp, err := getClient().Get(uri + TrafficMonitorStatsPath)
+ if err != nil {
+ return time.Duration(0), fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+ respBytes, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return time.Duration(0), fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+
+ stats := TrafficMonitorStatsJSON{}
+ if err := json.Unmarshal(respBytes, &stats); err != nil {
+ return time.Duration(0), fmt.Errorf("unmarshalling: %v", err)
+ }
+
+ oldestPolledPeerTime := time.Duration(stats.Stats.OldestPolledPeerTime) * time.Millisecond
+
+ return oldestPolledPeerTime, nil
+}
+
+func ValidatePeerPoller(uri string) error {
+ lastPollTime, err := GetOldestPolledPeerTime(uri)
+ if err != nil {
+ return fmt.Errorf("failed to get oldest peer time: %v", err)
+ }
+ if lastPollTime > PeerPollMax {
+ return fmt.Errorf("Peer poller is dead, last poll was %v ago", lastPollTime)
+ }
+ return nil
+}
+
+func ValidateAllPeerPollers(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ servers, err := GetMonitors(toClient, includeOffline)
+ if err != nil {
+ return nil, err
+ }
+ errs := map[enum.TrafficMonitorName]error{}
+ for _, server := range servers {
+ uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
+ errs[enum.TrafficMonitorName(server.HostName)] = ValidatePeerPoller(uri)
+ }
+ return errs, nil
+}
+
+func PeerPollersValidator(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+) {
+ wrapValidatePeerPoller := func(uri string, _ *to.Session) error { return ValidatePeerPoller(uri) }
+ Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, wrapValidatePeerPoller)
+}
+
+func PeerPollersAllValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllPeerPollers)
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/c9196a12/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index 819c1ab..a6e12ba 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -142,8 +142,28 @@ func ValidateCRStates(crstates *peer.Crstates, crconfig *crconfig.CRConfig) erro
return nil
}
+type ValidatorFunc func(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+)
+
+type AllValidatorFunc func(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+)
+
// CRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
-func CRStatesOfflineValidator(
+func Validator(
tmURI string,
toClient *to.Session,
interval time.Duration,
@@ -151,11 +171,12 @@ func CRStatesOfflineValidator(
onErr func(error),
onResumeSuccess func(),
onCheck func(error),
+ validator func(tmURI string, toClient *to.Session) error,
) {
invalid := false
invalidStart := time.Time{}
for {
- err := ValidateOfflineStates(tmURI, toClient)
+ err := validator(tmURI, toClient)
if err != nil && !invalid {
invalid = true
@@ -180,14 +201,26 @@ func CRStatesOfflineValidator(
}
}
+// CRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
+func CRStatesOfflineValidator(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+) {
+ Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, ValidateOfflineStates)
+}
+
// CRConfigOrError contains a CRConfig or an error. Union types? Monads? What are those?
type CRConfigOrError struct {
CRConfig *crconfig.CRConfig
Err error
}
-// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
-func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+func GetMonitors(toClient *to.Session, includeOffline bool) ([]to.Server, error) {
trafficMonitorType := "RASCAL"
monitorTypeQuery := map[string][]string{"type": []string{trafficMonitorType}}
servers, err := toClient.ServersByType(monitorTypeQuery)
@@ -198,6 +231,15 @@ func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool)
if !includeOffline {
servers = FilterOfflines(servers)
}
+ return servers, nil
+}
+
+// ValidateOfflineStates validates that no OFFLINE or ADMIN_DOWN caches in the given Traffic Ops' CRConfig are marked Available in the given Traffic Monitor's CRStates.
+func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ servers, err := GetMonitors(toClient, includeOffline)
+ if err != nil {
+ return nil, err
+ }
crConfigs := GetCRConfigs(GetCDNs(servers), toClient)
@@ -215,8 +257,7 @@ func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool)
return errs, nil
}
-// AllMonitorsCRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
-func AllMonitorsCRStatesOfflineValidator(
+func AllValidator(
toClient *to.Session,
interval time.Duration,
includeOffline bool,
@@ -224,12 +265,13 @@ func AllMonitorsCRStatesOfflineValidator(
onErr func(enum.TrafficMonitorName, error),
onResumeSuccess func(enum.TrafficMonitorName),
onCheck func(enum.TrafficMonitorName, error),
+ validator func(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error),
) {
invalid := map[enum.TrafficMonitorName]bool{}
invalidStart := map[enum.TrafficMonitorName]time.Time{}
metaFail := false
for {
- tmErrs, err := ValidateAllMonitorsOfflineStates(toClient, includeOffline)
+ tmErrs, err := validator(toClient, includeOffline)
if err != nil {
onErr("", fmt.Errorf("Error validating monitors: %v", err))
time.Sleep(interval)
@@ -266,6 +308,19 @@ func AllMonitorsCRStatesOfflineValidator(
}
}
+// AllMonitorsCRStatesOfflineValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
+func AllMonitorsCRStatesOfflineValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllMonitorsOfflineStates)
+}
+
// FilterOfflines returns only servers which are REPORTED or ONLINE
func FilterOfflines(servers []to.Server) []to.Server {
onlineServers := []to.Server{}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/c9196a12/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
new file mode 100644
index 0000000..5e9c9fd
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-peerpoller.go
@@ -0,0 +1,36 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/nagios"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+)
+
+const UserAgent = "tm-peerpoller-validator/0.1"
+
+func main() {
+ tmURI := flag.String("tm", "", "The Traffic Monitor URI, whose Peer Poller to validate")
+ // toUser := flag.String("touser", "", "The Traffic Ops user")
+ // toPass := flag.String("topass", "", "The Traffic Ops password")
+ // includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief {
+ fmt.Printf("Usage: ./nagios-validate-peerpoller -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
+ return
+ }
+
+ // toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ // if err != nil {
+ // fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ // return
+ // }
+
+ err := tmcheck.ValidatePeerPoller(*tmURI)
+ if err != nil {
+ nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor peer poller: %v", err))
+ }
+ nagios.Exit(nagios.Ok, "")
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/c9196a12/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
deleted file mode 100644
index 41e0eb4..0000000
--- a/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// validate-offline is a utility HTTP service which polls the given Traffic Monitor and validates that no OFFLINE or ADMIN_DOWN caches in the Traffic Ops CRConfig are marked Available in Traffic Monitor's CRstates endpoint.
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
- to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
- "net/http"
- "sort"
- "sync"
- "time"
-)
-
-const UserAgent = "tm-offline-validator/0.1"
-
-const LogLimit = 10
-
-type Log struct {
- log *[]string
- limit int
- errored *bool
- lastCheck *time.Time
- m *sync.RWMutex
-}
-
-func (l *Log) Add(msg string) {
- l.m.Lock()
- defer l.m.Unlock()
- *l.log = append([]string{msg}, *l.log...)
- if len(*l.log) > l.limit {
- *l.log = (*l.log)[:l.limit]
- }
-}
-
-func (l *Log) Get() []string {
- l.m.RLock()
- defer l.m.RUnlock()
- return *l.log
-}
-
-func (l *Log) GetErrored() (bool, time.Time) {
- l.m.RLock()
- defer l.m.RUnlock()
- return *l.errored, *l.lastCheck
-}
-
-func (l *Log) SetErrored(e bool) {
- l.m.Lock()
- defer l.m.Unlock()
- *l.errored = e
- *l.lastCheck = time.Now()
-}
-
-func NewLog() Log {
- log := make([]string, 0, LogLimit+1)
- errored := false
- limit := LogLimit
- lastCheck := time.Time{}
- return Log{log: &log, errored: &errored, m: &sync.RWMutex{}, limit: limit, lastCheck: &lastCheck}
-}
-
-type Logs struct {
- logs map[enum.TrafficMonitorName]Log
- m *sync.RWMutex
-}
-
-func NewLogs() Logs {
- return Logs{logs: map[enum.TrafficMonitorName]Log{}, m: &sync.RWMutex{}}
-}
-
-func (l Logs) Get(name enum.TrafficMonitorName) Log {
- l.m.Lock()
- defer l.m.Unlock()
- if _, ok := l.logs[name]; !ok {
- l.logs[name] = NewLog()
- }
- return l.logs[name]
-}
-
-func (l Logs) GetMonitors() []string {
- l.m.RLock()
- defer l.m.RUnlock()
- monitors := []string{}
- for name, _ := range l.logs {
- monitors = append(monitors, string(name))
- }
- return monitors
-}
-
-func main() {
- toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
- toUser := flag.String("touser", "", "The Traffic Ops user")
- toPass := flag.String("topass", "", "The Traffic Ops password")
- interval := flag.Duration("interval", time.Second*time.Duration(5), "The interval to validate")
- grace := flag.Duration("grace", time.Second*time.Duration(30), "The grace period before invalid states are reported")
- includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
- help := flag.Bool("help", false, "Usage info")
- helpBrief := flag.Bool("h", false, "Usage info")
- flag.Parse()
- if *help || *helpBrief {
- fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s -includeOffline true\n")
- return
- }
-
- toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
- if err != nil {
- fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
- return
- }
-
- logs := NewLogs()
-
- onErr := func(name enum.TrafficMonitorName, err error) {
- log := logs.Get(name)
- log.Add(fmt.Sprintf("%v ERROR %v\n", time.Now(), err))
- log.SetErrored(true)
- }
-
- onResumeSuccess := func(name enum.TrafficMonitorName) {
- log := logs.Get(name)
- log.Add(fmt.Sprintf("%v INFO State Valid\n", time.Now()))
- log.SetErrored(false)
- }
-
- onCheck := func(name enum.TrafficMonitorName, err error) {
- log := logs.Get(name)
- log.SetErrored(err != nil)
- }
-
- go tmcheck.AllMonitorsCRStatesOfflineValidator(toClient, *interval, *includeOffline, *grace, onErr, onResumeSuccess, onCheck)
-
- if err := serve(logs, *toURI); err != nil {
- fmt.Printf("Serve error: %v\n", err)
- }
-}
-
-func serve(logs Logs, toURI string) error {
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Content-Type", "text/html")
- fmt.Fprintf(w, `<!DOCTYPE html>
-<meta http-equiv="refresh" content="5">
-<meta charset="utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<title>Traffic Monitor Offline Validator</title>
-<style type="text/css">body{margin:40px auto;line-height:1.6;font-size:18px;color:#444;padding:0 8px 0 8px}h1,h2,h3{line-height:1.2}span{padding:0px 4px 0px 4px;}</style>`)
-
- fmt.Fprintf(w, `<p>%s`, toURI)
-
- fmt.Fprintf(w, `<table style="width:100%%">`)
-
- monitors := logs.GetMonitors()
- sort.Strings(monitors) // sort, so they're always in the same order in the webpage
- for _, monitor := range monitors {
- fmt.Fprintf(w, `</tr>`)
-
- log := logs.Get(enum.TrafficMonitorName(monitor))
-
- fmt.Fprintf(w, `<td><span>%s</span></td>`, monitor)
- errored, lastCheck := log.GetErrored()
- if errored {
- fmt.Fprintf(w, `<td><span style="color:red">Invalid</span></td>`)
- } else {
- fmt.Fprintf(w, `<td><span style="color:limegreen">Valid</span></td>`)
- }
- fmt.Fprintf(w, `<td><span>as of %v</span></td>`, lastCheck)
-
- fmt.Fprintf(w, `<td><span style="font-family:monospace">`)
- logCopy := log.Get()
- firstMsg := ""
- if len(logCopy) > 0 {
- firstMsg = logCopy[0]
- }
- fmt.Fprintf(w, "%s\n", firstMsg)
- fmt.Fprintf(w, `</span></td>`)
-
- fmt.Fprintf(w, `</tr>`)
- }
- fmt.Fprintf(w, `</table>`)
- })
- return http.ListenAndServe(":80", nil)
-}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/c9196a12/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
new file mode 100644
index 0000000..0b551c8
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// validate-offline is a utility HTTP service which polls the given Traffic Monitor and validates that no OFFLINE or ADMIN_DOWN caches in the Traffic Ops CRConfig are marked Available in Traffic Monitor's CRstates endpoint.
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+ "io"
+ "net/http"
+ "sort"
+ "sync"
+ "time"
+)
+
+const UserAgent = "tm-offline-validator/0.1"
+
+const LogLimit = 10
+
+type Log struct {
+ log *[]string
+ limit int
+ errored *bool
+ lastCheck *time.Time
+ m *sync.RWMutex
+}
+
+func (l *Log) Add(msg string) {
+ l.m.Lock()
+ defer l.m.Unlock()
+ *l.log = append([]string{msg}, *l.log...)
+ if len(*l.log) > l.limit {
+ *l.log = (*l.log)[:l.limit]
+ }
+}
+
+func (l *Log) Get() []string {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ return *l.log
+}
+
+func (l *Log) GetErrored() (bool, time.Time) {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ return *l.errored, *l.lastCheck
+}
+
+func (l *Log) SetErrored(e bool) {
+ l.m.Lock()
+ defer l.m.Unlock()
+ *l.errored = e
+ *l.lastCheck = time.Now()
+}
+
+func NewLog() Log {
+ log := make([]string, 0, LogLimit+1)
+ errored := false
+ limit := LogLimit
+ lastCheck := time.Time{}
+ return Log{log: &log, errored: &errored, m: &sync.RWMutex{}, limit: limit, lastCheck: &lastCheck}
+}
+
+type Logs struct {
+ logs map[enum.TrafficMonitorName]Log
+ m *sync.RWMutex
+}
+
+func NewLogs() Logs {
+ return Logs{logs: map[enum.TrafficMonitorName]Log{}, m: &sync.RWMutex{}}
+}
+
+func (l Logs) Get(name enum.TrafficMonitorName) Log {
+ l.m.Lock()
+ defer l.m.Unlock()
+ if _, ok := l.logs[name]; !ok {
+ l.logs[name] = NewLog()
+ }
+ return l.logs[name]
+}
+
+func (l Logs) GetMonitors() []string {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ monitors := []string{}
+ for name, _ := range l.logs {
+ monitors = append(monitors, string(name))
+ }
+ return monitors
+}
+
+func startValidator(validator tmcheck.AllValidatorFunc, toClient *to.Session, interval time.Duration, includeOffline bool, grace time.Duration) Logs {
+ logs := NewLogs()
+
+ onErr := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
+ log.Add(fmt.Sprintf("%v ERROR %v\n", time.Now(), err))
+ log.SetErrored(true)
+ }
+
+ onResumeSuccess := func(name enum.TrafficMonitorName) {
+ log := logs.Get(name)
+ log.Add(fmt.Sprintf("%v INFO State Valid\n", time.Now()))
+ log.SetErrored(false)
+ }
+
+ onCheck := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
+ log.SetErrored(err != nil)
+ }
+
+ go validator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck)
+ return logs
+}
+
+func main() {
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ interval := flag.Duration("interval", time.Second*time.Duration(5), "The interval to validate")
+ grace := flag.Duration("grace", time.Second*time.Duration(30), "The grace period before invalid states are reported")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief {
+ fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s -includeOffline true\n")
+ return
+ }
+
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ crStatesOfflineLogs := startValidator(tmcheck.AllMonitorsCRStatesOfflineValidator, toClient, *interval, *includeOffline, *grace)
+ peerPollerLogs := startValidator(tmcheck.PeerPollersAllValidator, toClient, *interval, *includeOffline, *grace)
+
+ if err := serve(*toURI, crStatesOfflineLogs, peerPollerLogs); err != nil {
+ fmt.Printf("Serve error: %v\n", err)
+ }
+}
+
+func printLogs(logs Logs, w io.Writer) {
+ fmt.Fprintf(w, `<table style="width:100%%">`)
+
+ monitors := logs.GetMonitors()
+ sort.Strings(monitors) // sort, so they're always in the same order in the webpage
+ for _, monitor := range monitors {
+ fmt.Fprintf(w, `</tr>`)
+
+ log := logs.Get(enum.TrafficMonitorName(monitor))
+
+ fmt.Fprintf(w, `<td><span>%s</span></td>`, monitor)
+ errored, lastCheck := log.GetErrored()
+ if errored {
+ fmt.Fprintf(w, `<td><span style="color:red">Invalid</span></td>`)
+ } else {
+ fmt.Fprintf(w, `<td><span style="color:limegreen">Valid</span></td>`)
+ }
+ fmt.Fprintf(w, `<td><span>as of %v</span></td>`, lastCheck)
+
+ fmt.Fprintf(w, `<td><span style="font-family:monospace">`)
+ logCopy := log.Get()
+ firstMsg := ""
+ if len(logCopy) > 0 {
+ firstMsg = logCopy[0]
+ }
+ fmt.Fprintf(w, "%s\n", firstMsg)
+ fmt.Fprintf(w, `</span></td>`)
+
+ fmt.Fprintf(w, `</tr>`)
+ }
+ fmt.Fprintf(w, `</table>`)
+}
+
+func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs) error {
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Content-Type", "text/html")
+ fmt.Fprintf(w, `<!DOCTYPE html>
+<meta http-equiv="refresh" content="5">
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Traffic Monitor Offline Validator</title>
+<style type="text/css">body{margin:40px auto;line-height:1.6;font-size:18px;color:#444;padding:0 8px 0 8px}h1,h2,h3{line-height:1.2}span{padding:0px 4px 0px 4px;}</style>`)
+
+ fmt.Fprintf(w, `<h1>Traffic Monitor Validator</h1>`)
+
+ fmt.Fprintf(w, `<p>%s`, toURI)
+
+ fmt.Fprintf(w, `<h2>CRStates Offline</h2>`)
+ printLogs(crStatesOfflineLogs, w)
+
+ fmt.Fprintf(w, `<h2>Peer Poller</h2>`)
+ printLogs(peerPollerLogs, w)
+
+ })
+ return http.ListenAndServe(":80", nil)
+}
[05/13] incubator-trafficcontrol git commit: Add TM2 validator
checking all TMs in TO
Posted by ne...@apache.org.
Add TM2 validator checking all TMs in TO
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/e252d4c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/e252d4c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/e252d4c9
Branch: refs/heads/master
Commit: e252d4c9cb502c7cdd90688f9b6b69f5129cd997
Parents: 83b58d9
Author: Robert Butts <ro...@gmail.com>
Authored: Fri Mar 3 08:05:11 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tmcheck/tmcheck.go | 6 +-
.../traffic_monitor/tools/validate-offline.go | 89 +++++++++++++++-----
2 files changed, 69 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/e252d4c9/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index 1178721..0fdab61 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -209,10 +209,8 @@ func ValidateAllMonitorsOfflineStates(toClient *to.Session, includeOffline bool)
continue
}
- fqdn := fmt.Sprintf("%s.%s", server.HostName, server.DomainName)
- if err := ValidateOfflineStatesWithCRConfig(fqdn, crConfig.CRConfig, toClient); err != nil {
- errs[enum.TrafficMonitorName(server.HostName)] = err
- }
+ uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
+ errs[enum.TrafficMonitorName(server.HostName)] = ValidateOfflineStatesWithCRConfig(uri, crConfig.CRConfig, toClient)
}
return errs, nil
}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/e252d4c9/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
index 07eee78..d031007 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
@@ -24,6 +24,7 @@ package main
import (
"flag"
"fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
"net/http"
@@ -33,7 +34,7 @@ import (
const UserAgent = "tm-offline-validator/0.1"
-const LogLimit = 100000
+const LogLimit = 10000
type Log struct {
log *[]string
@@ -76,18 +77,46 @@ func NewLog() Log {
return Log{log: &log, errored: &errored, m: &sync.RWMutex{}, limit: limit}
}
+type Logs struct {
+ logs map[enum.TrafficMonitorName]Log
+ m *sync.RWMutex
+}
+
+func NewLogs() Logs {
+ return Logs{logs: map[enum.TrafficMonitorName]Log{}, m: &sync.RWMutex{}}
+}
+
+func (l Logs) Get(name enum.TrafficMonitorName) Log {
+ l.m.Lock()
+ defer l.m.Unlock()
+ if _, ok := l.logs[name]; !ok {
+ l.logs[name] = NewLog()
+ }
+ return l.logs[name]
+}
+
+func (l Logs) GetMonitors() []enum.TrafficMonitorName {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ monitors := []enum.TrafficMonitorName{}
+ for name, _ := range l.logs {
+ monitors = append(monitors, name)
+ }
+ return monitors
+}
+
func main() {
toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
toUser := flag.String("touser", "", "The Traffic Ops user")
toPass := flag.String("topass", "", "The Traffic Ops password")
- tmURI := flag.String("tm", "", "The Traffic Monitor URI whose CRStates to validate")
interval := flag.Duration("interval", time.Second*time.Duration(5), "The interval to validate")
grace := flag.Duration("grace", time.Second*time.Duration(30), "The grace period before invalid states are reported")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
help := flag.Bool("help", false, "Usage info")
helpBrief := flag.Bool("h", false, "Usage info")
flag.Parse()
if *help || *helpBrief {
- fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s\n")
+ fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s -includeOffline true\n")
return
}
@@ -97,19 +126,22 @@ func main() {
return
}
- log := NewLog()
+ logs := NewLogs()
- onErr := func(err error) {
+ onErr := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
log.Add(fmt.Sprintf("%v ERROR %v\n", time.Now(), err))
log.SetErrored(true)
}
- onResumeSuccess := func() {
+ onResumeSuccess := func(name enum.TrafficMonitorName) {
+ log := logs.Get(name)
log.Add(fmt.Sprintf("%v INFO State Valid\n", time.Now()))
log.SetErrored(false)
}
- onCheck := func(err error) {
+ onCheck := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
if err != nil {
log.Add(fmt.Sprintf("%v DEBUG invalid: %v\n", time.Now(), err))
} else {
@@ -117,14 +149,14 @@ func main() {
}
}
- go tmcheck.CRStatesOfflineValidator(*tmURI, toClient, *interval, *grace, onErr, onResumeSuccess, onCheck)
+ go tmcheck.AllMonitorsCRStatesOfflineValidator(toClient, *interval, *includeOffline, *grace, onErr, onResumeSuccess, onCheck)
- if err := serve(log, *toURI, *tmURI); err != nil {
+ if err := serve(logs, *toURI); err != nil {
fmt.Printf("Serve error: %v\n", err)
}
}
-func serve(log Log, toURI string, tmURI string) error {
+func serve(logs Logs, toURI string) error {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "text/html")
@@ -133,23 +165,36 @@ func serve(log Log, toURI string, tmURI string) error {
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Traffic Monitor Offline Validator</title>
-<style type="text/css">body{margin:40px auto;max-width:650px;line-height:1.6;font-size:18px;color:#444;padding:0 10px}h1,h2,h3{line-height:1.2}</style>`)
+<style type="text/css">body{margin:40px auto;line-height:1.6;font-size:18px;color:#444;padding:0 2px}h1,h2,h3{line-height:1.2}</style>`)
fmt.Fprintf(w, `<p>%s`, toURI)
- fmt.Fprintf(w, `<p>%s`, tmURI)
- if log.GetErrored() {
- fmt.Fprintf(w, `<h1 style="color:red">Invalid</h1>`)
- } else {
- fmt.Fprintf(w, `<h1 style="color:limegreen">Valid</h1>`)
- }
- fmt.Fprintf(w, `<pre>`)
- logCopy := log.Get()
- for _, msg := range logCopy {
- fmt.Fprintf(w, "%s\n", msg)
+ fmt.Fprintf(w, `<table style="width:100%%"><tr>`)
+
+ monitors := logs.GetMonitors()
+ for _, monitor := range monitors {
+ fmt.Fprintf(w, `<td>`)
+
+ log := logs.Get(monitor)
+
+ fmt.Fprintf(w, `<p>%s`, monitor)
+ if log.GetErrored() {
+ fmt.Fprintf(w, `<h1 style="color:red">Invalid</h1>`)
+ } else {
+ fmt.Fprintf(w, `<h1 style="color:limegreen">Valid</h1>`)
+ }
+
+ fmt.Fprintf(w, `<pre>`)
+ logCopy := log.Get()
+ for _, msg := range logCopy {
+ fmt.Fprintf(w, "%s\n", msg)
+ }
+ fmt.Fprintf(w, `</pre>`)
+
+ fmt.Fprintf(w, `</td>`)
}
- fmt.Fprintf(w, `</pre>`)
+ fmt.Fprintf(w, `</tr></table>`)
})
return http.ListenAndServe(":80", nil)
}
[06/13] incubator-trafficcontrol git commit: Add TM2 nagios validator,
fix html formatting
Posted by ne...@apache.org.
Add TM2 nagios validator, fix html formatting
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/667ed342
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/667ed342
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/667ed342
Branch: refs/heads/master
Commit: 667ed342cd41d73923fffdf144134cedbac32bc4
Parents: e252d4c
Author: Robert Butts <ro...@gmail.com>
Authored: Fri Mar 3 11:47:24 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
traffic_monitor_golang/common/nagios/nagios.go | 23 +++
.../traffic_monitor/tmcheck/tmcheck.go | 2 +-
.../tools/nagios-validate-offline.go | 50 +++++
.../tools/service-validate-offline.go | 204 +++++++++++++++++++
.../traffic_monitor/tools/validate-offline.go | 200 ------------------
5 files changed, 278 insertions(+), 201 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/667ed342/traffic_monitor_golang/common/nagios/nagios.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/common/nagios/nagios.go b/traffic_monitor_golang/common/nagios/nagios.go
new file mode 100644
index 0000000..53af782
--- /dev/null
+++ b/traffic_monitor_golang/common/nagios/nagios.go
@@ -0,0 +1,23 @@
+package nagios
+
+import (
+ "fmt"
+ "os"
+ "strings"
+)
+
+type Status int
+
+const (
+ Ok Status = 0
+ Warning Status = 1
+ Critical Status = 2
+)
+
+func Exit(status Status, msg string) {
+ if msg != "" {
+ msg = strings.TrimRight(msg, "\n")
+ fmt.Printf("%s\n", msg)
+ }
+ os.Exit(int(status))
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/667ed342/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index 0fdab61..fa2c533 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -228,7 +228,7 @@ func AllMonitorsCRStatesOfflineValidator(
invalid := map[enum.TrafficMonitorName]bool{}
invalidStart := map[enum.TrafficMonitorName]time.Time{}
for {
- tmErrs, err := ValidateAllMonitorsOfflineStates(toClient, includeOffline) // []MonitorError {
+ tmErrs, err := ValidateAllMonitorsOfflineStates(toClient, includeOffline)
if err != nil {
onErr("", fmt.Errorf("Error validating monitors: %v", err))
time.Sleep(interval)
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/667ed342/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
new file mode 100644
index 0000000..6a1ab96
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-offline.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/nagios"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+const UserAgent = "tm-offline-validator/0.1"
+
+func main() {
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief {
+ fmt.Printf("Usage: ./nagios-validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
+ return
+ }
+
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ monitorErrs, err := tmcheck.ValidateAllMonitorsOfflineStates(toClient, *includeOffline)
+
+ if err != nil {
+ nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor offline statuses: %v", err))
+ }
+
+ errStr := ""
+ for monitor, err := range monitorErrs {
+ if err != nil {
+ errStr += fmt.Sprintf("error validating offline status for monitor %v : %v\n", monitor, err.Error())
+ }
+ }
+
+ if errStr != "" {
+ nagios.Exit(nagios.Critical, errStr)
+ }
+
+ nagios.Exit(nagios.Ok, "")
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/667ed342/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
new file mode 100644
index 0000000..41e0eb4
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/service-validate-offline.go
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// validate-offline is a utility HTTP service which polls the given Traffic Monitor and validates that no OFFLINE or ADMIN_DOWN caches in the Traffic Ops CRConfig are marked Available in Traffic Monitor's CRstates endpoint.
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+ "net/http"
+ "sort"
+ "sync"
+ "time"
+)
+
+const UserAgent = "tm-offline-validator/0.1"
+
+const LogLimit = 10
+
+type Log struct {
+ log *[]string
+ limit int
+ errored *bool
+ lastCheck *time.Time
+ m *sync.RWMutex
+}
+
+func (l *Log) Add(msg string) {
+ l.m.Lock()
+ defer l.m.Unlock()
+ *l.log = append([]string{msg}, *l.log...)
+ if len(*l.log) > l.limit {
+ *l.log = (*l.log)[:l.limit]
+ }
+}
+
+func (l *Log) Get() []string {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ return *l.log
+}
+
+func (l *Log) GetErrored() (bool, time.Time) {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ return *l.errored, *l.lastCheck
+}
+
+func (l *Log) SetErrored(e bool) {
+ l.m.Lock()
+ defer l.m.Unlock()
+ *l.errored = e
+ *l.lastCheck = time.Now()
+}
+
+func NewLog() Log {
+ log := make([]string, 0, LogLimit+1)
+ errored := false
+ limit := LogLimit
+ lastCheck := time.Time{}
+ return Log{log: &log, errored: &errored, m: &sync.RWMutex{}, limit: limit, lastCheck: &lastCheck}
+}
+
+type Logs struct {
+ logs map[enum.TrafficMonitorName]Log
+ m *sync.RWMutex
+}
+
+func NewLogs() Logs {
+ return Logs{logs: map[enum.TrafficMonitorName]Log{}, m: &sync.RWMutex{}}
+}
+
+func (l Logs) Get(name enum.TrafficMonitorName) Log {
+ l.m.Lock()
+ defer l.m.Unlock()
+ if _, ok := l.logs[name]; !ok {
+ l.logs[name] = NewLog()
+ }
+ return l.logs[name]
+}
+
+func (l Logs) GetMonitors() []string {
+ l.m.RLock()
+ defer l.m.RUnlock()
+ monitors := []string{}
+ for name, _ := range l.logs {
+ monitors = append(monitors, string(name))
+ }
+ return monitors
+}
+
+func main() {
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ interval := flag.Duration("interval", time.Second*time.Duration(5), "The interval to validate")
+ grace := flag.Duration("grace", time.Second*time.Duration(30), "The grace period before invalid states are reported")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief {
+ fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s -includeOffline true\n")
+ return
+ }
+
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ logs := NewLogs()
+
+ onErr := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
+ log.Add(fmt.Sprintf("%v ERROR %v\n", time.Now(), err))
+ log.SetErrored(true)
+ }
+
+ onResumeSuccess := func(name enum.TrafficMonitorName) {
+ log := logs.Get(name)
+ log.Add(fmt.Sprintf("%v INFO State Valid\n", time.Now()))
+ log.SetErrored(false)
+ }
+
+ onCheck := func(name enum.TrafficMonitorName, err error) {
+ log := logs.Get(name)
+ log.SetErrored(err != nil)
+ }
+
+ go tmcheck.AllMonitorsCRStatesOfflineValidator(toClient, *interval, *includeOffline, *grace, onErr, onResumeSuccess, onCheck)
+
+ if err := serve(logs, *toURI); err != nil {
+ fmt.Printf("Serve error: %v\n", err)
+ }
+}
+
+func serve(logs Logs, toURI string) error {
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Content-Type", "text/html")
+ fmt.Fprintf(w, `<!DOCTYPE html>
+<meta http-equiv="refresh" content="5">
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Traffic Monitor Offline Validator</title>
+<style type="text/css">body{margin:40px auto;line-height:1.6;font-size:18px;color:#444;padding:0 8px 0 8px}h1,h2,h3{line-height:1.2}span{padding:0px 4px 0px 4px;}</style>`)
+
+ fmt.Fprintf(w, `<p>%s`, toURI)
+
+ fmt.Fprintf(w, `<table style="width:100%%">`)
+
+ monitors := logs.GetMonitors()
+ sort.Strings(monitors) // sort, so they're always in the same order in the webpage
+ for _, monitor := range monitors {
+ fmt.Fprintf(w, `</tr>`)
+
+ log := logs.Get(enum.TrafficMonitorName(monitor))
+
+ fmt.Fprintf(w, `<td><span>%s</span></td>`, monitor)
+ errored, lastCheck := log.GetErrored()
+ if errored {
+ fmt.Fprintf(w, `<td><span style="color:red">Invalid</span></td>`)
+ } else {
+ fmt.Fprintf(w, `<td><span style="color:limegreen">Valid</span></td>`)
+ }
+ fmt.Fprintf(w, `<td><span>as of %v</span></td>`, lastCheck)
+
+ fmt.Fprintf(w, `<td><span style="font-family:monospace">`)
+ logCopy := log.Get()
+ firstMsg := ""
+ if len(logCopy) > 0 {
+ firstMsg = logCopy[0]
+ }
+ fmt.Fprintf(w, "%s\n", firstMsg)
+ fmt.Fprintf(w, `</span></td>`)
+
+ fmt.Fprintf(w, `</tr>`)
+ }
+ fmt.Fprintf(w, `</table>`)
+ })
+ return http.ListenAndServe(":80", nil)
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/667ed342/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go b/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
deleted file mode 100644
index d031007..0000000
--- a/traffic_monitor_golang/traffic_monitor/tools/validate-offline.go
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// validate-offline is a utility HTTP service which polls the given Traffic Monitor and validates that no OFFLINE or ADMIN_DOWN caches in the Traffic Ops CRConfig are marked Available in Traffic Monitor's CRstates endpoint.
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
- to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
- "net/http"
- "sync"
- "time"
-)
-
-const UserAgent = "tm-offline-validator/0.1"
-
-const LogLimit = 10000
-
-type Log struct {
- log *[]string
- limit int
- errored *bool
- m *sync.RWMutex
-}
-
-func (l *Log) Add(msg string) {
- l.m.Lock()
- defer l.m.Unlock()
- *l.log = append([]string{msg}, *l.log...)
- if len(*l.log) > l.limit {
- *l.log = (*l.log)[:l.limit]
- }
-}
-
-func (l *Log) Get() []string {
- l.m.RLock()
- defer l.m.RUnlock()
- return *l.log
-}
-
-func (l *Log) GetErrored() bool {
- l.m.RLock()
- defer l.m.RUnlock()
- return *l.errored
-}
-
-func (l *Log) SetErrored(e bool) {
- l.m.Lock()
- defer l.m.Unlock()
- *l.errored = e
-}
-
-func NewLog() Log {
- log := make([]string, 0, LogLimit+1)
- errored := false
- limit := LogLimit
- return Log{log: &log, errored: &errored, m: &sync.RWMutex{}, limit: limit}
-}
-
-type Logs struct {
- logs map[enum.TrafficMonitorName]Log
- m *sync.RWMutex
-}
-
-func NewLogs() Logs {
- return Logs{logs: map[enum.TrafficMonitorName]Log{}, m: &sync.RWMutex{}}
-}
-
-func (l Logs) Get(name enum.TrafficMonitorName) Log {
- l.m.Lock()
- defer l.m.Unlock()
- if _, ok := l.logs[name]; !ok {
- l.logs[name] = NewLog()
- }
- return l.logs[name]
-}
-
-func (l Logs) GetMonitors() []enum.TrafficMonitorName {
- l.m.RLock()
- defer l.m.RUnlock()
- monitors := []enum.TrafficMonitorName{}
- for name, _ := range l.logs {
- monitors = append(monitors, name)
- }
- return monitors
-}
-
-func main() {
- toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
- toUser := flag.String("touser", "", "The Traffic Ops user")
- toPass := flag.String("topass", "", "The Traffic Ops password")
- interval := flag.Duration("interval", time.Second*time.Duration(5), "The interval to validate")
- grace := flag.Duration("grace", time.Second*time.Duration(30), "The grace period before invalid states are reported")
- includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
- help := flag.Bool("help", false, "Usage info")
- helpBrief := flag.Bool("h", false, "Usage info")
- flag.Parse()
- if *help || *helpBrief {
- fmt.Printf("Usage: go run validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -tm http://traffic-monitor.example.net -interval 5s -grace 30s -includeOffline true\n")
- return
- }
-
- toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
- if err != nil {
- fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
- return
- }
-
- logs := NewLogs()
-
- onErr := func(name enum.TrafficMonitorName, err error) {
- log := logs.Get(name)
- log.Add(fmt.Sprintf("%v ERROR %v\n", time.Now(), err))
- log.SetErrored(true)
- }
-
- onResumeSuccess := func(name enum.TrafficMonitorName) {
- log := logs.Get(name)
- log.Add(fmt.Sprintf("%v INFO State Valid\n", time.Now()))
- log.SetErrored(false)
- }
-
- onCheck := func(name enum.TrafficMonitorName, err error) {
- log := logs.Get(name)
- if err != nil {
- log.Add(fmt.Sprintf("%v DEBUG invalid: %v\n", time.Now(), err))
- } else {
- log.Add(fmt.Sprintf("%v DEBUG valid\n", time.Now()))
- }
- }
-
- go tmcheck.AllMonitorsCRStatesOfflineValidator(toClient, *interval, *includeOffline, *grace, onErr, onResumeSuccess, onCheck)
-
- if err := serve(logs, *toURI); err != nil {
- fmt.Printf("Serve error: %v\n", err)
- }
-}
-
-func serve(logs Logs, toURI string) error {
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Content-Type", "text/html")
- fmt.Fprintf(w, `<!DOCTYPE html>
-<meta http-equiv="refresh" content="5">
-<meta charset="utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<title>Traffic Monitor Offline Validator</title>
-<style type="text/css">body{margin:40px auto;line-height:1.6;font-size:18px;color:#444;padding:0 2px}h1,h2,h3{line-height:1.2}</style>`)
-
- fmt.Fprintf(w, `<p>%s`, toURI)
-
- fmt.Fprintf(w, `<table style="width:100%%"><tr>`)
-
- monitors := logs.GetMonitors()
- for _, monitor := range monitors {
- fmt.Fprintf(w, `<td>`)
-
- log := logs.Get(monitor)
-
- fmt.Fprintf(w, `<p>%s`, monitor)
- if log.GetErrored() {
- fmt.Fprintf(w, `<h1 style="color:red">Invalid</h1>`)
- } else {
- fmt.Fprintf(w, `<h1 style="color:limegreen">Valid</h1>`)
- }
-
- fmt.Fprintf(w, `<pre>`)
- logCopy := log.Get()
- for _, msg := range logCopy {
- fmt.Fprintf(w, "%s\n", msg)
- }
- fmt.Fprintf(w, `</pre>`)
-
- fmt.Fprintf(w, `</td>`)
- }
-
- fmt.Fprintf(w, `</tr></table>`)
- })
- return http.ListenAndServe(":80", nil)
-}
[03/13] incubator-trafficcontrol git commit: Fix TM2 validator GUI to
hide errs when valid
Posted by ne...@apache.org.
Fix TM2 validator GUI to hide errs when valid
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/d87c8b3d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/d87c8b3d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/d87c8b3d
Branch: refs/heads/master
Commit: d87c8b3d34fad73ffe7f665805b548e1b9267531
Parents: c9196a1
Author: Robert Butts <ro...@gmail.com>
Authored: Mon Mar 6 08:47:34 2017 -0700
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tools/validator-service.go | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d87c8b3d/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
index 0b551c8..22295dd 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
@@ -182,14 +182,16 @@ func printLogs(logs Logs, w io.Writer) {
}
fmt.Fprintf(w, `<td><span>as of %v</span></td>`, lastCheck)
- fmt.Fprintf(w, `<td><span style="font-family:monospace">`)
- logCopy := log.Get()
- firstMsg := ""
- if len(logCopy) > 0 {
- firstMsg = logCopy[0]
+ if errored {
+ fmt.Fprintf(w, `<td><span style="font-family:monospace">`)
+ logCopy := log.Get()
+ firstMsg := ""
+ if len(logCopy) > 0 {
+ firstMsg = logCopy[0]
+ }
+ fmt.Fprintf(w, "%s\n", firstMsg)
+ fmt.Fprintf(w, `</span></td>`)
}
- fmt.Fprintf(w, "%s\n", firstMsg)
- fmt.Fprintf(w, `</span></td>`)
fmt.Fprintf(w, `</tr>`)
}
[02/13] incubator-trafficcontrol git commit: Add TM2 validator for
DsStats delivery services
Posted by ne...@apache.org.
Add TM2 validator for DsStats delivery services
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/095def7c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/095def7c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/095def7c
Branch: refs/heads/master
Commit: 095def7c03974f74b08e180476528ebbb6b32a90
Parents: 0dd73c1
Author: Robert Butts <ro...@gmail.com>
Authored: Thu Mar 30 10:45:50 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:31 2017 -0600
----------------------------------------------------------------------
.../traffic_monitor/tmcheck/dsstats.go | 137 +++++++++++++++++++
.../traffic_monitor/tmcheck/tmcheck.go | 20 +++
.../tools/nagios-validate-deliveryservices.go | 69 ++++++++++
.../traffic_monitor/tools/validator-service.go | 11 +-
4 files changed, 235 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/095def7c/traffic_monitor_golang/traffic_monitor/tmcheck/dsstats.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/dsstats.go b/traffic_monitor_golang/traffic_monitor/tmcheck/dsstats.go
new file mode 100644
index 0000000..a35a3a7
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/dsstats.go
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package tmcheck
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/crconfig"
+ dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/deliveryservicedata"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+// ValidateDSStates validates that all Delivery Services in the CRConfig exist in given Traffic Monitor's DSStats.
+// Existence in DSStats is useful to verify, because "Available: false" in CRStates
+func ValidateDSStats(tmURI string, toClient *to.Session) error {
+ cdn, err := GetCDN(tmURI)
+ if err != nil {
+ return fmt.Errorf("getting CDN from Traffic Monitor: %v", err)
+ }
+ return ValidateDSStatsWithCDN(tmURI, cdn, toClient)
+}
+
+// ValidateOfflineStatesWithCDN validates per ValidateOfflineStates, but saves an additional query if the Traffic Monitor's CDN is known.
+func ValidateDSStatsWithCDN(tmURI string, tmCDN string, toClient *to.Session) error {
+ crConfigBytes, err := toClient.CRConfigRaw(tmCDN)
+ if err != nil {
+ return fmt.Errorf("getting CRConfig: %v", err)
+ }
+
+ crConfig := crconfig.CRConfig{}
+ if err := json.Unmarshal(crConfigBytes, &crConfig); err != nil {
+ return fmt.Errorf("unmarshalling CRConfig JSON: %v", err)
+ }
+
+ return ValidateDSStatsWithCRConfig(tmURI, &crConfig, toClient)
+}
+
+// ValidateOfflineStatesWithCRConfig validates per ValidateOfflineStates, but saves querying the CRconfig if it's already fetched.
+func ValidateDSStatsWithCRConfig(tmURI string, crConfig *crconfig.CRConfig, toClient *to.Session) error {
+ dsStats, err := GetDSStats(tmURI + TrafficMonitorDSStatsPath)
+ if err != nil {
+ return fmt.Errorf("getting DSStats: %v", err)
+ }
+
+ return ValidateDSStatsData(dsStats, crConfig)
+}
+
+func hasCaches(dsName string, crconfig *crconfig.CRConfig) bool {
+ for _, server := range crconfig.ContentServers {
+ if _, ok := server.DeliveryServices[dsName]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+// ValidateDSStatsData validates that all delivery services in the given CRConfig with caches assigned exist in the given DSStats.
+func ValidateDSStatsData(dsStats *dsdata.StatsOld, crconfig *crconfig.CRConfig) error {
+ for dsName, _ := range crconfig.DeliveryServices {
+ if !hasCaches(dsName, crconfig) {
+ continue
+ }
+ if _, ok := dsStats.DeliveryService[enum.DeliveryServiceName(dsName)]; !ok {
+ return fmt.Errorf("Delivery Service %v in CRConfig but not DSStats", dsName)
+ }
+ }
+ return nil
+}
+
+// DSStatsValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll.
+func DSStatsValidator(
+ tmURI string,
+ toClient *to.Session,
+ interval time.Duration,
+ grace time.Duration,
+ onErr func(error),
+ onResumeSuccess func(),
+ onCheck func(error),
+) {
+ Validator(tmURI, toClient, interval, grace, onErr, onResumeSuccess, onCheck, ValidateDSStats)
+}
+
+// AllMonitorsDSStatsValidator is designed to be run as a goroutine, and does not return. It continously validates every `interval`, and calls `onErr` on failure, `onResumeSuccess` when a failure ceases, and `onCheck` on every poll. Note the error passed to `onErr` may be a general validation error not associated with any monitor, in which case the passed `enum.TrafficMonitorName` will be empty.
+func AllMonitorsDSStatsValidator(
+ toClient *to.Session,
+ interval time.Duration,
+ includeOffline bool,
+ grace time.Duration,
+ onErr func(enum.TrafficMonitorName, error),
+ onResumeSuccess func(enum.TrafficMonitorName),
+ onCheck func(enum.TrafficMonitorName, error),
+) {
+ AllValidator(toClient, interval, includeOffline, grace, onErr, onResumeSuccess, onCheck, ValidateAllMonitorsDSStats)
+}
+
+// ValidateAllMonitorDSStats validates, for all monitors in the given Traffic Ops, DSStats contains all Delivery Services in the CRConfig.
+func ValidateAllMonitorsDSStats(toClient *to.Session, includeOffline bool) (map[enum.TrafficMonitorName]error, error) {
+ servers, err := GetMonitors(toClient, includeOffline)
+ if err != nil {
+ return nil, err
+ }
+
+ crConfigs := GetCRConfigs(GetCDNs(servers), toClient)
+
+ errs := map[enum.TrafficMonitorName]error{}
+ for _, server := range servers {
+ crConfig := crConfigs[enum.CDNName(server.CDNName)]
+ if err := crConfig.Err; err != nil {
+ errs[enum.TrafficMonitorName(server.HostName)] = fmt.Errorf("getting CRConfig: %v", err)
+ continue
+ }
+
+ uri := fmt.Sprintf("http://%s.%s", server.HostName, server.DomainName)
+ errs[enum.TrafficMonitorName(server.HostName)] = ValidateDSStatsWithCRConfig(uri, crConfig.CRConfig, toClient)
+ }
+ return errs, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/095def7c/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
index 9c6016b..1ef2532 100644
--- a/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
+++ b/traffic_monitor_golang/traffic_monitor/tmcheck/tmcheck.go
@@ -29,6 +29,7 @@ import (
"time"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/crconfig"
+ dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/deliveryservicedata"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/enum"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/peer"
to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
@@ -37,6 +38,7 @@ import (
const RequestTimeout = time.Second * time.Duration(30)
const TrafficMonitorCRStatesPath = "/publish/CrStates"
+const TrafficMonitorDSStatsPath = "/publish/DsStats"
const TrafficMonitorConfigDocPath = "/publish/ConfigDoc"
func getClient() *http.Client {
@@ -87,6 +89,24 @@ func GetCRStates(uri string) (*peer.Crstates, error) {
return &states, nil
}
+// GetCRStates gets the CRStates from the given Traffic Monitor.
+func GetDSStats(uri string) (*dsdata.StatsOld, error) {
+ resp, err := getClient().Get(uri)
+ if err != nil {
+ return nil, fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+ respBytes, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, fmt.Errorf("reading reply from %v: %v\n", uri, err)
+ }
+
+ dsStats := dsdata.StatsOld{}
+ if err := json.Unmarshal(respBytes, &dsStats); err != nil {
+ return nil, fmt.Errorf("unmarshalling: %v", err)
+ }
+ return &dsStats, nil
+}
+
type ValidatorFunc func(
tmURI string,
toClient *to.Session,
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/095def7c/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-deliveryservices.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-deliveryservices.go b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-deliveryservices.go
new file mode 100644
index 0000000..3afdb72
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/tools/nagios-validate-deliveryservices.go
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/nagios"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/tmcheck"
+ to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+const UserAgent = "tm-offline-validator/0.1"
+
+func main() {
+ toURI := flag.String("to", "", "The Traffic Ops URI, whose CRConfig to validate")
+ toUser := flag.String("touser", "", "The Traffic Ops user")
+ toPass := flag.String("topass", "", "The Traffic Ops password")
+ includeOffline := flag.Bool("includeOffline", false, "Whether to include Offline Monitors")
+ help := flag.Bool("help", false, "Usage info")
+ helpBrief := flag.Bool("h", false, "Usage info")
+ flag.Parse()
+ if *help || *helpBrief || *toURI == "" {
+ fmt.Printf("Usage: ./nagios-validate-offline -to https://traffic-ops.example.net -touser bill -topass thelizard -includeOffline true\n")
+ return
+ }
+
+ toClient, err := to.LoginWithAgent(*toURI, *toUser, *toPass, true, UserAgent, false, tmcheck.RequestTimeout)
+ if err != nil {
+ fmt.Printf("Error logging in to Traffic Ops: %v\n", err)
+ return
+ }
+
+ monitorErrs, err := tmcheck.ValidateAllMonitorsDSStats(toClient, *includeOffline)
+
+ if err != nil {
+ nagios.Exit(nagios.Critical, fmt.Sprintf("Error validating monitor delivery services: %v", err))
+ }
+
+ errStr := ""
+ for monitor, err := range monitorErrs {
+ if err != nil {
+ errStr += fmt.Sprintf("error validating delivery services for monitor %v : %v\n", monitor, err.Error())
+ }
+ }
+
+ if errStr != "" {
+ nagios.Exit(nagios.Critical, errStr)
+ }
+
+ nagios.Exit(nagios.Ok, "")
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/095def7c/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
index 22295dd..5dc1e04 100644
--- a/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
+++ b/traffic_monitor_golang/traffic_monitor/tools/validator-service.go
@@ -157,8 +157,9 @@ func main() {
crStatesOfflineLogs := startValidator(tmcheck.AllMonitorsCRStatesOfflineValidator, toClient, *interval, *includeOffline, *grace)
peerPollerLogs := startValidator(tmcheck.PeerPollersAllValidator, toClient, *interval, *includeOffline, *grace)
+ dsStatsLogs := startValidator(tmcheck.AllMonitorsDSStatsValidator, toClient, *interval, *includeOffline, *grace)
- if err := serve(*toURI, crStatesOfflineLogs, peerPollerLogs); err != nil {
+ if err := serve(*toURI, crStatesOfflineLogs, peerPollerLogs, dsStatsLogs); err != nil {
fmt.Printf("Serve error: %v\n", err)
}
}
@@ -198,7 +199,7 @@ func printLogs(logs Logs, w io.Writer) {
fmt.Fprintf(w, `</table>`)
}
-func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs) error {
+func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs, dsStatsLogs Logs) error {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "text/html")
@@ -212,13 +213,19 @@ func serve(toURI string, crStatesOfflineLogs Logs, peerPollerLogs Logs) error {
fmt.Fprintf(w, `<h1>Traffic Monitor Validator</h1>`)
fmt.Fprintf(w, `<p>%s`, toURI)
+ fmt.Fprintf(w, `<p>%s`, time.Now())
fmt.Fprintf(w, `<h2>CRStates Offline</h2>`)
+ fmt.Fprintf(w, `<h3>validates all OFFLINE and ADMIN_DOWN caches in the CRConfig are Unavailable</h3>`)
printLogs(crStatesOfflineLogs, w)
fmt.Fprintf(w, `<h2>Peer Poller</h2>`)
+ fmt.Fprintf(w, `<h3>validates all peers in the CRConfig have been polled within the last %v</h3>`, tmcheck.PeerPollMax)
printLogs(peerPollerLogs, w)
+ fmt.Fprintf(w, `<h2>Delivery Services</h2>`)
+ fmt.Fprintf(w, `<h3>validates all Delivery Services in the CRConfig exist in DsStats</h3>`)
+ printLogs(dsStatsLogs, w)
})
return http.ListenAndServe(":80", nil)
}
[13/13] incubator-trafficcontrol git commit: This closes #330
Posted by ne...@apache.org.
This closes #330
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/43bb5e0b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/43bb5e0b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/43bb5e0b
Branch: refs/heads/master
Commit: 43bb5e0b6b4c1dcfaa7319c31fa511289443eb65
Parents: 0f56455
Author: Dave Neuman <ne...@apache.org>
Authored: Wed Apr 12 15:43:35 2017 -0600
Committer: Dave Neuman <ne...@apache.org>
Committed: Wed Apr 12 15:43:35 2017 -0600
----------------------------------------------------------------------
----------------------------------------------------------------------