Skip to content

Commit

Permalink
Merge pull request #245 from dmitriishaburov/slack-app-support
Browse files Browse the repository at this point in the history
Add support for Slack app
  • Loading branch information
stefanprodan authored Oct 27, 2021
2 parents 3f53986 + c65885f commit 4e96e0d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
38 changes: 37 additions & 1 deletion docs/spec/v1beta1/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,42 @@ The provider will send the following labels for the event.
| namespace | The namespace of the involved object associated with the event |


### Slack App

It is possible to use Slack Apps bot integration to send messages. To obtain bot token, follow the [Slack's guide](https://api.slack.com/bot-users).

Differences from Slack [webhook method](#notifications):

* Possible to use single credentials to post into different channels (integration should be added to each channel)
* All messages would be posted from app username, losing the `helm-controller`, `source-controller` usernames

In that case, Slack secret should contain URL of [chat.postMessage](https://api.slack.com/methods/chat.postMessage) method and your Slack bot token (starts with `xoxb-`):

```shell
kubectl create secret generic slack-token \
--from-literal=address=https://slack.com/api/chat.postMessage \
--from-literal=token=xoxb-YOUR-TOKEN
```

Then reference this secret in `spec.secretRef`:

```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
name: slack
namespace: default
spec:
type: slack
channel: general
# HTTP(S) proxy (optional)
proxy: https://proxy.corp:8080
# secret containing Slack API address and token
secretRef:
name: slack-token
```


### Git commit status

The GitHub, GitLab, Bitbucket, and Azure DevOps provider will write to the
Expand Down Expand Up @@ -366,7 +402,7 @@ spec:

The provider type can be: `github`, `gitlab`, `bitbucket` or `azuredevops`.

For bitbucket, the token should contain the username and [app password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/#Create-an-app-password)
For bitbucket, the token should contain the username and [app password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/#Create-an-app-password)
in the format `<username>:<password>`. The app password should have `Repositories (Read/Write)` permission.

You can create the secret using this command:
Expand Down
2 changes: 1 addition & 1 deletion internal/notifier/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (f Factory) Notifier(provider string) (Interface, error) {
case v1beta1.GenericProvider:
n, err = NewForwarder(f.URL, f.ProxyURL, f.CertPool)
case v1beta1.SlackProvider:
n, err = NewSlack(f.URL, f.ProxyURL, f.CertPool, f.Username, f.Channel)
n, err = NewSlack(f.URL, f.ProxyURL, f.Token, f.CertPool, f.Username, f.Channel)
case v1beta1.DiscordProvider:
n, err = NewDiscord(f.URL, f.ProxyURL, f.Username, f.Channel)
case v1beta1.RocketProvider:
Expand Down
11 changes: 9 additions & 2 deletions internal/notifier/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ import (
"strings"

"github.com/fluxcd/pkg/runtime/events"
"github.com/hashicorp/go-retryablehttp"
)

// Slack holds the hook URL
type Slack struct {
URL string
ProxyURL string
Token string
Username string
Channel string
CertPool *x509.CertPool
Expand Down Expand Up @@ -60,7 +62,7 @@ type SlackField struct {
}

// NewSlack validates the Slack URL and returns a Slack object
func NewSlack(hookURL string, proxyURL string, certPool *x509.CertPool, username string, channel string) (*Slack, error) {
func NewSlack(hookURL string, proxyURL string, token string, certPool *x509.CertPool, username string, channel string) (*Slack, error) {
_, err := url.ParseRequestURI(hookURL)
if err != nil {
return nil, fmt.Errorf("invalid Slack hook URL %s", hookURL)
Expand All @@ -71,6 +73,7 @@ func NewSlack(hookURL string, proxyURL string, certPool *x509.CertPool, username
Username: username,
URL: hookURL,
ProxyURL: proxyURL,
Token: token,
CertPool: certPool,
}, nil
}
Expand Down Expand Up @@ -114,7 +117,11 @@ func (s *Slack) Post(event events.Event) error {

payload.Attachments = []SlackAttachment{a}

err := postMessage(s.URL, s.ProxyURL, s.CertPool, payload)
err := postMessage(s.URL, s.ProxyURL, s.CertPool, payload, func(request *retryablehttp.Request) {
if s.Token != "" {
request.Header.Add("Authorization", "Bearer "+s.Token)
}
})
if err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/notifier/slack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ func TestSlack_Post(t *testing.T) {
}))
defer ts.Close()

slack, err := NewSlack(ts.URL, "", nil, "", "test")
slack, err := NewSlack(ts.URL, "", "", nil, "", "test")
require.NoError(t, err)

err = slack.Post(testEvent())
require.NoError(t, err)
}

func TestSlack_PostUpdate(t *testing.T) {
slack, err := NewSlack("http://localhost", "", nil, "", "test")
slack, err := NewSlack("http://localhost", "", "", nil, "", "test")
require.NoError(t, err)

event := testEvent()
Expand Down

0 comments on commit 4e96e0d

Please sign in to comment.