Skip to content

Commit ee103dd

Browse files
committed
Generate event for condition change and support unknown status.
1 parent 8f286a4 commit ee103dd

File tree

8 files changed

+100
-19
lines changed

8 files changed

+100
-19
lines changed

pkg/condition/manager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func newTestManager() (*conditionManager, *problemclient.FakeProblemClient, *clo
4141
func newTestCondition(condition string) types.Condition {
4242
return types.Condition{
4343
Type: condition,
44-
Status: true,
44+
Status: types.True,
4545
Transition: time.Now(),
4646
Reason: "TestReason",
4747
Message: "test message",

pkg/custompluginmonitor/custom_plugin_monitor.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"k8s.io/node-problem-detector/pkg/custompluginmonitor/plugin"
2727
cpmtypes "k8s.io/node-problem-detector/pkg/custompluginmonitor/types"
2828
"k8s.io/node-problem-detector/pkg/types"
29+
"k8s.io/node-problem-detector/pkg/util"
2930
"k8s.io/node-problem-detector/pkg/util/tomb"
3031
)
3132

@@ -124,10 +125,16 @@ func (c *customPluginMonitor) generateStatus(result cpmtypes.Result) *types.Stat
124125
for i := range c.conditions {
125126
condition := &c.conditions[i]
126127
if condition.Type == result.Rule.Condition {
127-
status := result.ExitStatus >= cpmtypes.NonOK
128+
status := toConditionStatus(result.ExitStatus)
128129
if condition.Status != status || condition.Reason != result.Rule.Reason {
129130
condition.Transition = timestamp
130131
condition.Message = result.Message
132+
events = append(events, util.GenerateConditionChangeEvent(
133+
condition.Type,
134+
status,
135+
result.Rule.Reason,
136+
timestamp,
137+
))
131138
}
132139
condition.Status = status
133140
condition.Reason = result.Rule.Reason
@@ -143,6 +150,17 @@ func (c *customPluginMonitor) generateStatus(result cpmtypes.Result) *types.Stat
143150
}
144151
}
145152

153+
func toConditionStatus(s cpmtypes.Status) types.ConditionStatus {
154+
switch s {
155+
case cpmtypes.OK:
156+
return types.False
157+
case cpmtypes.NonOK:
158+
return types.True
159+
default:
160+
return types.Unknown
161+
}
162+
}
163+
146164
// initializeStatus initializes the internal condition and also reports it to the node problem detector.
147165
func (c *customPluginMonitor) initializeStatus() {
148166
// Initialize the default node conditions
@@ -159,8 +177,7 @@ func initialConditions(defaults []types.Condition) []types.Condition {
159177
conditions := make([]types.Condition, len(defaults))
160178
copy(conditions, defaults)
161179
for i := range conditions {
162-
// TODO(random-liu): Validate default conditions
163-
conditions[i].Status = false
180+
conditions[i].Status = types.False
164181
conditions[i].Transition = time.Now()
165182
}
166183
return conditions

pkg/systemlogmonitor/log_monitor.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import (
2121
"io/ioutil"
2222
"time"
2323

24+
"github.com/golang/glog"
25+
2426
"k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers"
2527
watchertypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types"
2628
logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types"
2729
systemlogtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types"
2830
"k8s.io/node-problem-detector/pkg/types"
29-
30-
"github.com/golang/glog"
31+
"k8s.io/node-problem-detector/pkg/util"
3132
"k8s.io/node-problem-detector/pkg/util/tomb"
3233
)
3334

@@ -138,11 +139,17 @@ func (l *logMonitor) generateStatus(logs []*logtypes.Log, rule systemlogtypes.Ru
138139
// Update transition timestamp and message when the condition
139140
// changes. Condition is considered to be changed only when
140141
// status or reason changes.
141-
if !condition.Status || condition.Reason != rule.Reason {
142+
if condition.Status == types.False || condition.Reason != rule.Reason {
142143
condition.Transition = timestamp
143144
condition.Message = message
145+
events = append(events, util.GenerateConditionChangeEvent(
146+
condition.Type,
147+
types.True,
148+
rule.Reason,
149+
timestamp,
150+
))
144151
}
145-
condition.Status = true
152+
condition.Status = types.True
146153
condition.Reason = rule.Reason
147154
break
148155
}
@@ -172,8 +179,7 @@ func initialConditions(defaults []types.Condition) []types.Condition {
172179
conditions := make([]types.Condition, len(defaults))
173180
copy(conditions, defaults)
174181
for i := range conditions {
175-
// TODO(random-liu): Validate default conditions
176-
conditions[i].Status = false
182+
conditions[i].Status = types.False
177183
conditions[i].Transition = time.Now()
178184
}
179185
return conditions

pkg/systemlogmonitor/log_monitor_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
watchertest "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/testing"
2929
logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types"
3030
"k8s.io/node-problem-detector/pkg/types"
31+
"k8s.io/node-problem-detector/pkg/util"
3132
)
3233

3334
const (
@@ -40,13 +41,13 @@ func TestGenerateStatus(t *testing.T) {
4041
initConditions := []types.Condition{
4142
{
4243
Type: testConditionA,
43-
Status: true,
44+
Status: types.True,
4445
Transition: time.Unix(500, 500),
4546
Reason: "initial reason",
4647
},
4748
{
4849
Type: testConditionB,
49-
Status: false,
50+
Status: types.False,
5051
Transition: time.Unix(500, 500),
5152
},
5253
}
@@ -73,10 +74,16 @@ func TestGenerateStatus(t *testing.T) {
7374
},
7475
expected: types.Status{
7576
Source: testSource,
77+
Events: []types.Event{util.GenerateConditionChangeEvent(
78+
testConditionA,
79+
types.True,
80+
"test reason",
81+
time.Unix(1000, 1000),
82+
)},
7683
Conditions: []types.Condition{
7784
{
7885
Type: testConditionA,
79-
Status: true,
86+
Status: types.True,
8087
Transition: time.Unix(1000, 1000),
8188
Reason: "test reason",
8289
Message: "test message 1\ntest message 2",
@@ -97,7 +104,7 @@ func TestGenerateStatus(t *testing.T) {
97104
Conditions: []types.Condition{
98105
{
99106
Type: testConditionA,
100-
Status: true,
107+
Status: types.True,
101108
Transition: time.Unix(500, 500),
102109
Reason: "initial reason",
103110
},

pkg/types/types.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,25 @@ const (
3838
Warn Severity = "warn"
3939
)
4040

41+
// ConditionStatus is the status of the condition.
42+
type ConditionStatus string
43+
44+
const (
45+
// True means the condition status is true.
46+
True ConditionStatus = "True"
47+
// False means the condition status is false.
48+
False ConditionStatus = "False"
49+
// Unknown means the condition status is unknown.
50+
Unknown ConditionStatus = "Unknown"
51+
)
52+
4153
// Condition is the node condition used internally by problem detector.
4254
type Condition struct {
4355
// Type is the condition type. It should describe the condition of node in problem. For example
4456
// KernelDeadlock, OutOfResource etc.
4557
Type string `json:"type"`
4658
// Status indicates whether the node is in the condition or not.
47-
Status bool `json:"status"`
59+
Status ConditionStatus `json:"status"`
4860
// Transition is the time when the node transits to this condition.
4961
Transition time.Time `json:"transition"`
5062
// Reason is a short reason of why node goes into this condition.

pkg/util/convert.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@ func ConvertToAPICondition(condition types.Condition) api.NodeCondition {
3737
}
3838

3939
// ConvertToAPIConditionStatus converts the internal node condition status to api.ConditionStatus.
40-
func ConvertToAPIConditionStatus(status bool) api.ConditionStatus {
41-
if status {
40+
func ConvertToAPIConditionStatus(status types.ConditionStatus) api.ConditionStatus {
41+
switch status {
42+
case types.True:
4243
return api.ConditionTrue
44+
case types.False:
45+
return api.ConditionFalse
46+
case types.Unknown:
47+
return api.ConditionUnknown
48+
default:
49+
panic("unknown condition status")
4350
}
44-
return api.ConditionFalse
4551
}
4652

4753
// ConvertToAPIEventType converts the internal severity to event type.

pkg/util/convert_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestConvertToAPICondition(t *testing.T) {
3030
now := time.Now()
3131
condition := types.Condition{
3232
Type: "TestCondition",
33-
Status: true,
33+
Status: types.True,
3434
Transition: now,
3535
Reason: "test reason",
3636
Message: "test message",

pkg/util/helpers.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package util
17+
18+
import (
19+
"fmt"
20+
"time"
21+
22+
"k8s.io/node-problem-detector/pkg/types"
23+
)
24+
25+
// GenerateConditionChangeEvent generates an event for condition change.
26+
func GenerateConditionChangeEvent(t string, status types.ConditionStatus, reason string, timestamp time.Time) types.Event {
27+
return types.Event{
28+
Severity: types.Info,
29+
Timestamp: timestamp,
30+
Reason: reason,
31+
Message: fmt.Sprintf("Node condition %s is now: %s, reason: %s", t, status, reason),
32+
}
33+
}

0 commit comments

Comments
 (0)