Add existing monitors into the problem daemon registration hook.

This commit is contained in:
Xuewei Zhang
2019-06-13 00:51:17 -07:00
parent 63f0e35e56
commit a07176073a
9 changed files with 435 additions and 32 deletions
+7 -21
View File
@@ -23,10 +23,9 @@ import (
"github.com/spf13/pflag"
"k8s.io/node-problem-detector/cmd/options"
"k8s.io/node-problem-detector/pkg/custompluginmonitor"
"k8s.io/node-problem-detector/pkg/exporters/k8sexporter"
"k8s.io/node-problem-detector/pkg/problemdaemon"
"k8s.io/node-problem-detector/pkg/problemdetector"
"k8s.io/node-problem-detector/pkg/systemlogmonitor"
"k8s.io/node-problem-detector/pkg/types"
"k8s.io/node-problem-detector/pkg/version"
)
@@ -43,26 +42,13 @@ func main() {
}
npdo.SetNodeNameOrDie()
npdo.SetConfigFromDeprecatedOptionsOrDie()
npdo.ValidOrDie()
monitors := make(map[string]types.Monitor)
for _, config := range npdo.SystemLogMonitorConfigPaths {
if _, ok := monitors[config]; ok {
// Skip the config if it's duplicated.
glog.Warningf("Duplicated monitor configuration %q", config)
continue
}
monitors[config] = systemlogmonitor.NewLogMonitorOrDie(config)
}
for _, config := range npdo.CustomPluginMonitorConfigPaths {
if _, ok := monitors[config]; ok {
// Skip the config if it's duplicated.
glog.Warningf("Duplicated monitor configuration %q", config)
continue
}
monitors[config] = custompluginmonitor.NewCustomPluginMonitorOrDie(config)
// Initialize problem daemons.
problemDaemons := problemdaemon.NewProblemDaemons(npdo.MonitorConfigPaths)
if len(problemDaemons) == 0 {
glog.Fatalf("No problem daemon is configured")
}
// Initialize exporters.
@@ -76,7 +62,7 @@ func main() {
}
// Initialize NPD core.
p := problemdetector.NewProblemDetector(monitors, exporters)
p := problemdetector.NewProblemDetector(problemDaemons, exporters)
if err := p.Run(); err != nil {
glog.Fatalf("Problem detector failed with error: %v", err)
}
+52 -5
View File
@@ -25,7 +25,9 @@ import (
"github.com/spf13/pflag"
"k8s.io/node-problem-detector/pkg/custompluginmonitor"
"k8s.io/node-problem-detector/pkg/problemdaemon"
"k8s.io/node-problem-detector/pkg/systemlogmonitor"
"k8s.io/node-problem-detector/pkg/types"
)
@@ -54,9 +56,13 @@ type NodeProblemDetectorOptions struct {
// SystemLogMonitorConfigPaths specifies the list of paths to system log monitor configuration
// files.
// SystemLogMonitorConfigPaths is used by the deprecated option --system-log-monitors. The new
// option --config.system-log-monitor will stored the config file paths in MonitorConfigPaths.
SystemLogMonitorConfigPaths []string
// CustomPluginMonitorConfigPaths specifies the list of paths to custom plugin monitor configuration
// files.
// CustomPluginMonitorConfigPaths is used by the deprecated option --custom-plugin-monitors. The
// new option --config.custom-plugin-monitor will stored the config file paths in MonitorConfigPaths.
CustomPluginMonitorConfigPaths []string
// MonitorConfigPaths specifies the list of paths to configuration files for each monitor.
MonitorConfigPaths types.ProblemDaemonConfigPathMap
@@ -75,8 +81,10 @@ func NewNodeProblemDetectorOptions() *NodeProblemDetectorOptions {
func (npdo *NodeProblemDetectorOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringSliceVar(&npdo.SystemLogMonitorConfigPaths, "system-log-monitors",
[]string{}, "List of paths to system log monitor config files, comma separated.")
fs.MarkDeprecated("system-log-monitors", "replaced by --config.system-log-monitor. NPD will panic if both --system-log-monitors and --config.system-log-monitor are set.")
fs.StringSliceVar(&npdo.CustomPluginMonitorConfigPaths, "custom-plugin-monitors",
[]string{}, "List of paths to custom plugin monitor config files, comma separated.")
fs.MarkDeprecated("custom-plugin-monitors", "replaced by --config.custom-plugin-monitor. NPD will panic if both --custom-plugin-monitors and --config.custom-plugin-monitor are set.")
fs.BoolVar(&npdo.EnableK8sExporter, "enable-k8s-exporter", true, "Enables reporting to Kubernetes API server.")
fs.StringVar(&npdo.ApiServerOverride, "apiserver-override",
"", "Custom URI used to connect to Kubernetes ApiServer. This is ignored if --enable-k8s-exporter is false.")
@@ -106,14 +114,53 @@ func (npdo *NodeProblemDetectorOptions) ValidOrDie() {
panic(fmt.Sprintf("apiserver-override %q is not a valid HTTP URI: %v",
npdo.ApiServerOverride, err))
}
if len(npdo.SystemLogMonitorConfigPaths) == 0 && len(npdo.CustomPluginMonitorConfigPaths) == 0 {
panic(fmt.Sprintf("Either --system-log-monitors or --custom-plugin-monitors is required"))
if len(npdo.SystemLogMonitorConfigPaths) != 0 {
panic("SystemLogMonitorConfigPaths is deprecated. It should have been reassigned to MonitorConfigPaths. This should not happen.")
}
if len(npdo.CustomPluginMonitorConfigPaths) != 0 {
panic("CustomPluginMonitorConfigPaths is deprecated. It should have been reassigned to MonitorConfigPaths. This should not happen.")
}
for problemDaemonName, configs := range npdo.MonitorConfigPaths {
if configs == nil {
panic(fmt.Sprintf("nil config for problem daemon %q. This should never happen, might indicates bug in pflag.", problemDaemonName))
configCount := 0
for _, problemDaemonConfigPaths := range npdo.MonitorConfigPaths {
configCount += len(*problemDaemonConfigPaths)
}
if configCount == 0 {
panic("No configuration option for any problem daemon is specified.")
}
}
// SetConfigFromDeprecatedOptionsOrDie sets NPD option using deprecated options.
func (npdo *NodeProblemDetectorOptions) SetConfigFromDeprecatedOptionsOrDie() {
if len(npdo.SystemLogMonitorConfigPaths) != 0 {
if npdo.MonitorConfigPaths[systemlogmonitor.SystemLogMonitorName] == nil {
npdo.MonitorConfigPaths[systemlogmonitor.SystemLogMonitorName] = &[]string{}
}
if len(*npdo.MonitorConfigPaths[systemlogmonitor.SystemLogMonitorName]) != 0 {
panic("Option --system-log-monitors is deprecated in favor of --config.system-log-monitor. They cannot be set at the same time.")
}
*npdo.MonitorConfigPaths[systemlogmonitor.SystemLogMonitorName] = append(
*npdo.MonitorConfigPaths[systemlogmonitor.SystemLogMonitorName],
npdo.SystemLogMonitorConfigPaths...)
npdo.SystemLogMonitorConfigPaths = []string{}
}
if len(npdo.CustomPluginMonitorConfigPaths) != 0 {
if npdo.MonitorConfigPaths[custompluginmonitor.CustomPluginMonitorName] == nil {
npdo.MonitorConfigPaths[custompluginmonitor.CustomPluginMonitorName] = &[]string{}
}
if len(*npdo.MonitorConfigPaths[custompluginmonitor.CustomPluginMonitorName]) != 0 {
panic("Option --custom-plugin-monitors is deprecated in favor of --config.custom-plugin-monitor. They cannot be set at the same time.")
}
*npdo.MonitorConfigPaths[custompluginmonitor.CustomPluginMonitorName] = append(
*npdo.MonitorConfigPaths[custompluginmonitor.CustomPluginMonitorName],
npdo.CustomPluginMonitorConfigPaths...)
npdo.CustomPluginMonitorConfigPaths = []string{}
}
}
+283
View File
@@ -18,9 +18,47 @@ package options
import (
"os"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/node-problem-detector/pkg/custompluginmonitor"
"k8s.io/node-problem-detector/pkg/systemlogmonitor"
"k8s.io/node-problem-detector/pkg/types"
)
func equalMonitorConfigPaths(npdoX NodeProblemDetectorOptions, npdoY NodeProblemDetectorOptions) bool {
monitorConfigPathsX, monitorConfigPathsY := npdoX.MonitorConfigPaths, npdoY.MonitorConfigPaths
if monitorConfigPathsX == nil && monitorConfigPathsY == nil {
return true
}
if monitorConfigPathsX == nil || monitorConfigPathsY == nil {
return false
}
if len(monitorConfigPathsX) != len(monitorConfigPathsY) {
return false
}
for problemDaemonType, configPathsX := range monitorConfigPathsX {
configPathsY, ok := monitorConfigPathsY[problemDaemonType]
if !ok {
return false
}
if configPathsX == nil && configPathsY == nil {
continue
}
if configPathsX == nil || configPathsY == nil {
return false
}
if !reflect.DeepEqual(*configPathsX, *configPathsY) {
return false
}
}
return true
}
type options struct {
Nodename string
HostnameOverride string
@@ -82,3 +120,248 @@ func TestSetNodeNameOrDie(t *testing.T) {
}
}
}
func TestValidOrDie(t *testing.T) {
fooMonitorConfigMap := types.ProblemDaemonConfigPathMap{}
fooMonitorConfigMap["foo-monitor"] = &[]string{"config-a", "config-b"}
emptyMonitorConfigMap := types.ProblemDaemonConfigPathMap{}
testCases := []struct {
name string
npdo NodeProblemDetectorOptions
expectPanic bool
}{
{
name: "default k8s exporter config",
npdo: NodeProblemDetectorOptions{
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: false,
},
{
name: "enables k8s exporter config",
npdo: NodeProblemDetectorOptions{
ApiServerOverride: "",
EnableK8sExporter: true,
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: false,
},
{
name: "k8s exporter config with valid ApiServerOverride",
npdo: NodeProblemDetectorOptions{
ApiServerOverride: "127.0.0.1",
EnableK8sExporter: true,
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: false,
},
{
name: "k8s exporter config with invalid ApiServerOverride",
npdo: NodeProblemDetectorOptions{
ApiServerOverride: ":foo",
EnableK8sExporter: true,
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: true,
},
{
name: "non-empty MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: false,
},
{
name: "empty MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
MonitorConfigPaths: emptyMonitorConfigMap,
},
expectPanic: true,
},
{
name: "un-initialized MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{},
expectPanic: true,
},
{
name: "mixture of deprecated SystemLogMonitorConfigPaths and new MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a"},
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: true,
},
{
name: "mixture of deprecated CustomPluginMonitorConfigPaths and new MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
CustomPluginMonitorConfigPaths: []string{"config-a"},
MonitorConfigPaths: fooMonitorConfigMap,
},
expectPanic: true,
},
{
name: "deprecated SystemLogMonitor option with empty MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a"},
MonitorConfigPaths: emptyMonitorConfigMap,
},
expectPanic: true,
},
{
name: "deprecated SystemLogMonitor option with un-initialized MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a"},
},
expectPanic: true,
},
{
name: "deprecated CustomPluginMonitor option with empty MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
CustomPluginMonitorConfigPaths: []string{"config-b"},
MonitorConfigPaths: emptyMonitorConfigMap,
},
expectPanic: true,
},
{
name: "deprecated CustomPluginMonitor option with un-initialized MonitorConfigPaths",
npdo: NodeProblemDetectorOptions{
CustomPluginMonitorConfigPaths: []string{"config-b"},
},
expectPanic: true,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
if test.expectPanic {
assert.Panics(t, test.npdo.ValidOrDie, "NPD option %+v is invalid. Expected ValidOrDie to panic.", test.npdo)
} else {
assert.NotPanics(t, test.npdo.ValidOrDie, "NPD option %+v is valid. Expected ValidOrDie to not panic.", test.npdo)
}
})
}
}
func TestSetConfigFromDeprecatedOptionsOrDie(t *testing.T) {
testCases := []struct {
name string
orig NodeProblemDetectorOptions
wanted NodeProblemDetectorOptions
expectPanic bool
}{
{
name: "no deprecated options",
orig: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-a", "config-b"},
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-c", "config-d"},
},
},
expectPanic: false,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-a", "config-b"},
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-c", "config-d"},
},
},
},
{
name: "correctly using deprecated options",
orig: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a", "config-b"},
CustomPluginMonitorConfigPaths: []string{"config-c", "config-d"},
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{},
},
expectPanic: false,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-a", "config-b"},
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-c", "config-d"},
},
},
},
{
name: "using deprecated SystemLogMonitor option and new CustomPluginMonitor option",
orig: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a", "config-b"},
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-c", "config-d"},
},
},
expectPanic: false,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-a", "config-b"},
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-c", "config-d"},
},
},
},
{
name: "using deprecated CustomPluginMonitor option and new SystemLogMonitor option",
orig: NodeProblemDetectorOptions{
CustomPluginMonitorConfigPaths: []string{"config-a", "config-b"},
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-c", "config-d"},
},
},
expectPanic: false,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-c", "config-d"},
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-a", "config-b"},
},
},
},
{
name: "using deprecated & new options on SystemLogMonitor",
orig: NodeProblemDetectorOptions{
SystemLogMonitorConfigPaths: []string{"config-a"},
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-b"},
},
},
expectPanic: true,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
systemlogmonitor.SystemLogMonitorName: &[]string{"config-b"},
},
},
},
{
name: "using deprecated & new options on CustomPluginMonitor",
orig: NodeProblemDetectorOptions{
CustomPluginMonitorConfigPaths: []string{"config-a"},
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-b"},
},
},
expectPanic: true,
wanted: NodeProblemDetectorOptions{
MonitorConfigPaths: types.ProblemDaemonConfigPathMap{
custompluginmonitor.CustomPluginMonitorName: &[]string{"config-b"},
},
},
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
if test.expectPanic {
assert.Panics(t, test.orig.SetConfigFromDeprecatedOptionsOrDie,
"NPD option %+v is illegal. Expected SetConfigFromDeprecatedOptionsOrDie to panic.", test.orig)
} else {
assert.NotPanics(t, test.orig.SetConfigFromDeprecatedOptionsOrDie,
"NPD option %+v is illegal. Expected SetConfigFromDeprecatedOptionsOrDie to not panic.", test.orig)
if !equalMonitorConfigPaths(test.orig, test.wanted) {
t.Errorf("Expect to get NPD option %+v, but got %+v", test.wanted, test.orig)
}
assert.Len(t, test.orig.SystemLogMonitorConfigPaths, 0,
"SystemLogMonitorConfigPaths is deprecated and should to be cleared.")
assert.Len(t, test.orig.CustomPluginMonitorConfigPaths, 0,
"CustomPluginMonitorConfigPaths is deprecated and should to be cleared.")
}
})
}
}
+23
View File
@@ -0,0 +1,23 @@
/*
Copyright 2019 The Kubernetes Authors All rights reserved.
Licensed 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
// register problem daemons here
import (
_ "k8s.io/node-problem-detector/pkg/custompluginmonitor"
_ "k8s.io/node-problem-detector/pkg/systemlogmonitor"
)