Skip to content

Commit f242620

Browse files
authored
make the annotation key prefix configurable (#157)
This is intended to make the prefix configurable for projects using this controller which are not in the Argo ecosystem. This allows such projects to use an annotation key that is consistent with the conventions of their project. Signed-off-by: Your <[email protected]>
1 parent 2965063 commit f242620

File tree

6 files changed

+51
-18
lines changed

6 files changed

+51
-18
lines changed

examples/certmanager/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ The example demonstrates how Notifications Engine can be used to implement noti
66

77
The machinery required for controller implementation is provided by [pkg/controller](../../pkg/controller) and [pkg/api](../../pkg/api) packages.
88

9+
* You may optionally set the annotation prefix using the `subscriptions.SetAnnotationPrefix` function. This defaults to `"notifications.argoproj.io"`.
10+
11+
```golang
12+
subscriptions.SetAnnotationPrefix("example.prefix.io")
13+
```
14+
915
* The first step is to write the boilerplate code required to get Kubernetes REST config so we can talk to API server.
1016

1117
* Next create `ConfigMap` and `Secret` informers and use it to initialize `api.Factory`:

examples/certmanager/controller/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ func main() {
3434
var command = cobra.Command{
3535
Use: "controller",
3636
Run: func(c *cobra.Command, args []string) {
37+
// Optionally set the annotations prefix
38+
// subscriptions.SetAnnotationPrefix("example.prefix.io")
39+
3740
// Get Kubernetes REST Config and current Namespace so we can talk to Kubernetes
3841
restConfig, err := clientConfig.ClientConfig()
3942
if err != nil {

pkg/controller/controller_test.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ import (
2929
)
3030

3131
var (
32-
testGVR = schema.GroupVersionResource{Group: "argoproj.io", Resource: "applications", Version: "v1alpha1"}
33-
testNamespace = "default"
34-
logEntry = logrus.NewEntry(logrus.New())
32+
testGVR = schema.GroupVersionResource{Group: "argoproj.io", Resource: "applications", Version: "v1alpha1"}
33+
testNamespace = "default"
34+
logEntry = logrus.NewEntry(logrus.New())
35+
notifiedAnnotationKey = subscriptions.NotifiedAnnotationKey()
3536
)
3637

3738
func mustToJson(val interface{}) string {
@@ -120,7 +121,7 @@ func TestSendsNotificationIfTriggered(t *testing.T) {
120121

121122
assert.NoError(t, err)
122123

123-
state := NewState(annotations[NotifiedAnnotationKey])
124+
state := NewState(annotations[notifiedAnnotationKey])
124125
assert.NotNil(t, state[StateItemKey("mock", triggers.ConditionResult{}, services.Destination{Service: "mock", Recipient: "recipient"})])
125126
assert.Equal(t, app.Object, receivedObj)
126127
}
@@ -132,7 +133,7 @@ func TestDoesNotSendNotificationIfAnnotationPresent(t *testing.T) {
132133
_ = state.SetAlreadyNotified("my-trigger", triggers.ConditionResult{}, services.Destination{Service: "mock", Recipient: "recipient"}, true)
133134
app := newResource("test", withAnnotations(map[string]string{
134135
subscriptions.SubscribeAnnotationKey("my-trigger", "mock"): "recipient",
135-
NotifiedAnnotationKey: mustToJson(state),
136+
notifiedAnnotationKey: mustToJson(state),
136137
}))
137138
ctrl, api, err := newController(t, ctx, newFakeClient(app))
138139
assert.NoError(t, err)
@@ -154,7 +155,7 @@ func TestRemovesAnnotationIfNoTrigger(t *testing.T) {
154155
_ = state.SetAlreadyNotified("my-trigger", triggers.ConditionResult{}, services.Destination{Service: "mock", Recipient: "recipient"}, true)
155156
app := newResource("test", withAnnotations(map[string]string{
156157
subscriptions.SubscribeAnnotationKey("my-trigger", "mock"): "recipient",
157-
NotifiedAnnotationKey: mustToJson(state),
158+
notifiedAnnotationKey: mustToJson(state),
158159
}))
159160
ctrl, api, err := newController(t, ctx, newFakeClient(app))
160161
assert.NoError(t, err)
@@ -166,7 +167,7 @@ func TestRemovesAnnotationIfNoTrigger(t *testing.T) {
166167
logEntry.Errorf("Failed to process: %v", err)
167168
}
168169
assert.NoError(t, err)
169-
state = NewState(annotations[NotifiedAnnotationKey])
170+
state = NewState(annotations[notifiedAnnotationKey])
170171
assert.Empty(t, state)
171172
}
172173

@@ -179,7 +180,7 @@ func TestUpdatedAnnotationsSavedAsPatch(t *testing.T) {
179180

180181
app := newResource("test", withAnnotations(map[string]string{
181182
subscriptions.SubscribeAnnotationKey("my-trigger", "mock"): "recipient",
182-
NotifiedAnnotationKey: mustToJson(state),
183+
notifiedAnnotationKey: mustToJson(state),
183184
}))
184185

185186
patchCh := make(chan []byte)
@@ -202,7 +203,7 @@ func TestUpdatedAnnotationsSavedAsPatch(t *testing.T) {
202203
patch := map[string]interface{}{}
203204
err = json.Unmarshal(patchData, &patch)
204205
assert.NoError(t, err)
205-
val, ok, err := unstructured.NestedFieldNoCopy(patch, "metadata", "annotations", NotifiedAnnotationKey)
206+
val, ok, err := unstructured.NestedFieldNoCopy(patch, "metadata", "annotations", notifiedAnnotationKey)
206207
assert.NoError(t, err)
207208
assert.True(t, ok)
208209
assert.Nil(t, val)

pkg/controller/state.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
const (
1717
notifiedHistoryMaxSize = 100
18-
NotifiedAnnotationKey = "notified." + subscriptions.AnnotationPrefix
1918
)
2019

2120
func StateItemKey(trigger string, conditionResult triggers.ConditionResult, dest services.Destination) string {
@@ -67,6 +66,7 @@ func (s NotificationsState) SetAlreadyNotified(trigger string, result triggers.C
6766
func (s NotificationsState) Persist(res metav1.Object) (map[string]string, error) {
6867
s.truncate(notifiedHistoryMaxSize)
6968

69+
notifiedAnnotationKey := subscriptions.NotifiedAnnotationKey()
7070
annotations := map[string]string{}
7171

7272
if res.GetAnnotations() != nil {
@@ -76,13 +76,13 @@ func (s NotificationsState) Persist(res metav1.Object) (map[string]string, error
7676
}
7777

7878
if len(s) == 0 {
79-
delete(annotations, NotifiedAnnotationKey)
79+
delete(annotations, notifiedAnnotationKey)
8080
} else {
8181
stateJson, err := json.Marshal(s)
8282
if err != nil {
8383
return nil, err
8484
}
85-
annotations[NotifiedAnnotationKey] = string(stateJson)
85+
annotations[notifiedAnnotationKey] = string(stateJson)
8686
}
8787

8888
return annotations, nil
@@ -100,8 +100,9 @@ func NewState(val string) NotificationsState {
100100
}
101101

102102
func NewStateFromRes(res metav1.Object) NotificationsState {
103+
notifiedAnnotationKey := subscriptions.NotifiedAnnotationKey()
103104
if annotations := res.GetAnnotations(); annotations != nil {
104-
return NewState(annotations[NotifiedAnnotationKey])
105+
return NewState(annotations[notifiedAnnotationKey])
105106
}
106107
return NotificationsState{}
107108
}

pkg/subscriptions/annotations.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,20 @@ import (
1010
"github.com/argoproj/notifications-engine/pkg/services"
1111
)
1212

13-
const (
14-
AnnotationPrefix = "notifications.argoproj.io"
13+
var (
14+
annotationPrefix = "notifications.argoproj.io"
1515
)
1616

17+
// SetAnnotationPrefix sets the annotationPrefix to the provided string.
18+
// defaults to "notifications.argoproj.io"
19+
func SetAnnotationPrefix(prefix string) {
20+
annotationPrefix = prefix
21+
}
22+
23+
func NotifiedAnnotationKey() string {
24+
return fmt.Sprintf("notified.%s", annotationPrefix)
25+
}
26+
1727
func parseRecipients(v string) []string {
1828
var recipients []string
1929
for _, recipient := range strings.Split(v, ";") {
@@ -26,7 +36,7 @@ func parseRecipients(v string) []string {
2636
}
2737

2838
func SubscribeAnnotationKey(trigger string, service string) string {
29-
return fmt.Sprintf("%s/subscribe.%s.%s", AnnotationPrefix, trigger, service)
39+
return fmt.Sprintf("%s/subscribe.%s.%s", annotationPrefix, trigger, service)
3040
}
3141

3242
type Annotations map[string]string
@@ -51,8 +61,8 @@ type Destination struct {
5161
}
5262

5363
func (a Annotations) iterate(callback func(trigger string, service string, recipients []string, key string)) {
54-
prefix := AnnotationPrefix + "/subscribe."
55-
altPrefix := AnnotationPrefix + "/subscriptions"
64+
prefix := annotationPrefix + "/subscribe."
65+
altPrefix := annotationPrefix + "/subscriptions"
5666
var recipients []string
5767
for k, v := range a {
5868
switch {

pkg/subscriptions/annotations_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,15 @@ func TestUnsubscribe(t *testing.T) {
257257
_, ok := a["notifications.argoproj.io/subscribe.my-trigger.slack"]
258258
assert.False(t, ok)
259259
}
260+
261+
func TestSetAnnotationPrefix(t *testing.T) {
262+
origPrefix := annotationPrefix
263+
defer func() {
264+
annotationPrefix = origPrefix
265+
}()
266+
267+
SetAnnotationPrefix("test.prefix")
268+
269+
assert.Equal(t, "test.prefix", annotationPrefix)
270+
assert.Equal(t, "notified.test.prefix", NotifiedAnnotationKey())
271+
}

0 commit comments

Comments
 (0)