mirror of
https://github.com/kyverno/policy-reporter.git
synced 2024-12-14 11:57:32 +00:00
parent
dc88751e3e
commit
591e1fc2eb
15 changed files with 478 additions and 10 deletions
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
## 0.21.0
|
||||
|
||||
* New Target MS Teams
|
||||
|
||||
## 0.20.2
|
||||
|
||||
* Policy Reporter UI update
|
||||
|
|
24
README.md
24
README.md
|
@ -13,6 +13,7 @@ This project is in an early stage. Please let me know if anything did not work a
|
|||
* [Elasticsearch](#installation-with-elasticsearch)
|
||||
* [Slack](#installation-with-slack)
|
||||
* [Discord](#installation-with-discord)
|
||||
* [MS Teams](#installation-with-ms-teams)
|
||||
* [Customization](#customization)
|
||||
* [Configure Policy Priorities](#configure-policy-priorities)
|
||||
* [Configure Monitoring](#monitoring)
|
||||
|
@ -134,6 +135,29 @@ target:
|
|||
|
||||
![Discord](https://github.com/fjogeleit/policy-reporter/blob/main/docs/images/discord.png?raw=true)
|
||||
|
||||
### Installation with MS Teams
|
||||
|
||||
```bash
|
||||
helm install policy-reporter policy-reporter/policy-reporter --set target.teams.webhook=http://hook.teams -n policy-reporter --create-namespace
|
||||
```
|
||||
|
||||
#### Additional configurations for MS Teams
|
||||
|
||||
* Configure `target.teams.minimumPriority` to send only results with the configured minimumPriority or above, empty means all results. (info < warning < error)
|
||||
* Configure `target.teams.skipExistingOnStartup` to skip all results who already existed before the PolicyReporter started (default: `true`).
|
||||
|
||||
```yaml
|
||||
target:
|
||||
teams:
|
||||
webhook: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
![MS Teams](https://github.com/fjogeleit/policy-reporter/blob/main/docs/images/ms-teams.png?raw=true)
|
||||
|
||||
### Customization
|
||||
|
||||
You can combine multiple targets by setting the required `host` or `webhook` configuration for your targets of choice. For all possible configurations checkout the `./charts/policy-reporter/values.yaml` to change any available configuration.
|
||||
|
|
|
@ -5,8 +5,8 @@ description: |
|
|||
It creates Prometheus Metrics and can send rule validation events to different targets like Loki, Elasticsearch, Slack or Discord
|
||||
|
||||
type: application
|
||||
version: 0.20.2
|
||||
appVersion: 0.12.0
|
||||
version: 0.21.0
|
||||
appVersion: 0.13.0
|
||||
|
||||
dependencies:
|
||||
- name: monitoring
|
||||
|
|
|
@ -18,4 +18,9 @@ slack:
|
|||
discord:
|
||||
webhook: {{ .Values.target.discord.webhook | quote }}
|
||||
minimumPriority: {{ .Values.target.discord.minimumPriority | quote }}
|
||||
skipExistingOnStartup: {{ .Values.target.discord.skipExistingOnStartup }}
|
||||
skipExistingOnStartup: {{ .Values.target.discord.skipExistingOnStartup }}
|
||||
|
||||
teams:
|
||||
webhook: {{ .Values.target.teams.webhook | quote }}
|
||||
minimumPriority: {{ .Values.target.teams.minimumPriority | quote }}
|
||||
skipExistingOnStartup: {{ .Values.target.teams.skipExistingOnStartup }}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
image:
|
||||
repository: fjogeleit/policy-reporter
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 0.12.0
|
||||
tag: 0.13.0
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
|
@ -139,6 +139,14 @@ target:
|
|||
# Skip already existing PolicyReportResults on startup
|
||||
skipExistingOnStartup: true
|
||||
|
||||
teams:
|
||||
# teams webhook address
|
||||
webhook: ""
|
||||
# minimum priority "" < info < warning < error
|
||||
minimumPriority: ""
|
||||
# Skip already existing PolicyReportResults on startup
|
||||
skipExistingOnStartup: true
|
||||
|
||||
# Node labels for pod assignment
|
||||
# ref: https://kubernetes.io/docs/user-guide/node-selection/
|
||||
nodeSelector: {}
|
||||
|
|
BIN
docs/images/ms-teams.png
Normal file
BIN
docs/images/ms-teams.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
|
@ -30,6 +30,13 @@ type Discord struct {
|
|||
MinimumPriority string `mapstructure:"minimumPriority"`
|
||||
}
|
||||
|
||||
// Teams configuration
|
||||
type Teams struct {
|
||||
Webhook string `mapstructure:"webhook"`
|
||||
SkipExisting bool `mapstructure:"skipExistingOnStartup"`
|
||||
MinimumPriority string `mapstructure:"minimumPriority"`
|
||||
}
|
||||
|
||||
// Server configuration
|
||||
type API struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
|
@ -42,6 +49,7 @@ type Config struct {
|
|||
Elasticsearch Elasticsearch `mapstructure:"elasticsearch"`
|
||||
Slack Slack `mapstructure:"slack"`
|
||||
Discord Discord `mapstructure:"discord"`
|
||||
Teams Teams `mapstructure:"teams"`
|
||||
API API `mapstructure:"api"`
|
||||
Kubeconfig string `mapstructure:"kubeconfig"`
|
||||
Namespace string `mapstructure:"namespace"`
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/fjogeleit/policy-reporter/pkg/target/elasticsearch"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target/loki"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target/slack"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target/teams"
|
||||
"k8s.io/client-go/dynamic"
|
||||
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
|
@ -33,6 +34,7 @@ type Resolver struct {
|
|||
elasticsearchClient target.Client
|
||||
slackClient target.Client
|
||||
discordClient target.Client
|
||||
teamsClient target.Client
|
||||
}
|
||||
|
||||
// APIServer resolver method
|
||||
|
@ -258,6 +260,28 @@ func (r *Resolver) DiscordClient() target.Client {
|
|||
return r.discordClient
|
||||
}
|
||||
|
||||
// TeamsClient resolver method
|
||||
func (r *Resolver) TeamsClient() target.Client {
|
||||
if r.teamsClient != nil {
|
||||
return r.teamsClient
|
||||
}
|
||||
|
||||
if r.config.Teams.Webhook == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
r.teamsClient = teams.NewClient(
|
||||
r.config.Teams.Webhook,
|
||||
r.config.Teams.MinimumPriority,
|
||||
r.config.Teams.SkipExisting,
|
||||
&http.Client{},
|
||||
)
|
||||
|
||||
log.Println("[INFO] Teams configured")
|
||||
|
||||
return r.teamsClient
|
||||
}
|
||||
|
||||
func (r *Resolver) TargetClients() []target.Client {
|
||||
clients := make([]target.Client, 0)
|
||||
|
||||
|
@ -277,6 +301,10 @@ func (r *Resolver) TargetClients() []target.Client {
|
|||
clients = append(clients, discord)
|
||||
}
|
||||
|
||||
if teams := r.TeamsClient(); teams != nil {
|
||||
clients = append(clients, teams)
|
||||
}
|
||||
|
||||
return clients
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,11 @@ var testConfig = &config.Config{
|
|||
SkipExisting: true,
|
||||
MinimumPriority: "debug",
|
||||
},
|
||||
Teams: config.Teams{
|
||||
Webhook: "http://hook.teams:80",
|
||||
SkipExisting: true,
|
||||
MinimumPriority: "debug",
|
||||
},
|
||||
}
|
||||
|
||||
func Test_ResolveTarget(t *testing.T) {
|
||||
|
@ -80,14 +85,25 @@ func Test_ResolveTarget(t *testing.T) {
|
|||
t.Error("Error: Should reuse first instance")
|
||||
}
|
||||
})
|
||||
t.Run("Teams", func(t *testing.T) {
|
||||
client := resolver.TeamsClient()
|
||||
if client == nil {
|
||||
t.Error("Expected Client, got nil")
|
||||
}
|
||||
|
||||
client2 := resolver.TeamsClient()
|
||||
if client != client2 {
|
||||
t.Error("Error: Should reuse first instance")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ResolveTargets(t *testing.T) {
|
||||
resolver := config.NewResolver(testConfig, nil)
|
||||
|
||||
clients := resolver.TargetClients()
|
||||
if count := len(clients); count != 4 {
|
||||
t.Errorf("Expected 4 Clients, got %d", count)
|
||||
if count := len(clients); count != 5 {
|
||||
t.Errorf("Expected 5 Clients, got %d", count)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,6 +166,11 @@ func Test_ResolveTargetWithoutHost(t *testing.T) {
|
|||
SkipExisting: true,
|
||||
MinimumPriority: "debug",
|
||||
},
|
||||
Teams: config.Teams{
|
||||
Webhook: "",
|
||||
SkipExisting: true,
|
||||
MinimumPriority: "debug",
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("Loki", func(t *testing.T) {
|
||||
|
@ -180,6 +201,13 @@ func Test_ResolveTargetWithoutHost(t *testing.T) {
|
|||
t.Error("Expected Client to be nil if no host is configured")
|
||||
}
|
||||
})
|
||||
t.Run("Teams", func(t *testing.T) {
|
||||
resolver := config.NewResolver(config2, nil)
|
||||
|
||||
if resolver.TeamsClient() != nil {
|
||||
t.Error("Expected Client to be nil if no host is configured")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ResolveResultClient(t *testing.T) {
|
||||
|
|
|
@ -135,7 +135,7 @@ func (d *client) MinimumPriority() string {
|
|||
return d.minimumPriority
|
||||
}
|
||||
|
||||
// NewClient creates a new loki.client to send Results to Loki
|
||||
// NewClient creates a new loki.client to send Results to Discord
|
||||
func NewClient(webhook, minimumPriority string, skipExistingOnStartup bool, httpClient httpClient) target.Client {
|
||||
return &client{
|
||||
webhook,
|
||||
|
|
|
@ -84,7 +84,7 @@ func (e *client) MinimumPriority() string {
|
|||
return e.minimumPriority
|
||||
}
|
||||
|
||||
// NewClient creates a new loki.client to send Results to Loki
|
||||
// NewClient creates a new loki.client to send Results to Elasticsearch
|
||||
func NewClient(host, index, rotation, minimumPriority string, skipExistingOnStartup bool, httpClient httpClient) target.Client {
|
||||
return &client{
|
||||
host,
|
||||
|
|
|
@ -188,7 +188,7 @@ func (s *client) MinimumPriority() string {
|
|||
return s.minimumPriority
|
||||
}
|
||||
|
||||
// NewClient creates a new slack.client to send Results to Loki
|
||||
// NewClient creates a new slack.client to send Results to Slack
|
||||
func NewClient(host, minimumPriority string, skipExistingOnStartup bool, httpClient httpClient) target.Client {
|
||||
return &client{
|
||||
host,
|
||||
|
|
|
@ -49,7 +49,7 @@ func (c testClient) Do(req *http.Request) (*http.Response, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func Test_LokiTarget(t *testing.T) {
|
||||
func Test_SlackTarget(t *testing.T) {
|
||||
t.Run("Send Complete Result", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
if contentType := req.Header.Get("Content-Type"); contentType != "application/json; charset=utf-8" {
|
||||
|
|
155
pkg/target/teams/teams.go
Normal file
155
pkg/target/teams/teams.go
Normal file
|
@ -0,0 +1,155 @@
|
|||
package teams
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/fjogeleit/policy-reporter/pkg/report"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target/helper"
|
||||
)
|
||||
|
||||
type httpClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
type fact struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type section struct {
|
||||
Title string `json:"activityTitle"`
|
||||
SubTitle string `json:"activitySubtitle"`
|
||||
Text string `json:"text"`
|
||||
Facts []fact `json:"facts,omitempty"`
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Type string `json:"@type"`
|
||||
Context string `json:"@context"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
ThemeColor string `json:"themeColor,omitempty"`
|
||||
Sections []section `json:"sections"`
|
||||
}
|
||||
|
||||
func colorFromPriority(p report.Priority) string {
|
||||
if p == report.ErrorPriority {
|
||||
return "e20b0b"
|
||||
}
|
||||
if p == report.WarningPriority {
|
||||
return "f2c744"
|
||||
}
|
||||
if p == report.InfoPriority {
|
||||
return "36a64f"
|
||||
}
|
||||
|
||||
return "68c2ff"
|
||||
}
|
||||
|
||||
func newPayload(result report.Result) payload {
|
||||
facts := make([]fact, 0)
|
||||
|
||||
facts = append(facts, fact{"Policy", result.Policy})
|
||||
|
||||
if result.Rule != "" {
|
||||
facts = append(facts, fact{"Rule", result.Rule})
|
||||
}
|
||||
|
||||
facts = append(facts, fact{"Priority", result.Priority.String()})
|
||||
|
||||
if result.Category != "" {
|
||||
facts = append(facts, fact{"Category", result.Category})
|
||||
}
|
||||
if result.Severity != "" {
|
||||
facts = append(facts, fact{"Severity", result.Severity})
|
||||
}
|
||||
res := report.Resource{}
|
||||
|
||||
if len(result.Resources) > 0 {
|
||||
res = result.Resources[0]
|
||||
}
|
||||
if res.Kind != "" {
|
||||
facts = append(facts, fact{"Kind", res.Kind})
|
||||
facts = append(facts, fact{"Name", res.Name})
|
||||
facts = append(facts, fact{"UID", res.UID})
|
||||
if res.Namespace != "" {
|
||||
facts = append(facts, fact{"Namespace", res.Namespace})
|
||||
}
|
||||
facts = append(facts, fact{"API Version", res.APIVersion})
|
||||
}
|
||||
|
||||
sections := make([]section, 0, 1)
|
||||
sections = append(sections, section{
|
||||
Title: "New Policy Report Result",
|
||||
SubTitle: time.Now().Format(time.RFC3339),
|
||||
Text: result.Message,
|
||||
Facts: facts,
|
||||
})
|
||||
|
||||
return payload{
|
||||
Type: "MessageCard",
|
||||
Context: "http://schema.org/extensions",
|
||||
Summary: result.Message,
|
||||
ThemeColor: colorFromPriority(result.Priority),
|
||||
Sections: sections,
|
||||
}
|
||||
}
|
||||
|
||||
type client struct {
|
||||
webhook string
|
||||
minimumPriority string
|
||||
skipExistingOnStartup bool
|
||||
client httpClient
|
||||
}
|
||||
|
||||
func (s *client) Send(result report.Result) {
|
||||
if result.Priority < report.NewPriority(s.minimumPriority) {
|
||||
return
|
||||
}
|
||||
|
||||
payload := newPayload(result)
|
||||
body := new(bytes.Buffer)
|
||||
|
||||
if err := json.NewEncoder(body).Encode(payload); err != nil {
|
||||
log.Printf("[ERROR] TEAMS : %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", s.webhook, body)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] TEAMS : %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", "application/json; charset=utf-8")
|
||||
req.Header.Add("User-Agent", "Policy-Reporter")
|
||||
|
||||
resp, err := s.client.Do(req)
|
||||
helper.HandleHTTPResponse("TEAMS", resp, err)
|
||||
}
|
||||
|
||||
func (s *client) SkipExistingOnStartup() bool {
|
||||
return s.skipExistingOnStartup
|
||||
}
|
||||
|
||||
func (s *client) Name() string {
|
||||
return "Teams"
|
||||
}
|
||||
|
||||
func (s *client) MinimumPriority() string {
|
||||
return s.minimumPriority
|
||||
}
|
||||
|
||||
// NewClient creates a new teams.client to send Results to MS Teams
|
||||
func NewClient(host, minimumPriority string, skipExistingOnStartup bool, httpClient httpClient) target.Client {
|
||||
return &client{
|
||||
host,
|
||||
minimumPriority,
|
||||
skipExistingOnStartup,
|
||||
httpClient,
|
||||
}
|
||||
}
|
208
pkg/target/teams/teams_test.go
Normal file
208
pkg/target/teams/teams_test.go
Normal file
|
@ -0,0 +1,208 @@
|
|||
package teams_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/fjogeleit/policy-reporter/pkg/report"
|
||||
"github.com/fjogeleit/policy-reporter/pkg/target/teams"
|
||||
)
|
||||
|
||||
var completeResult = report.Result{
|
||||
Message: "validation error: requests and limits required. Rule autogen-check-for-requests-and-limits failed at path /spec/template/spec/containers/0/resources/requests/",
|
||||
Policy: "require-requests-and-limits-required",
|
||||
Rule: "autogen-check-for-requests-and-limits",
|
||||
Priority: report.WarningPriority,
|
||||
Status: report.Fail,
|
||||
Severity: report.Heigh,
|
||||
Category: "resources",
|
||||
Scored: true,
|
||||
Resources: []report.Resource{
|
||||
{
|
||||
APIVersion: "v1",
|
||||
Kind: "Deployment",
|
||||
Name: "nginx",
|
||||
Namespace: "default",
|
||||
UID: "536ab69f-1b3c-4bd9-9ba4-274a56188409",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var minimalResult = report.Result{
|
||||
Message: "validation error: label required. Rule app-label-required failed at path /spec/template/spec/containers/0/resources/requests/",
|
||||
Policy: "app-label-requirement",
|
||||
Priority: report.ErrorPriority,
|
||||
Status: report.Fail,
|
||||
Scored: true,
|
||||
}
|
||||
|
||||
var minimalInfoResult = report.Result{
|
||||
Message: "validation error: label required. Rule app-label-required failed at path /spec/template/spec/containers/0/resources/requests/",
|
||||
Policy: "app-label-requirement",
|
||||
Priority: report.InfoPriority,
|
||||
Status: report.Fail,
|
||||
Scored: true,
|
||||
}
|
||||
|
||||
var minimalDebugResult = report.Result{
|
||||
Message: "validation error: label required. Rule app-label-required failed at path /spec/template/spec/containers/0/resources/requests/",
|
||||
Policy: "app-label-requirement",
|
||||
Priority: report.DebugPriority,
|
||||
Status: report.Fail,
|
||||
Scored: true,
|
||||
}
|
||||
|
||||
type testClient struct {
|
||||
callback func(req *http.Request)
|
||||
statusCode int
|
||||
}
|
||||
|
||||
func (c testClient) Do(req *http.Request) (*http.Response, error) {
|
||||
c.callback(req)
|
||||
|
||||
return &http.Response{
|
||||
StatusCode: c.statusCode,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Test_TeamsTarget(t *testing.T) {
|
||||
t.Run("Send Complete Result", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
if contentType := req.Header.Get("Content-Type"); contentType != "application/json; charset=utf-8" {
|
||||
t.Errorf("Unexpected Content-Type: %s", contentType)
|
||||
}
|
||||
|
||||
if agend := req.Header.Get("User-Agent"); agend != "Policy-Reporter" {
|
||||
t.Errorf("Unexpected Host: %s", agend)
|
||||
}
|
||||
|
||||
if url := req.URL.String(); url != "http://hook.teams:80" {
|
||||
t.Errorf("Unexpected Host: %s", url)
|
||||
}
|
||||
|
||||
payload := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if payload["themeColor"] != "f2c744" {
|
||||
t.Errorf("Unexpected ThemeColor %s", payload["themeColor"])
|
||||
}
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://hook.teams:80", "", false, testClient{callback, 200})
|
||||
client.Send(completeResult)
|
||||
})
|
||||
|
||||
t.Run("Send Minimal Result", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
if contentType := req.Header.Get("Content-Type"); contentType != "application/json; charset=utf-8" {
|
||||
t.Errorf("Unexpected Content-Type: %s", contentType)
|
||||
}
|
||||
|
||||
if agend := req.Header.Get("User-Agent"); agend != "Policy-Reporter" {
|
||||
t.Errorf("Unexpected Host: %s", agend)
|
||||
}
|
||||
|
||||
if url := req.URL.String(); url != "http://hook.teams:80" {
|
||||
t.Errorf("Unexpected Host: %s", url)
|
||||
}
|
||||
|
||||
payload := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if payload["themeColor"] != "e20b0b" {
|
||||
t.Errorf("Unexpected ThemeColor %s", payload["themeColor"])
|
||||
}
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://hook.teams:80", "", false, testClient{callback, 200})
|
||||
client.Send(minimalResult)
|
||||
})
|
||||
t.Run("Send Minimal InfoResult", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
payload := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if payload["themeColor"] != "36a64f" {
|
||||
t.Errorf("Unexpected ThemeColor %s", payload["themeColor"])
|
||||
}
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://hook.teams:80", "", false, testClient{callback, 200})
|
||||
client.Send(minimalInfoResult)
|
||||
})
|
||||
t.Run("Send Minimal Debug Result", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
if contentType := req.Header.Get("Content-Type"); contentType != "application/json; charset=utf-8" {
|
||||
t.Errorf("Unexpected Content-Type: %s", contentType)
|
||||
}
|
||||
|
||||
if agend := req.Header.Get("User-Agent"); agend != "Policy-Reporter" {
|
||||
t.Errorf("Unexpected Host: %s", agend)
|
||||
}
|
||||
|
||||
if url := req.URL.String(); url != "http://hook.teams:80" {
|
||||
t.Errorf("Unexpected Host: %s", url)
|
||||
}
|
||||
|
||||
payload := make(map[string]interface{})
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if payload["themeColor"] != "68c2ff" {
|
||||
t.Errorf("Unexpected ThemeColor %s", payload["themeColor"])
|
||||
}
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://hook.teams:80", "", false, testClient{callback, 200})
|
||||
client.Send(minimalDebugResult)
|
||||
})
|
||||
t.Run("Send with ingored Priority", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
t.Errorf("Unexpected Call")
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://localhost:9200", "error", false, testClient{callback, 200})
|
||||
client.Send(completeResult)
|
||||
})
|
||||
t.Run("SkipExistingOnStartup", func(t *testing.T) {
|
||||
callback := func(req *http.Request) {
|
||||
t.Errorf("Unexpected Call")
|
||||
}
|
||||
|
||||
client := teams.NewClient("http://localhost:9200", "", true, testClient{callback, 200})
|
||||
|
||||
if !client.SkipExistingOnStartup() {
|
||||
t.Error("Should return configured SkipExistingOnStartup")
|
||||
}
|
||||
})
|
||||
t.Run("Name", func(t *testing.T) {
|
||||
client := teams.NewClient("http://localhost:9200", "", true, testClient{})
|
||||
|
||||
if client.Name() != "Teams" {
|
||||
t.Errorf("Unexpected Name %s", client.Name())
|
||||
}
|
||||
})
|
||||
t.Run("MinimumPriority", func(t *testing.T) {
|
||||
client := teams.NewClient("http://localhost:9200", "debug", true, testClient{})
|
||||
|
||||
if client.MinimumPriority() != "debug" {
|
||||
t.Errorf("Unexpected MinimumPriority %s", client.MinimumPriority())
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue