1
0
Fork 0
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:
Frank Jogeleit 2022-02-25 09:58:29 +01:00
parent dc8e18e164
commit f49883379c
14 changed files with 51 additions and 23 deletions

View file

@ -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)]

View file

@ -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

View file

@ -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

View file

@ -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 }}

View file

@ -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

View file

@ -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: ""

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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{},
)

View file

@ -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,
}
}

View file

@ -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())