-
Notifications
You must be signed in to change notification settings - Fork 292
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit, - enables filtering of events based on annotations present in objects at run time. - annotation `botkube.io/disable: true` disables event notifications for the annotated object - annotation `botkube.io/channel: <channel_name>` sends events notifications of the annotated object to the mentioned channel. - adds func `ExtractAnnotations()`. It extract annotations from Event.InvolvedObject and adds them to event.Metadata.Annotations - implements individual actions using internal functions. - adds unit tests for internal functions. - replaces Init() with InitialiseKubeClient() to decouple config.yaml and KubeClinet dependencies from unit testing
- Loading branch information
Showing
7 changed files
with
326 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
pkg/filterengine/filters/object-annotation-filter/object_annotation_checker.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package filters | ||
|
||
import ( | ||
"github.com/infracloudio/botkube/pkg/events" | ||
"github.com/infracloudio/botkube/pkg/filterengine" | ||
log "github.com/infracloudio/botkube/pkg/logging" | ||
"github.com/infracloudio/botkube/pkg/utils" | ||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
const ( | ||
// DisableAnnotation is the object disable annotation | ||
DisableAnnotation string = "botkube.io/disable" | ||
// ChannelAnnotation is the multichannel support annotation | ||
ChannelAnnotation string = "botkube.io/channel" | ||
) | ||
|
||
// ObjectAnnotationChecker add recommendations to the event object if pod created without any labels | ||
type ObjectAnnotationChecker struct { | ||
Description string | ||
} | ||
|
||
// Register filter | ||
func init() { | ||
filterengine.DefaultFilterEngine.Register(ObjectAnnotationChecker{ | ||
Description: "Checks if annotations botkube.io/* present in object specs and filters them.", | ||
}) | ||
} | ||
|
||
// Run filters and modifies event struct | ||
func (f ObjectAnnotationChecker) Run(object interface{}, event *events.Event) { | ||
|
||
// get objects metadata | ||
obj := utils.GetObjectMetaData(object) | ||
|
||
// if eventObj, ok := object.(*apiV1.Event); ok { | ||
// // check annotations of the involved object | ||
// eventObj = utils.ExtractAnnotaions(eventObj) | ||
// obj = eventObj.ObjectMeta | ||
// log.Logger.Debugf("Event Object >>> %+v",eventObj) | ||
// } | ||
|
||
// Check annotations in object | ||
if isObjectNotifDisabled(obj) { | ||
event.Skip = true | ||
log.Logger.Debug("Object Notification Disable through annotations") | ||
} | ||
|
||
if channel, ok := reconfigureChannel(obj); ok { | ||
event.Channel = channel | ||
log.Logger.Debugf("Redirecting Event Notifications to channel: %s", channel) | ||
} | ||
|
||
log.Logger.Debug("Object annotations filter successful!") | ||
} | ||
|
||
// Describe filter | ||
func (f ObjectAnnotationChecker) Describe() string { | ||
return f.Description | ||
} | ||
|
||
// isObjectNotifDisabled checks annotation botkube.io/disable | ||
// annotation botkube.io/disable disables the event notifications from objects | ||
func isObjectNotifDisabled(obj metaV1.ObjectMeta) bool { | ||
|
||
if obj.Annotations[DisableAnnotation] == "true" { | ||
log.Logger.Debug("Skipping Disabled Event Notifications!") | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
// reconfigureChannel checks annotation botkube.io/channel | ||
// annotation botkube.io/channel directs event notifications to channels | ||
// based on the channel names present in them | ||
// Note: Add botkube app into the desired channel to receive notifications | ||
func reconfigureChannel(obj metaV1.ObjectMeta) (string, bool) { | ||
// redirect messages to channels based on annotations | ||
if channel, ok := obj.Annotations[ChannelAnnotation]; ok { | ||
return channel, true | ||
} | ||
return "", false | ||
} |
50 changes: 50 additions & 0 deletions
50
pkg/filterengine/filters/object-annotation-filter/object_annotation_checker_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package filters | ||
|
||
import ( | ||
"testing" | ||
|
||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func TestIsObjectNotifDisabled(t *testing.T) { | ||
tests := map[string]struct { | ||
annotaion metaV1.ObjectMeta | ||
expected bool | ||
}{ | ||
`Empty ObjectMeta`: {metaV1.ObjectMeta{}, false}, | ||
`ObjectMeta with some annotations`: {metaV1.ObjectMeta{Annotations: map[string]string{"foo": "bar"}}, false}, | ||
`ObjectMeta with disable false`: {metaV1.ObjectMeta{Annotations: map[string]string{"botkube.io/disable": "false"}}, false}, | ||
`ObjectMeta with disable true`: {metaV1.ObjectMeta{Annotations: map[string]string{"botkube.io/disable": "true"}}, true}, | ||
} | ||
for name, test := range tests { | ||
name, test := name, test | ||
t.Run(name, func(t *testing.T) { | ||
if actual := isObjectNotifDisabled(test.annotaion); actual != test.expected { | ||
t.Errorf("expected: %+v != actual: %+v\n", test.expected, actual) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestReconfigureChannel(t *testing.T) { | ||
tests := map[string]struct { | ||
objectMeta metaV1.ObjectMeta | ||
expectedChannel string | ||
expectedBool bool | ||
}{ | ||
`Empty ObjectMeta`: {metaV1.ObjectMeta{}, "", false}, | ||
`ObjectMeta with some annotations`: {metaV1.ObjectMeta{Annotations: map[string]string{"foo": "bar"}}, "", false}, | ||
`ObjectMeta with channel ""`: {metaV1.ObjectMeta{Annotations: map[string]string{"botkube.io/channel": ""}}, "", false}, | ||
`ObjectMeta with channel foo-channel`: {metaV1.ObjectMeta{Annotations: map[string]string{"botkube.io/channel": "foo-channel"}}, "foo-channel", true}, | ||
} | ||
for name, test := range tests { | ||
name, test := name, test | ||
t.Run(name, func(t *testing.T) { | ||
if actualChannel, actualBool := reconfigureChannel(test.objectMeta); actualBool != test.expectedBool { | ||
if actualChannel != test.expectedChannel { | ||
t.Errorf("expected: %+v != actual: %+v\n", test.expectedChannel, actualChannel) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.