diff --git a/traffic_monitor/towrap/towrap.go b/traffic_monitor/towrap/towrap.go index d81ba695a7..8b3b82f241 100644 --- a/traffic_monitor/towrap/towrap.go +++ b/traffic_monitor/towrap/towrap.go @@ -244,6 +244,43 @@ func (s *TrafficOpsSessionThreadsafe) CRConfigValid(crc *tc.CRConfig, cdn string return nil } +func MonitorConfigValid(cfg *tc.TrafficMonitorConfigMap) error { + if cfg == nil { + return errors.New("MonitorConfig is nil") + } + if len(cfg.TrafficServer) == 0 { + return errors.New("MonitorConfig.TrafficServer empty (is the monitoring.json an empty object?)") + } + if len(cfg.CacheGroup) == 0 { + return errors.New("MonitorConfig.CacheGroup empty") + } + if len(cfg.TrafficMonitor) == 0 { + return errors.New("MonitorConfig.TrafficMonitor empty") + } + // TODO uncomment this, when TO is fixed to include DeliveryServices. + // See https://github.com/apache/trafficcontrol/issues/3528 + // if len(cfg.DeliveryService) == 0 { + // return errors.New("MonitorConfig.DeliveryService empty") + // } + if len(cfg.Profile) == 0 { + return errors.New("MonitorConfig.Profile empty") + } + + if intervalI, ok := cfg.Config["peers.polling.interval"]; !ok { + return errors.New(`MonitorConfig.Config["peers.polling.interval"] missing, peers.polling.interval parameter required`) + } else if _, ok := intervalI.(float64); !ok { + return fmt.Errorf(`MonitorConfig.Config["peers.polling.interval"] '%v' not a number, parameter peers.polling.interval must be a number`, intervalI) + } + + if intervalI, ok := cfg.Config["health.polling.interval"]; !ok { + return errors.New(`MonitorConfig.Config["health.polling.interval"] missing, health.polling.interval parameter required`) + } else if _, ok := intervalI.(float64); !ok { + return fmt.Errorf(`MonitorConfig.Config["health.polling.interval"] '%v' not a number, parameter health.polling.interval must be a number`, intervalI) + } + + return nil +} + // CRConfigRaw returns the CRConfig from the Traffic Ops. This is safe for multiple goroutines. func (s TrafficOpsSessionThreadsafe) CRConfigRaw(cdn string) ([]byte, error) { @@ -318,10 +355,15 @@ func (s TrafficOpsSessionThreadsafe) trafficMonitorConfigMapRaw(cdn string) (*tc } configMap, _, err := ss.GetTrafficMonitorConfigMap(cdn) + + if err == nil { + err = MonitorConfigValid(configMap) + } + if err != nil { // Default error case, no backup file exists if !s.BackupFileExists() { - return configMap, err + return nil, err } b, err := ioutil.ReadFile(s.TMConfigBackupFile) @@ -342,6 +384,7 @@ func (s TrafficOpsSessionThreadsafe) trafficMonitorConfigMapRaw(cdn string) (*tc if err == nil { ioutil.WriteFile(s.TMConfigBackupFile, data, 0644) } + return configMap, err } diff --git a/traffic_monitor/towrap/towrap_test.go b/traffic_monitor/towrap/towrap_test.go new file mode 100644 index 0000000000..357475ca68 --- /dev/null +++ b/traffic_monitor/towrap/towrap_test.go @@ -0,0 +1,52 @@ +package towrap + +/* + * 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. + */ + +import ( + "testing" + + "github.com/apache/trafficcontrol/lib/go-tc" +) + +func TestMonitorConfigValid(t *testing.T) { + mc := (*tc.TrafficMonitorConfigMap)(nil) + if MonitorConfigValid(mc) == nil { + t.Errorf("MonitorCopnfigValid(nil) expected: error, actual: nil") + } + mc = &tc.TrafficMonitorConfigMap{} + if MonitorConfigValid(mc) == nil { + t.Errorf("MonitorConfigValid({}) expected: error, actual: nil") + } + + validMC := &tc.TrafficMonitorConfigMap{ + TrafficServer: map[string]tc.TrafficServer{"a": {}}, + CacheGroup: map[string]tc.TMCacheGroup{"a": {}}, + TrafficMonitor: map[string]tc.TrafficMonitor{"a": {}}, + DeliveryService: map[string]tc.TMDeliveryService{"a": {}}, + Profile: map[string]tc.TMProfile{"a": {}}, + Config: map[string]interface{}{ + "peers.polling.interval": 42.0, + "health.polling.interval": 24.0, + }, + } + if err := MonitorConfigValid(validMC); err != nil { + t.Errorf("MonitorConfigValid(%++v) expected: nil, actual: %+v", validMC, err) + } +}