-
Notifications
You must be signed in to change notification settings - Fork 649
/
Copy pathoptions.go
256 lines (220 loc) · 11.4 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
Copyright 2017 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 options
import (
"flag"
"fmt"
"os"
"time"
"net/url"
"github.com/spf13/pflag"
"k8s.io/node-problem-detector/pkg/exporters"
"k8s.io/node-problem-detector/pkg/problemdaemon"
"k8s.io/node-problem-detector/pkg/types"
)
// NodeProblemDetectorOptions contains node problem detector command line and application options.
type NodeProblemDetectorOptions struct {
// command line options
// PrintVersion is the flag determining whether version information is printed.
PrintVersion bool
// HostnameOverride specifies custom node name used to override hostname.
HostnameOverride string
// ServerPort is the port to bind the node problem detector server. Use 0 to disable.
ServerPort int
// ServerAddress is the address to bind the node problem detector server.
ServerAddress string
// QPS is the maximum QPS to the master from client.
QPS float32
// Burst is the maximum burst for throttle.
Burst int
// exporter options
// k8sExporter options
// EnableK8sExporter is the flag determining whether to report to Kubernetes.
EnableK8sExporter bool
// EventNamespace is the namespace events are written to
EventNamespace string
// ApiServerOverride is the custom URI used to connect to Kubernetes ApiServer.
ApiServerOverride string
// APIServerWaitTimeout is the timeout on waiting for kube-apiserver to be
// ready.
APIServerWaitTimeout time.Duration
// APIServerWaitInterval is the interval between the checks on the
// readiness of kube-apiserver.
APIServerWaitInterval time.Duration
// K8sExporterHeartbeatPeriod is the period at which the k8s exporter does forcibly sync with apiserver.
K8sExporterHeartbeatPeriod time.Duration
// prometheusExporter options
// PrometheusServerPort is the port to bind the Prometheus scrape endpoint. Use 0 to disable.
PrometheusServerPort int
// PrometheusServerAddress is the address to bind the Prometheus scrape endpoint.
PrometheusServerAddress string
// problem daemon options
// 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
// application options
// DeleteDeprecatedConditions is the flag determining whether to delete deprecated Conditions and Events from the node status.
DeleteDeprecatedConditions bool
DeprecatedConditionTypes []string
// NodeName is the node name used to communicate with Kubernetes ApiServer.
NodeName string
}
func NewNodeProblemDetectorOptions() *NodeProblemDetectorOptions {
npdo := &NodeProblemDetectorOptions{MonitorConfigPaths: types.ProblemDaemonConfigPathMap{}}
for _, problemDaemonName := range problemdaemon.GetProblemDaemonNames() {
npdo.MonitorConfigPaths[problemDaemonName] = &[]string{}
}
return npdo
}
// AddFlags adds node problem detector command line options to pflag.
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.EventNamespace, "event-namespace", "", "Namespace for recorded Kubernetes events.")
fs.StringVar(&npdo.ApiServerOverride, "apiserver-override",
"", "Custom URI used to connect to Kubernetes ApiServer. This is ignored if --enable-k8s-exporter is false.")
fs.DurationVar(&npdo.APIServerWaitTimeout, "apiserver-wait-timeout", time.Duration(5)*time.Minute, "The timeout on waiting for kube-apiserver to be ready. This is ignored if --enable-k8s-exporter is false.")
fs.DurationVar(&npdo.APIServerWaitInterval, "apiserver-wait-interval", time.Duration(5)*time.Second, "The interval between the checks on the readiness of kube-apiserver. This is ignored if --enable-k8s-exporter is false.")
fs.DurationVar(&npdo.K8sExporterHeartbeatPeriod, "k8s-exporter-heartbeat-period", 5*time.Minute, "The period at which k8s-exporter does forcibly sync with apiserver.")
fs.BoolVar(&npdo.PrintVersion, "version", false, "Print version information and quit")
fs.StringVar(&npdo.HostnameOverride, "hostname-override",
"", "Custom node name used to override hostname")
fs.IntVar(&npdo.ServerPort, "port",
20256, "The port to bind the node problem detector server. Use 0 to disable.")
fs.StringVar(&npdo.ServerAddress, "address",
"127.0.0.1", "The address to bind the node problem detector server.")
fs.IntVar(&npdo.PrometheusServerPort, "prometheus-port",
20257, "The port to bind the Prometheus scrape endpoint. Prometheus exporter is enabled by default at port 20257. Use 0 to disable.")
fs.StringVar(&npdo.PrometheusServerAddress, "prometheus-address",
"127.0.0.1", "The address to bind the Prometheus scrape endpoint.")
fs.Float32Var(&npdo.QPS, "kube-api-qps", 500, "Maximum QPS to use while talking with Kubernetes API")
fs.IntVar(&npdo.Burst, "kube-api-burst", 500, "Maximum burst for throttle while talking with Kubernetes API")
fs.BoolVar(&npdo.DeleteDeprecatedConditions, "delete-deprecated-conditions", false, "Whether to delete deprecated Conditions and Events from the node status")
fs.StringSliceVar(&npdo.DeprecatedConditionTypes, "deprecated-condition-types", []string{}, "List of deprecated condition types to delete. This is ignored if --delete-deprecated-conditions is false.")
for _, exporterName := range exporters.GetExporterNames() {
exporterHandler := exporters.GetExporterHandlerOrDie(exporterName)
exporterHandler.Options.SetFlags(fs)
}
for _, problemDaemonName := range problemdaemon.GetProblemDaemonNames() {
fs.StringSliceVar(
npdo.MonitorConfigPaths[problemDaemonName],
"config."+string(problemDaemonName),
[]string{},
fmt.Sprintf("Comma separated configurations for %v monitor. %v",
problemDaemonName,
problemdaemon.GetProblemDaemonHandlerOrDie(problemDaemonName).CmdOptionDescription))
}
}
// ValidOrDie validates node problem detector command line options.
func (npdo *NodeProblemDetectorOptions) ValidOrDie() {
if _, err := url.Parse(npdo.ApiServerOverride); npdo.EnableK8sExporter && err != nil {
panic(fmt.Sprintf("apiserver-override %q is not a valid HTTP URI: %v",
npdo.ApiServerOverride, err))
}
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.")
}
configCount := 0
for _, problemDaemonConfigPaths := range npdo.MonitorConfigPaths {
configCount += len(*problemDaemonConfigPaths)
}
if configCount == 0 {
panic("No configuration option for any problem daemon is specified.")
}
}
// Plugin names for custom plugin monitor and system log monitor.
// Hard code them here to:
// 1) Handle deprecated flags for --system-log-monitors and --custom-plugin-monitors.
// 2) Avoid direct dependencies to packages in those plugins, so that those plugins
// can be disabled at compile time.
const (
customPluginMonitorName = "custom-plugin-monitor"
systemLogMonitorName = "system-log-monitor"
)
// SetConfigFromDeprecatedOptionsOrDie sets NPD option using deprecated options.
func (npdo *NodeProblemDetectorOptions) SetConfigFromDeprecatedOptionsOrDie() {
if len(npdo.SystemLogMonitorConfigPaths) != 0 {
if npdo.MonitorConfigPaths[systemLogMonitorName] == nil {
// As long as the problem daemon is registered, MonitorConfigPaths should
// not be nil.
panic("System log monitor is not supported")
}
if len(*npdo.MonitorConfigPaths[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[systemLogMonitorName] = append(
*npdo.MonitorConfigPaths[systemLogMonitorName],
npdo.SystemLogMonitorConfigPaths...)
npdo.SystemLogMonitorConfigPaths = []string{}
}
if len(npdo.CustomPluginMonitorConfigPaths) != 0 {
if npdo.MonitorConfigPaths[customPluginMonitorName] == nil {
// As long as the problem daemon is registered, MonitorConfigPaths should
// not be nil.
panic("Custom plugin monitor is not supported")
}
if len(*npdo.MonitorConfigPaths[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[customPluginMonitorName] = append(
*npdo.MonitorConfigPaths[customPluginMonitorName],
npdo.CustomPluginMonitorConfigPaths...)
npdo.CustomPluginMonitorConfigPaths = []string{}
}
}
// SetNodeNameOrDie sets `NodeName` field with valid value.
func (npdo *NodeProblemDetectorOptions) SetNodeNameOrDie() {
// Check hostname override first for customized node name.
if npdo.HostnameOverride != "" {
npdo.NodeName = npdo.HostnameOverride
return
}
// Get node name from environment variable NODE_NAME
// By default, assume that the NODE_NAME env should have been set with
// downward api or user defined exported environment variable. We prefer it because sometimes
// the hostname returned by os.Hostname is not right because:
// 1. User may override the hostname.
// 2. For some cloud providers, os.Hostname is different from the real hostname.
npdo.NodeName = os.Getenv("NODE_NAME")
if npdo.NodeName != "" {
return
}
// For backward compatibility. If the env is not set, get the hostname
// from os.Hostname(). This may not work for all configurations and
// environments.
nodeName, err := os.Hostname()
if err != nil {
panic(fmt.Sprintf("Failed to get host name: %v", err))
}
npdo.NodeName = nodeName
}
func init() {
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
}