Skip to content

Commit e280e20

Browse files
authored
Merge pull request #320 from wangzhen127/custom-plugin-fix
Don't update condition if status stays False/Unknown for custom plugin
2 parents eeb51ee + 30e20c6 commit e280e20

File tree

3 files changed

+122
-53
lines changed

3 files changed

+122
-53
lines changed

pkg/custompluginmonitor/custom_plugin_monitor.go

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -158,77 +158,78 @@ func (c *customPluginMonitor) generateStatus(result cpmtypes.Result) *types.Stat
158158
})
159159
}
160160
} else {
161-
// For permanent error changes the condition
161+
// For permanent error that changes the condition
162162
for i := range c.conditions {
163163
condition := &c.conditions[i]
164164
if condition.Type == result.Rule.Condition {
165+
// The condition reason specified in the rule and the result message
166+
// represent the problem happened. We need to know the default condition
167+
// from the config, so that we can set the new condition reason/message
168+
// back when such problem goes away.
169+
var defaultConditionReason string
170+
var defaultConditionMessage string
171+
for j := range c.config.DefaultConditions {
172+
defaultCondition := &c.config.DefaultConditions[j]
173+
if defaultCondition.Type == result.Rule.Condition {
174+
defaultConditionReason = defaultCondition.Reason
175+
defaultConditionMessage = defaultCondition.Message
176+
break
177+
}
178+
}
179+
180+
needToUpdateCondition := true
181+
var newReason string
182+
var newMessage string
165183
status := toConditionStatus(result.ExitStatus)
166-
// change 1: Condition status change from True to False/Unknown
167184
if condition.Status == types.True && status != types.True {
168-
condition.Transition = timestamp
169-
var defaultConditionReason string
170-
var defaultConditionMessage string
171-
for j := range c.config.DefaultConditions {
172-
defaultCondition := &c.config.DefaultConditions[j]
173-
if defaultCondition.Type == result.Rule.Condition {
174-
defaultConditionReason = defaultCondition.Reason
175-
defaultConditionMessage = defaultCondition.Message
176-
break
177-
}
185+
// Scenario 1: Condition status changes from True to False/Unknown
186+
newReason = defaultConditionReason
187+
if newMessage == "" {
188+
newMessage = defaultConditionMessage
189+
} else {
190+
newMessage = result.Message
178191
}
179-
180-
inactiveProblemEvents = append(inactiveProblemEvents, util.GenerateConditionChangeEvent(
181-
condition.Type,
182-
status,
183-
defaultConditionReason,
184-
timestamp,
185-
))
186-
187-
condition.Status = status
188-
condition.Message = defaultConditionMessage
189-
condition.Reason = defaultConditionReason
190192
} else if condition.Status != types.True && status == types.True {
191-
// change 2: Condition status change from False/Unknown to True
192-
condition.Transition = timestamp
193-
condition.Message = result.Message
194-
activeProblemEvents = append(activeProblemEvents, util.GenerateConditionChangeEvent(
195-
condition.Type,
196-
status,
197-
result.Rule.Reason,
198-
timestamp,
199-
))
200-
201-
condition.Status = status
202-
condition.Reason = result.Rule.Reason
193+
// Scenario 2: Condition status changes from False/Unknown to True
194+
newReason = result.Rule.Reason
195+
newMessage = result.Message
203196
} else if condition.Status != status {
204-
// change 3: Condition status change from False to Unknown or vice versa
205-
condition.Transition = timestamp
206-
condition.Message = result.Message
207-
inactiveProblemEvents = append(inactiveProblemEvents, util.GenerateConditionChangeEvent(
208-
condition.Type,
209-
status,
210-
result.Rule.Reason,
211-
timestamp,
212-
))
213-
214-
condition.Status = status
215-
condition.Reason = result.Rule.Reason
216-
} else if condition.Status == status &&
197+
// Scenario 3: Condition status changes from False to Unknown or vice versa
198+
newReason = defaultConditionReason
199+
if newMessage == "" {
200+
newMessage = defaultConditionMessage
201+
} else {
202+
newMessage = result.Message
203+
}
204+
} else if condition.Status == types.True && status == types.True &&
217205
(condition.Reason != result.Rule.Reason ||
218206
(*c.config.PluginGlobalConfig.EnableMessageChangeBasedConditionUpdate && condition.Message != result.Message)) {
219-
// change 4: Condition status do not change.
207+
// Scenario 4: Condition status does not change and it stays true.
220208
// condition reason changes or
221209
// condition message changes when message based condition update is enabled.
210+
newReason = result.Rule.Reason
211+
newMessage = result.Message
212+
} else {
213+
// Scenario 5: Condition status does not change and it stays False/Unknown.
214+
// This should just be the default reason or message (as a consequence
215+
// of scenario 1 and scenario 3 above).
216+
needToUpdateCondition = false
217+
}
218+
219+
if needToUpdateCondition {
222220
condition.Transition = timestamp
223-
condition.Reason = result.Rule.Reason
224-
condition.Message = result.Message
221+
condition.Status = status
222+
condition.Reason = newReason
223+
condition.Message = newMessage
224+
225225
updateEvent := util.GenerateConditionChangeEvent(
226226
condition.Type,
227227
status,
228-
condition.Reason,
228+
newReason,
229229
timestamp,
230230
)
231-
if condition.Status == types.True {
231+
232+
if status == types.True {
232233
activeProblemEvents = append(activeProblemEvents, updateEvent)
233234
} else {
234235
inactiveProblemEvents = append(inactiveProblemEvents, updateEvent)

pkg/custompluginmonitor/types/config.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,22 @@ func (cpc CustomPluginConfig) Validate() error {
141141
}
142142
}
143143

144+
for _, rule := range cpc.Rules {
145+
if rule.Type != types.Perm {
146+
continue
147+
}
148+
conditionType := rule.Condition
149+
defaultConditionExists := false
150+
for _, cond := range cpc.DefaultConditions {
151+
if conditionType == cond.Type {
152+
defaultConditionExists = true
153+
break
154+
}
155+
}
156+
if !defaultConditionExists {
157+
return fmt.Errorf("Permanent problem %s does not have preset default condition.", conditionType)
158+
}
159+
}
160+
144161
return nil
145162
}

pkg/custompluginmonitor/types/config_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"reflect"
2121
"testing"
2222
"time"
23+
24+
"k8s.io/node-problem-detector/pkg/types"
2325
)
2426

2527
func TestCustomPluginConfigApplyConfiguration(t *testing.T) {
@@ -279,6 +281,55 @@ func TestCustomPluginConfigValidate(t *testing.T) {
279281
},
280282
IsError: true,
281283
},
284+
"permanent problem has preset default condition": {
285+
Conf: CustomPluginConfig{
286+
Plugin: customPluginName,
287+
PluginGlobalConfig: pluginGlobalConfig{
288+
InvokeInterval: &defaultInvokeInterval,
289+
Timeout: &defaultGlobalTimeout,
290+
MaxOutputLength: &defaultMaxOutputLength,
291+
Concurrency: &defaultConcurrency,
292+
},
293+
DefaultConditions: []types.Condition{
294+
{
295+
Type: "TestCondition",
296+
Reason: "TestConditionOK",
297+
Message: "Test condition is OK.",
298+
},
299+
},
300+
Rules: []*CustomRule{
301+
{
302+
Type: types.Perm,
303+
Condition: "TestCondition",
304+
Reason: "TestConditionFail",
305+
Path: "../plugin/test-data/ok.sh",
306+
Timeout: &normalRuleTimeout,
307+
},
308+
},
309+
},
310+
IsError: false,
311+
},
312+
"permanent problem does not have preset default condition": {
313+
Conf: CustomPluginConfig{
314+
Plugin: customPluginName,
315+
PluginGlobalConfig: pluginGlobalConfig{
316+
InvokeInterval: &defaultInvokeInterval,
317+
Timeout: &defaultGlobalTimeout,
318+
MaxOutputLength: &defaultMaxOutputLength,
319+
Concurrency: &defaultConcurrency,
320+
},
321+
Rules: []*CustomRule{
322+
{
323+
Type: types.Perm,
324+
Condition: "TestCondition",
325+
Reason: "TestConditionFail",
326+
Path: "../plugin/test-data/ok.sh",
327+
Timeout: &normalRuleTimeout,
328+
},
329+
},
330+
},
331+
IsError: true,
332+
},
282333
}
283334

284335
for desp, utMeta := range utMetas {

0 commit comments

Comments
 (0)