Skip to content

Commit

Permalink
update events configured to watch specific fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Surbhidongaonkar committed Dec 9, 2019
1 parent d8f10a6 commit 889dd2a
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 24 deletions.
16 changes: 15 additions & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ resources:
- create
- update
- delete
- update
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: statefulset
namespaces:
include:
Expand All @@ -43,6 +47,11 @@ resources:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: ingress
namespaces:
include:
Expand Down Expand Up @@ -134,6 +143,11 @@ resources:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: role
namespaces:
include:
Expand Down
20 changes: 20 additions & 0 deletions deploy-all-in-one.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ data:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: statefulset
namespaces:
include:
Expand All @@ -52,6 +57,11 @@ data:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: ingress
namespaces:
include:
Expand Down Expand Up @@ -123,6 +133,11 @@ data:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: job
namespaces:
include:
Expand All @@ -134,6 +149,11 @@ data:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: role
namespaces:
include:
Expand Down
15 changes: 15 additions & 0 deletions helm/botkube/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ config:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: statefulset
namespaces:
include:
Expand All @@ -72,6 +77,11 @@ config:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: ingress
namespaces:
include:
Expand Down Expand Up @@ -153,6 +163,11 @@ config:
- update
- delete
- error
updateSetting:
includeDiff: true
fields:
- spec
- status
- name: role
namespaces:
include:
Expand Down
16 changes: 13 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ var Notify = true
// NotifType to change notification type
type NotifType string

// FieldType to specify the resource fields for which to get notification
type FieldType string

