Merge pull request #252 from Alan01252/feature/OpsAndMeta
Add opsgenie provider
This commit is contained in:
commit
0e55a23de7
|
@ -28,7 +28,7 @@ const (
|
|||
// ProviderSpec defines the desired state of Provider
|
||||
type ProviderSpec struct {
|
||||
// Type of provider
|
||||
// +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab;bitbucket;azuredevops;googlechat;webex;sentry;azureeventhub;telegram;lark;matrix;
|
||||
// +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab;bitbucket;azuredevops;googlechat;webex;sentry;azureeventhub;telegram;lark;matrix;opsgenie;
|
||||
// +required
|
||||
Type string `json:"type"`
|
||||
|
||||
|
@ -80,6 +80,7 @@ const (
|
|||
TelegramProvider string = "telegram"
|
||||
LarkProvider string = "lark"
|
||||
Matrix string = "matrix"
|
||||
OpsgenieProvider string = "opsgenie"
|
||||
)
|
||||
|
||||
// ProviderStatus defines the observed state of Provider
|
||||
|
|
|
@ -90,6 +90,7 @@ spec:
|
|||
- telegram
|
||||
- lark
|
||||
- matrix
|
||||
- opsgenie
|
||||
type: string
|
||||
username:
|
||||
description: Bot username for this provider
|
||||
|
|
|
@ -9,7 +9,7 @@ Spec:
|
|||
```go
|
||||
type ProviderSpec struct {
|
||||
// Type of provider
|
||||
// +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab;bitbucket;azuredevops;googlechat;webex;sentry;azureeventhub;telegram;lark;matrix;
|
||||
// +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab;bitbucket;azuredevops;googlechat;webex;sentry;azureeventhub;telegram;lark;matrix;opsgenie
|
||||
// +required
|
||||
Type string `json:"type"`
|
||||
|
||||
|
@ -56,6 +56,7 @@ Notification providers:
|
|||
* Matrix
|
||||
* Azure Event Hub
|
||||
* Generic webhook
|
||||
* Opsgenie
|
||||
|
||||
Git commit status providers:
|
||||
|
||||
|
@ -225,7 +226,7 @@ Note that `spec.channel` holds the room id.
|
|||
|
||||
### Lark
|
||||
|
||||
For sending notifications to Lark, You will have to
|
||||
For sending notifications to Lark, you will have to
|
||||
[add a bot to the group](https://www.larksuite.com/hc/en-US/articles/360048487736-Bot-Use-bots-in-groups#III.%20How%20to%20configure%20custom%20bots%20in%20a%20group%C2%A0)
|
||||
and set up a webhook for the bot. This serves as the address field in the secret:
|
||||
|
||||
|
@ -248,6 +249,36 @@ spec:
|
|||
name: lark-token
|
||||
```
|
||||
|
||||
|
||||
### Opsgenie
|
||||
|
||||
For sending notifications to Opsgenie, you will have to
|
||||
[add a REST api integration](https://support.atlassian.com/opsgenie/docs/create-a-default-api-integration/)
|
||||
and setup a api integration for notification provider.
|
||||
|
||||
A secret needs to be generated with the api key given by Opsgenie for the integration
|
||||
|
||||
```shell
|
||||
kubectl create secret generic opsgenie-token \
|
||||
--from-literal=token=<opsgenie-api-key>
|
||||
```
|
||||
|
||||
Then reference the secret in `spec.secretRef`:
|
||||
|
||||
```yaml
|
||||
apiVersion: notification.toolkit.fluxcd.io/v1beta1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: opsgenie
|
||||
namespace: default
|
||||
spec:
|
||||
type: opsgenie
|
||||
address: https://api.opsgenie.com/v2/alerts
|
||||
secretRef:
|
||||
name: opsgenie-token
|
||||
```
|
||||
|
||||
|
||||
### Git commit status
|
||||
|
||||
The GitHub, GitLab, Bitbucket, and Azure DevOps provider will write to the
|
||||
|
@ -317,6 +348,19 @@ data:
|
|||
token: <username>:<app-password>
|
||||
```
|
||||
|
||||
|
||||
Opsgenie uses an api key to authenticate [api key](https://support.atlassian.com/opsgenie/docs/api-key-management/).
|
||||
The providers require a secret in the same format, with the api key as the value for the token key:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: api-token
|
||||
namespace: default
|
||||
data:
|
||||
token: <api-key>
|
||||
```
|
||||
### Azure Event Hub
|
||||
|
||||
The Azure Event Hub supports two authentication methods, [JWT](https://docs.microsoft.com/en-us/azure/event-hubs/authenticate-application)
|
||||
|
|
|
@ -83,6 +83,8 @@ func (f Factory) Notifier(provider string) (Interface, error) {
|
|||
n, err = NewLark(f.URL)
|
||||
case v1beta1.Matrix:
|
||||
n, err = NewMatrix(f.URL, f.Token, f.Channel)
|
||||
case v1beta1.OpsgenieProvider:
|
||||
n, err = NewOpsgenie(f.URL, f.ProxyURL, f.CertPool, f.Token)
|
||||
default:
|
||||
err = fmt.Errorf("provider %s not supported", provider)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright 2020 The Flux authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notifier
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/fluxcd/pkg/runtime/events"
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
)
|
||||
|
||||
type Opsgenie struct {
|
||||
URL string
|
||||
ProxyURL string
|
||||
CertPool *x509.CertPool
|
||||
ApiKey string
|
||||
}
|
||||
|
||||
type OpsgenieAlert struct {
|
||||
Message string `json:"message"`
|
||||
Description string `json:"description"`
|
||||
Details map[string]string `json:"details"`
|
||||
}
|
||||
|
||||
// NewSlack validates the Slack URL and returns a Slack object
|
||||
func NewOpsgenie(hookURL string, proxyURL string, certPool *x509.CertPool, token string) (*Opsgenie, error) {
|
||||
_, err := url.ParseRequestURI(hookURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid Opsgenie hook URL %s", hookURL)
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
return nil, errors.New("empty Opsgenie apikey/token")
|
||||
}
|
||||
|
||||
return &Opsgenie{
|
||||
URL: hookURL,
|
||||
ProxyURL: proxyURL,
|
||||
CertPool: certPool,
|
||||
ApiKey: token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Post opsgenie alert message
|
||||
func (s *Opsgenie) Post(event events.Event) error {
|
||||
// Skip any update events
|
||||
if isCommitStatus(event.Metadata, "update") {
|
||||
return nil
|
||||
}
|
||||
|
||||
payload := OpsgenieAlert{
|
||||
Message: event.InvolvedObject.Kind + "/" + event.InvolvedObject.Name,
|
||||
Description: event.Message,
|
||||
Details: event.Metadata,
|
||||
}
|
||||
|
||||
err := postMessage(s.URL, s.ProxyURL, s.CertPool, payload, func(req *retryablehttp.Request) {
|
||||
req.Header.Set("Authorization", "GenieKey "+s.ApiKey)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("postMessage failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2020 The Flux authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notifier
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOpsgenie_Post(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
b, err := ioutil.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var payload OpsgenieAlert
|
||||
err = json.Unmarshal(b, &payload)
|
||||
require.NoError(t, err)
|
||||
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
opsgenie, err := NewOpsgenie(ts.URL, "", nil, "token")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = opsgenie.Post(testEvent())
|
||||
require.NoError(t, err)
|
||||
}
|
Loading…
Reference in New Issue