Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Commit

Permalink
fix: support overriding slack specific settings (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Matyushentsev committed Jan 24, 2020
1 parent 3e98b47 commit 49bc7f6
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage:
status:
patch: off
project:
default:
threshold: 2
18 changes: 13 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func newCommand() *cobra.Command {
}

var cancelPrev context.CancelFunc
watchConfig(k8sClient, namespace, func(triggers map[string]triggers.Trigger, notifiers map[string]notifiers.Notifier, contextVals map[string]string) error {
watchConfig(context.Background(), k8sClient, namespace, func(triggers map[string]triggers.Trigger, notifiers map[string]notifiers.Notifier, contextVals map[string]string) error {
if cancelPrev != nil {
log.Info("Settings had been updated. Restarting controller...")
cancelPrev()
Expand Down Expand Up @@ -142,7 +142,7 @@ func parseConfig(configData map[string]string, notifiersData []byte) (map[string
return t, notifiers.GetAll(notifiersConfig), cfg.Context, nil
}

func watchConfig(clientset kubernetes.Interface, namespace string, callback func(map[string]triggers.Trigger, map[string]notifiers.Notifier, map[string]string) error) {
func watchConfig(ctx context.Context, clientset kubernetes.Interface, namespace string, callback func(map[string]triggers.Trigger, map[string]notifiers.Notifier, map[string]string) error) {
var secret *v1.Secret
var configMap *v1.ConfigMap
lock := &sync.Mutex{}
Expand Down Expand Up @@ -197,10 +197,10 @@ func watchConfig(clientset kubernetes.Interface, namespace string, callback func
onSecretChanged(newObj)
},
})
go secretInformer.Run(context.Background().Done())
go cmInformer.Run(context.Background().Done())
go secretInformer.Run(ctx.Done())
go cmInformer.Run(ctx.Done())

if !cache.WaitForCacheSync(context.Background().Done(), cmInformer.HasSynced, secretInformer.HasSynced) {
if !cache.WaitForCacheSync(ctx.Done(), cmInformer.HasSynced, secretInformer.HasSynced) {
log.Fatal(errors.New("timed out waiting for caches to sync"))
}
}
Expand Down Expand Up @@ -242,6 +242,14 @@ func (cfg *config) merge(other *config) *config {
if existing, ok := templatesMap[item.Name]; ok {
existing.Body = coalesce(item.Body, existing.Body)
existing.Title = coalesce(item.Title, existing.Title)
if item.Slack != nil {
if existing.Slack == nil {
existing.Slack = &notifiers.SlackSpecific{Blocks: item.Slack.Blocks, Attachments: item.Slack.Attachments}
} else {
existing.Slack.Attachments = coalesce(item.Slack.Attachments, existing.Slack.Attachments)
existing.Slack.Blocks = coalesce(item.Slack.Blocks, existing.Slack.Blocks)
}
}
templatesMap[item.Name] = existing
} else {
templatesMap[item.Name] = item
Expand Down
148 changes: 148 additions & 0 deletions cmd/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package main

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/utils/pointer"

"github.com/argoproj-labs/argocd-notifications/notifiers"
"github.com/argoproj-labs/argocd-notifications/triggers"
)

func TestMergeConfigTemplate(t *testing.T) {
cfg := config{
Templates: []triggers.NotificationTemplate{{
Name: "foo",
Notification: notifiers.Notification{
Body: "the body",
Title: "the title",
Slack: &notifiers.SlackSpecific{
Attachments: "attachments",
},
},
}},
}
merged := cfg.merge(&config{
Templates: []triggers.NotificationTemplate{{
Name: "foo",
Notification: notifiers.Notification{
Body: "new body",
Slack: &notifiers.SlackSpecific{
Blocks: "blocks",
},
},
}, {
Name: "bar",
Notification: notifiers.Notification{
Body: "the body",
Title: "the title",
},
}},
})
assert.ElementsMatch(t, merged.Templates, []triggers.NotificationTemplate{{
Name: "foo",
Notification: notifiers.Notification{
Title: "the title",
Body: "new body",
Slack: &notifiers.SlackSpecific{
Attachments: "attachments",
Blocks: "blocks",
},
},
}, {
Name: "bar",
Notification: notifiers.Notification{
Body: "the body",
Title: "the title",
},
}})
}

func TestMergeConfigTriggers(t *testing.T) {
cfg := config{
Triggers: []triggers.NotificationTrigger{{
Name: "foo",
Template: "template name",
Condition: "the condition",
Enabled: pointer.BoolPtr(false),
}},
}

merged := cfg.merge(&config{
Triggers: []triggers.NotificationTrigger{{
Name: "foo",
Condition: "new condition",
Enabled: pointer.BoolPtr(true),
}, {
Name: "bar",
Condition: "the condition",
Template: "the template",
Enabled: pointer.BoolPtr(true),
}},
})

assert.ElementsMatch(t, merged.Triggers, []triggers.NotificationTrigger{{
Name: "foo",
Template: "template name",
Condition: "new condition",
Enabled: pointer.BoolPtr(true),
}, {
Name: "bar",
Condition: "the condition",
Template: "the template",
Enabled: pointer.BoolPtr(true),
}})
}

func TestWatchConfig(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
configMap := &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: configMapName,
Namespace: "default",
},
Data: map[string]string{
"config.yaml": `
triggers:
- name: on-sync-status-unknown
template: app-sync-status
enabled: true
templates:
- name: app-sync-status
title: updated
body: updated"`,
},
}
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: "default",
},
Data: map[string][]byte{
"notifiers.yaml": []byte(`slack: {token: my-token}`),
},
}

triggersMap := make(map[string]triggers.Trigger)
notifiersMap := make(map[string]notifiers.Notifier)
clientset := fake.NewSimpleClientset(configMap, secret)
watchConfig(ctx, clientset, "default", func(t map[string]triggers.Trigger, n map[string]notifiers.Notifier, ctx map[string]string) error {
triggersMap = t
notifiersMap = n
return nil
})

assert.Len(t, triggersMap, 1)

_, ok := triggersMap["on-sync-status-unknown"]
assert.True(t, ok)

_, ok = notifiersMap["slack"]
assert.True(t, ok)
}
1 change: 0 additions & 1 deletion notifiers/notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type SlackSpecific struct {
}

type Notification struct {
Name string `json:"name,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"body,omitempty"`
Slack *SlackSpecific
Expand Down

0 comments on commit 49bc7f6

Please sign in to comment.