// Config structure of configuration yaml file
type Config struct {
Resources []Resource
Expand All @@ -53,9 +56,16 @@ type Config struct {

// Resource contains resources to watch
type Resource struct {
Name string
Namespaces Namespaces
Events []EventType
Name string
Namespaces Namespaces
Events []EventType
UpdateSetting UpdateSetting `yaml:"updateSetting"`
}

//UpdateSetting struct defines updateEvent fields specification
type UpdateSetting struct {
Fields []FieldType
IncludeDiff bool `yaml:"includeDiff"`
}

// Namespaces contains namespaces to include and ignore
Expand Down
9 changes: 8 additions & 1 deletion pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,14 @@ func sendEvent(obj, oldObj interface{}, c *config.Config, notifiers []notify.Not

// check for siginificant Update Events in objects
if eventType == config.UpdateEvent {
updateMsg := utils.Diff(oldObj, obj)
updatesettingAll, existsAll := utils.AllowedUpdateEventsMap[utils.KindNS{Resource: kind, Namespace: "all"}]
updatesettingNS, existsNS := utils.AllowedUpdateEventsMap[utils.KindNS{Resource: kind, Namespace: objectMeta.Namespace}]
var updateMsg string
if existsAll {
updateMsg = utils.Diff(oldObj, obj, updatesettingAll)
} else if existsNS {
updateMsg = utils.Diff(oldObj, obj, updatesettingNS)
}
if len(updateMsg) > 0 {
event.Messages = append(event.Messages, updateMsg)
} else {
Expand Down
31 changes: 19 additions & 12 deletions pkg/utils/cmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,51 @@ import (
"strings"

"github.com/google/go-cmp/cmp"
"github.com/infracloudio/botkube/pkg/config"
)

// SpecDiffReporter is a simple custom reporter that only records differences
// detected in Object Spec during comparison.
type SpecDiffReporter struct {
// DiffReporter is a simple custom reporter that records differences
// detected in Object during comparison.
type DiffReporter struct {
field string
path cmp.Path
diffs []string
}

// PushStep custom implements Reporter interface
func (r *SpecDiffReporter) PushStep(ps cmp.PathStep) {
func (r *DiffReporter) PushStep(ps cmp.PathStep) {
r.path = append(r.path, ps)
}

// Report custom implements Reporter interface
func (r *SpecDiffReporter) Report(rs cmp.Result) {
func (r *DiffReporter) Report(rs cmp.Result) {
if !rs.Equal() {
vx, vy := r.path.Last().Values()
path := fmt.Sprintf("%#v", r.path)
if ok := strings.Contains(path, ".Spec."); ok {
if ok := strings.Contains(path, "."+strings.Title(r.field)); ok {
r.diffs = append(r.diffs, fmt.Sprintf("%#v:\n\t-: %+v\n\t+: %+v\n", r.path, vx, vy))
}
}
}

// PopStep custom implements Reporter interface
func (r *SpecDiffReporter) PopStep() {
func (r *DiffReporter) PopStep() {
r.path = r.path[:len(r.path)-1]
}

// String custom implements Reporter interface
func (r *SpecDiffReporter) String() string {
func (r *DiffReporter) String() string {
return strings.Join(r.diffs, "\n")
}

// Diff provides differences between two objects spec
func Diff(x, y interface{}) string {
var r SpecDiffReporter
cmp.Equal(x, y, cmp.Reporter(&r))
return r.String()
func Diff(x, y interface{}, updatesetting config.UpdateSetting) string {
msg := ""
for _, val := range updatesetting.Fields {
var r DiffReporter
r.field = string(val)
cmp.Equal(x, y, cmp.Reporter(&r))
msg = msg + r.String()
}
return msg
}
81 changes: 76 additions & 5 deletions pkg/utils/cmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ package utils
import (
"fmt"
"testing"

"github.com/infracloudio/botkube/pkg/config"
)

// Object mocks kubernetes objects
type Object struct {
Spec Spec
Other Other
Spec Spec
Status Status
Data Data
Rules Rules
Other Other
}

// Other mocks fileds like MetaData, Status etc in kubernetes objects
Expand All @@ -21,6 +26,21 @@ type Spec struct {
Port int
}

// Status mocks ObjectStatus field in kubernetes object
type Status struct {
Replicas int
}

// Data mocks ObjectData field in kubernetes object like configmap
type Data struct {
Properties string
}

// Rules mocks ObjectRules field in kubernetes object
type Rules struct {
Verbs string
}

// ExpectedDiff struct to generate expected diff
type ExpectedDiff struct {
Path string
Expand All @@ -32,11 +52,13 @@ func TestDiff(t *testing.T) {
tests := map[string]struct {
old Object
new Object
update config.UpdateSetting
expected ExpectedDiff
}{
`Spec Diff`: {
old: Object{Spec: Spec{Port: 81}, Other: Other{Foo: "bar"}},
new: Object{Spec: Spec{Port: 83}, Other: Other{Foo: "bar"}},
old: Object{Spec: Spec{Port: 81}, Other: Other{Foo: "bar"}},
new: Object{Spec: Spec{Port: 83}, Other: Other{Foo: "bar"}},
update: config.UpdateSetting{Fields: []config.FieldType{"Spec"}, IncludeDiff: true},
expected: ExpectedDiff{
Path: "{utils.Object}.Spec.Port",
X: "81",
Expand All @@ -46,13 +68,62 @@ func TestDiff(t *testing.T) {
`Non Spec Diff`: {
old: Object{Spec: Spec{Port: 81}, Other: Other{Foo: "bar"}},
new: Object{Spec: Spec{Port: 81}, Other: Other{Foo: "boo"}},
update: config.UpdateSetting{Fields: []config.FieldType{"metadata"}, IncludeDiff: true},
expected: ExpectedDiff{},
},
`Status Diff`: {
old: Object{Status: Status{Replicas: 1}, Other: Other{Foo: "bar"}},
new: Object{Status: Status{Replicas: 2}, Other: Other{Foo: "bar"}},
update: config.UpdateSetting{Fields: []config.FieldType{"Status"}, IncludeDiff: true},
expected: ExpectedDiff{
Path: "{utils.Object}.Status.Replicas",
X: "1",
Y: "2",
},
},
`Non Status Diff`: {
old: Object{Status: Status{Replicas: 1}, Other: Other{Foo: "bar"}},
new: Object{Status: Status{Replicas: 1}, Other: Other{Foo: "boo"}},
update: config.UpdateSetting{Fields: []config.FieldType{"metadata"}, IncludeDiff: true},
expected: ExpectedDiff{},
},
`Data Diff`: {
old: Object{Data: Data{Properties: "Color: blue"}, Other: Other{Foo: "bar"}},
new: Object{Data: Data{Properties: "Color: red"}, Other: Other{Foo: "bar"}},
update: config.UpdateSetting{Fields: []config.FieldType{"Data"}, IncludeDiff: true},
expected: ExpectedDiff{
Path: "{utils.Object}.Data.Properties",
X: "Color: blue",
Y: "Color: red",
},
},
`Non Data Diff`: {
old: Object{Data: Data{Properties: "Color: blue"}, Other: Other{Foo: "bar"}},
new: Object{Data: Data{Properties: "Color: blue"}, Other: Other{Foo: "boo"}},
update: config.UpdateSetting{Fields: []config.FieldType{"metadata"}, IncludeDiff: true},
expected: ExpectedDiff{},
},
`Rules Diff`: {
old: Object{Rules: Rules{Verbs: "list"}, Other: Other{Foo: "bar"}},
new: Object{Rules: Rules{Verbs: "watch"}, Other: Other{Foo: "bar"}},
update: config.UpdateSetting{Fields: []config.FieldType{"Rules"}, IncludeDiff: true},
expected: ExpectedDiff{
Path: "{utils.Object}.Rules.Verbs",
X: "list",
Y: "watch",
},
},
`Non Rules Diff`: {
old: Object{Rules: Rules{Verbs: "list"}, Other: Other{Foo: "bar"}},
new: Object{Rules: Rules{Verbs: "list"}, Other: Other{Foo: "boo"}},
update: config.UpdateSetting{Fields: []config.FieldType{"metadata"}, IncludeDiff: true},
expected: ExpectedDiff{},
},
}
for name, test := range tests {
name, test := name, test
t.Run(name, func(t *testing.T) {
if actual := Diff(test.old, test.new); actual != test.expected.MockDiff() {
if actual := Diff(test.old, test.new, test.update); actual != test.expected.MockDiff() {
t.Errorf("expected: %+v != actual: %+v\n", test.expected.MockDiff(), actual)
}
})
Expand Down
Loading

0 comments on commit 889dd2a

Please sign in to comment.