mirror of
https://github.com/kyverno/policy-reporter.git
synced 2024-12-14 11:57:32 +00:00
Support custom labels for Loki pushes
Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de>
This commit is contained in:
parent
dc8e18e164
commit
f49883379c
14 changed files with 51 additions and 23 deletions
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
# 2.4.0
|
||||
* Policy Reporter
|
||||
* Add Support for custom Loki labels
|
||||
|
||||
# 2.3.0
|
||||
* Policy Reporter
|
||||
* Add Support for linux/s390x [[#115](https://github.com/kyverno/policy-reporter/pull/115) by [skuethe](https://github.com/skuethe)]
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
GO ?= go
|
||||
BUILD ?= build
|
||||
REPO ?= ghcr.io/kyverno/policy-reporter
|
||||
IMAGE_TAG ?= 2.1.0
|
||||
IMAGE_TAG ?= 2.2.0
|
||||
LD_FLAGS='-s -w -linkmode external -extldflags "-static"'
|
||||
|
||||
all: build
|
||||
|
|
|
@ -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: 2.3.0
|
||||
appVersion: 2.1.0
|
||||
version: 2.4.0
|
||||
appVersion: 2.2.0
|
||||
|
||||
icon: https://github.com/kyverno/kyverno/raw/main/img/logo.png
|
||||
home: https://kyverno.github.io/policy-reporter
|
||||
|
|
|
@ -2,6 +2,10 @@ loki:
|
|||
host: {{ .Values.target.loki.host | quote }}
|
||||
minimumPriority: {{ .Values.target.loki.minimumPriority | quote }}
|
||||
skipExistingOnStartup: {{ .Values.target.loki.skipExistingOnStartup }}
|
||||
{{- with .Values.target.loki.customLabels }}
|
||||
customLabels:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.target.loki.sources }}
|
||||
sources:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
|
|
|
@ -2,7 +2,7 @@ image:
|
|||
registry: ghcr.io
|
||||
repository: kyverno/policy-reporter
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 2.1.0
|
||||
tag: 2.2.0
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
|
@ -145,6 +145,8 @@ target:
|
|||
sources: []
|
||||
# Skip already existing PolicyReportResults on startup
|
||||
skipExistingOnStartup: true
|
||||
# Added as additional labels to each Loki event
|
||||
customLabels: {}
|
||||
|
||||
elasticsearch:
|
||||
# elasticsearch host address
|
||||
|
|
|
@ -64,6 +64,8 @@ loki:
|
|||
host: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
customLabels: {}
|
||||
sources: []
|
||||
|
||||
elasticsearch:
|
||||
host: ""
|
||||
|
@ -71,26 +73,31 @@ elasticsearch:
|
|||
rotation: "dayli"
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
sources: []
|
||||
|
||||
slack:
|
||||
webhook: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
sources: []
|
||||
|
||||
discord:
|
||||
webhook: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
sources: []
|
||||
|
||||
teams:
|
||||
webhook: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
sources: []
|
||||
|
||||
ui:
|
||||
host: ""
|
||||
minimumPriority: ""
|
||||
skipExistingOnStartup: true
|
||||
sources: []
|
||||
|
||||
s3:
|
||||
endpoint: ""
|
||||
|
|
|
@ -93,7 +93,7 @@ spec:
|
|||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: ui
|
||||
image: "ghcr.io/kyverno/policy-reporter-ui:1.2.0"
|
||||
image: "ghcr.io/kyverno/policy-reporter-ui:1.3.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
@ -145,7 +145,7 @@ spec:
|
|||
fsGroup: 1234
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.0.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.2.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -157,7 +157,7 @@ spec:
|
|||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- name: "kyverno-plugin"
|
||||
image: "ghcr.io/kyverno/policy-reporter-kyverno-plugin:1.1.0"
|
||||
image: "ghcr.io/kyverno/policy-reporter-kyverno-plugin:1.2.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
@ -204,7 +204,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: ui
|
||||
image: "ghcr.io/kyverno/policy-reporter-ui:1.2.0"
|
||||
image: "ghcr.io/kyverno/policy-reporter-ui:1.3.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
@ -256,7 +256,7 @@ spec:
|
|||
fsGroup: 1234
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.0.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.2.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -84,7 +84,7 @@ spec:
|
|||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.0.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.2.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -433,7 +433,7 @@ func Test_TargetsAPI(t *testing.T) {
|
|||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := v1.TargetsHandler([]target.Client{
|
||||
loki.NewClient("", "", []string{}, true, &http.Client{}),
|
||||
loki.NewClient("", "", []string{}, true, make(map[string]string), &http.Client{}),
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
|
|
@ -2,10 +2,11 @@ package config
|
|||
|
||||
// Loki configuration
|
||||
type Loki struct {
|
||||
Host string `mapstructure:"host"`
|
||||
SkipExisting bool `mapstructure:"skipExistingOnStartup"`
|
||||
MinimumPriority string `mapstructure:"minimumPriority"`
|
||||
Sources []string `mapstructure:"sources"`
|
||||
Host string `mapstructure:"host"`
|
||||
SkipExisting bool `mapstructure:"skipExistingOnStartup"`
|
||||
MinimumPriority string `mapstructure:"minimumPriority"`
|
||||
Sources []string `mapstructure:"sources"`
|
||||
CustomLabels map[string]string `mapstructure:"customLabels"`
|
||||
}
|
||||
|
||||
// Elasticsearch configuration
|
||||
|
|
|
@ -133,6 +133,7 @@ func (r *Resolver) LokiClient() target.Client {
|
|||
r.config.Loki.MinimumPriority,
|
||||
r.config.Loki.Sources,
|
||||
r.config.Loki.SkipExisting,
|
||||
r.config.Loki.CustomLabels,
|
||||
&http.Client{},
|
||||
)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ type entry struct {
|
|||
Line string `json:"line"`
|
||||
}
|
||||
|
||||
func newLokiPayload(result *report.Result) payload {
|
||||
func newLokiPayload(result *report.Result, customLabels map[string]string) payload {
|
||||
timestamp := time.Now()
|
||||
if !result.Timestamp.IsZero() {
|
||||
timestamp = result.Timestamp
|
||||
|
@ -65,6 +65,10 @@ func newLokiPayload(result *report.Result) payload {
|
|||
labels = append(labels, strings.ReplaceAll(property, ".", "_")+"=\""+strings.ReplaceAll(value, "\"", "")+"\"")
|
||||
}
|
||||
|
||||
for label, value := range customLabels {
|
||||
labels = append(labels, strings.ReplaceAll(label, ".", "_")+"=\""+strings.ReplaceAll(value, "\"", "")+"\"")
|
||||
}
|
||||
|
||||
ls.Labels = "{" + strings.Join(labels, ",") + "}"
|
||||
|
||||
return payload{Streams: []stream{ls}}
|
||||
|
@ -72,12 +76,13 @@ func newLokiPayload(result *report.Result) payload {
|
|||
|
||||
type client struct {
|
||||
target.BaseClient
|
||||
host string
|
||||
client httpClient
|
||||
host string
|
||||
client httpClient
|
||||
customLabels map[string]string
|
||||
}
|
||||
|
||||
func (l *client) Send(result *report.Result) {
|
||||
req, err := helper.CreateJSONRequest(l.Name(), "POST", l.host, newLokiPayload(result))
|
||||
req, err := helper.CreateJSONRequest(l.Name(), "POST", l.host, newLokiPayload(result, l.customLabels))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -94,10 +99,11 @@ func (l *client) Name() string {
|
|||
}
|
||||
|
||||
// NewClient creates a new loki.client to send Results to Loki
|
||||
func NewClient(host, minimumPriority string, sources []string, skipExistingOnStartup bool, httpClient httpClient) target.Client {
|
||||
func NewClient(host, minimumPriority string, sources []string, skipExistingOnStartup bool, customLabels map[string]string, httpClient httpClient) target.Client {
|
||||
return &client{
|
||||
target.NewBaseClient(minimumPriority, sources, skipExistingOnStartup),
|
||||
host + "/api/prom/push",
|
||||
httpClient,
|
||||
customLabels,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,9 @@ func Test_LokiTarget(t *testing.T) {
|
|||
if !strings.Contains(labels, "severity=\""+completeResult.Severity+"\"") {
|
||||
t.Error("Missing Content for Label 'severity'")
|
||||
}
|
||||
if !strings.Contains(labels, "custom=\"label\"") {
|
||||
t.Error("Missing Content for Label 'severity'")
|
||||
}
|
||||
|
||||
res := completeResult.Resource
|
||||
if !strings.Contains(labels, "kind=\""+res.Kind+"\"") {
|
||||
|
@ -114,7 +117,7 @@ func Test_LokiTarget(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
loki := loki.NewClient("http://localhost:3100", "", []string{}, false, testClient{callback, 200})
|
||||
loki := loki.NewClient("http://localhost:3100", "", []string{}, false, map[string]string{"custom": "label"}, testClient{callback, 200})
|
||||
loki.Send(completeResult)
|
||||
})
|
||||
|
||||
|
@ -172,11 +175,11 @@ func Test_LokiTarget(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
loki := loki.NewClient("http://localhost:3100", "", []string{}, false, testClient{callback, 200})
|
||||
loki := loki.NewClient("http://localhost:3100", "", []string{}, false, make(map[string]string), testClient{callback, 200})
|
||||
loki.Send(minimalResult)
|
||||
})
|
||||
t.Run("Name", func(t *testing.T) {
|
||||
client := loki.NewClient("http://localhost:9200", "", []string{}, true, testClient{})
|
||||
client := loki.NewClient("http://localhost:9200", "", []string{}, true, make(map[string]string), testClient{})
|
||||
|
||||
if client.Name() != "Loki" {
|
||||
t.Errorf("Unexpected Name %s", client.Name())
|
||||
|
|
Loading…
Reference in a new issue