mirror of
https://github.com/kyverno/policy-reporter.git
synced 2024-12-14 11:57:32 +00:00
support custom headers for loki target (#422)
* support custom headers for loki target Signed-off-by: Frank Jogeleit <frank.jogeleit@lovoo.com>
This commit is contained in:
parent
cb5d836ad3
commit
ea8ae54520
21 changed files with 56 additions and 36 deletions
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
|
@ -19,10 +19,10 @@ jobs:
|
|||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.21
|
||||
- name: Set up Go 1.22
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.21
|
||||
go-version: 1.22
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Get dependencies
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
# Changelog
|
||||
|
||||
# 2.22.5
|
||||
* Helm Chart
|
||||
* fix(helm): correct typo when using global.annotations [[#420](https://github.com/kyverno/policy-reporter/pull/420) by [ThomasLachaux](https://github.com/ThomasLachaux)]
|
||||
* Policy Reporter v2.18.2
|
||||
* Add support for custom headers for the Loki target
|
||||
|
||||
# 2.22.4
|
||||
* Helm Chart
|
||||
* fix mapping of headers properties to from values.yaml to config.yaml
|
||||
* fix(helm): mapping of headers properties to from values.yaml to config.yaml
|
||||
|
||||
# 2.22.3
|
||||
* Helm Chart
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.21.6 as builder
|
||||
FROM golang:1.22 as builder
|
||||
|
||||
ARG LD_FLAGS='-s -w -linkmode external -extldflags "-static"'
|
||||
ARG TARGETPLATFORM
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
GO ?= go
|
||||
BUILD ?= build
|
||||
REPO ?= ghcr.io/kyverno/policy-reporter
|
||||
IMAGE_TAG ?= 2.18.1
|
||||
IMAGE_TAG ?= 2.18.2
|
||||
LD_FLAGS=-s -w -linkmode external -extldflags "-static"
|
||||
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ description: |
|
|||
|
||||
type: application
|
||||
version: 2.22.5
|
||||
appVersion: 2.18.1
|
||||
appVersion: 2.18.2
|
||||
|
||||
icon: https://github.com/kyverno/kyverno/raw/main/img/logo.png
|
||||
home: https://kyverno.github.io/policy-reporter
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Policy Reporter
|
||||
|
||||
![Version: v2.22.4](https://img.shields.io/badge/Version-v2.22.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.18.1](https://img.shields.io/badge/AppVersion-v2.18.1-informational?style=flat-square)
|
||||
![Version: v2.22.5](https://img.shields.io/badge/Version-v2.22.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.18.2](https://img.shields.io/badge/AppVersion-v2.18.2-informational?style=flat-square)
|
||||
|
||||
## Motivation
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ image:
|
|||
registry: ghcr.io
|
||||
repository: kyverno/policy-reporter
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 2.18.1
|
||||
tag: 2.18.2
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
|||
module github.com/kyverno/policy-reporter
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.36.0
|
||||
|
|
|
@ -480,7 +480,7 @@ spec:
|
|||
fsGroup: 1234
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -367,7 +367,7 @@ spec:
|
|||
fsGroup: 1234
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -223,7 +223,7 @@ spec:
|
|||
fsGroup: 1234
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -113,7 +113,7 @@ spec:
|
|||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -26,7 +26,7 @@ spec:
|
|||
restartPolicy: Never
|
||||
containers:
|
||||
- name: policy-reporter
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.1"
|
||||
image: "ghcr.io/kyverno/policy-reporter:2.18.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
|
|
@ -91,6 +91,7 @@ type TargetOption interface {
|
|||
type Loki struct {
|
||||
TargetBaseOptions `mapstructure:",squash"`
|
||||
CustomLabels map[string]string `mapstructure:"customLabels"`
|
||||
Headers map[string]string `mapstructure:"headers"`
|
||||
Host string `mapstructure:"host"`
|
||||
SkipTLS bool `mapstructure:"skipTLS"`
|
||||
Certificate string `mapstructure:"certificate"`
|
||||
|
@ -110,9 +111,9 @@ type Elasticsearch struct {
|
|||
Rotation string `mapstructure:"rotation"`
|
||||
Username string `mapstructure:"username"`
|
||||
Password string `mapstructure:"password"`
|
||||
ApiKey string `mapstructure:"apiKey"`
|
||||
APIKey string `mapstructure:"apiKey"`
|
||||
Channels []*Elasticsearch `mapstructure:"channels"`
|
||||
TypelessApi bool `mapstructure:"typelessApi"`
|
||||
TypelessAPI bool `mapstructure:"typelessApi"`
|
||||
}
|
||||
|
||||
// Slack configuration
|
||||
|
|
|
@ -27,6 +27,7 @@ var testConfig = &config.Config{
|
|||
},
|
||||
},
|
||||
},
|
||||
Headers: map[string]string{"X-Forward": "http://loki"},
|
||||
},
|
||||
Elasticsearch: &config.Elasticsearch{
|
||||
Host: "http://localhost:9200",
|
||||
|
|
|
@ -395,6 +395,7 @@ func (f *TargetFactory) createLokiClient(config, parent *Loki) target.Client {
|
|||
HTTPClient: http.NewClient(config.Certificate, config.SkipTLS),
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
Headers: config.Headers,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -412,10 +413,10 @@ func (f *TargetFactory) createElasticsearchClient(config, parent *Elasticsearch)
|
|||
setBool(&config.SkipTLS, parent.SkipTLS)
|
||||
setFallback(&config.Username, parent.Username)
|
||||
setFallback(&config.Password, parent.Password)
|
||||
setFallback(&config.ApiKey, parent.ApiKey)
|
||||
setFallback(&config.APIKey, parent.APIKey)
|
||||
setFallback(&config.Index, parent.Index, "policy-reporter")
|
||||
setFallback(&config.Rotation, parent.Rotation, elasticsearch.Daily)
|
||||
setBool(&config.TypelessApi, parent.TypelessApi)
|
||||
setBool(&config.TypelessAPI, parent.TypelessAPI)
|
||||
|
||||
config.MapBaseParent(parent.TargetBaseOptions)
|
||||
|
||||
|
@ -426,12 +427,12 @@ func (f *TargetFactory) createElasticsearchClient(config, parent *Elasticsearch)
|
|||
Host: config.Host,
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
ApiKey: config.ApiKey,
|
||||
ApiKey: config.APIKey,
|
||||
Rotation: config.Rotation,
|
||||
Index: config.Index,
|
||||
CustomFields: config.CustomFields,
|
||||
HTTPClient: http.NewClient(config.Certificate, config.SkipTLS),
|
||||
TypelessApi: config.TypelessApi,
|
||||
TypelessApi: config.TypelessAPI,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -839,11 +840,11 @@ func (f *TargetFactory) mapSecretValues(config any, ref, mountedSecret string) {
|
|||
if values.Password != "" {
|
||||
c.Password = values.Password
|
||||
}
|
||||
if values.ApiKey != "" {
|
||||
c.ApiKey = values.ApiKey
|
||||
if values.APIKey != "" {
|
||||
c.APIKey = values.APIKey
|
||||
}
|
||||
if values.TypelessApi != false {
|
||||
c.TypelessApi = values.TypelessApi
|
||||
if values.TypelessAPI != false {
|
||||
c.TypelessAPI = values.TypelessAPI
|
||||
}
|
||||
|
||||
case *S3:
|
||||
|
|
|
@ -51,7 +51,7 @@ func mountSecret() {
|
|||
Webhook: "http://localhost:9200/webhook",
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
ApiKey: "apiKey",
|
||||
APIKey: "apiKey",
|
||||
AccessKeyID: "accessKeyId",
|
||||
SecretAccessKey: "secretAccessKey",
|
||||
KmsKeyID: "kmsKeyId",
|
||||
|
@ -59,7 +59,7 @@ func mountSecret() {
|
|||
Credentials: `{"token": "token", "type": "authorized_user"}`,
|
||||
Database: "database",
|
||||
DSN: "",
|
||||
TypelessApi: false,
|
||||
TypelessAPI: false,
|
||||
}
|
||||
file, _ := json.MarshalIndent(secretValues, "", " ")
|
||||
_ = os.WriteFile(mountedSecret, file, 0o644)
|
||||
|
|
|
@ -18,7 +18,7 @@ type Values struct {
|
|||
Channel string `json:"channel,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
ApiKey string `json:"apiKey,omitempty"`
|
||||
APIKey string `json:"apiKey,omitempty"`
|
||||
AccessKeyID string `json:"accessKeyID,omitempty"`
|
||||
SecretAccessKey string `json:"secretAccessKey,omitempty"`
|
||||
AccountID string `json:"accountID,omitempty"`
|
||||
|
@ -27,7 +27,7 @@ type Values struct {
|
|||
Credentials string `json:"credentials,omitempty"`
|
||||
Database string `json:"database,omitempty"`
|
||||
DSN string `json:"dsn,omitempty"`
|
||||
TypelessApi bool `json:"typelessApi,omitempty"`
|
||||
TypelessAPI bool `json:"typelessApi,omitempty"`
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
|
@ -92,7 +92,7 @@ func (c *k8sClient) Get(ctx context.Context, name string) (Values, error) {
|
|||
}
|
||||
|
||||
if apiKey, ok := secret.Data["apiKey"]; ok {
|
||||
values.ApiKey = string(apiKey)
|
||||
values.APIKey = string(apiKey)
|
||||
}
|
||||
|
||||
if database, ok := secret.Data["database"]; ok {
|
||||
|
@ -127,10 +127,10 @@ func (c *k8sClient) Get(ctx context.Context, name string) (Values, error) {
|
|||
values.Credentials = string(credentials)
|
||||
}
|
||||
|
||||
if typelessApi, ok := secret.Data["typelessApi"]; ok {
|
||||
values.TypelessApi, err = strconv.ParseBool(string(typelessApi))
|
||||
if typelessAPI, ok := secret.Data["typelessApi"]; ok {
|
||||
values.TypelessAPI, err = strconv.ParseBool(string(typelessAPI))
|
||||
if err != nil {
|
||||
values.TypelessApi = false
|
||||
values.TypelessAPI = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ func Test_Client(t *testing.T) {
|
|||
t.Errorf("Unexpected Password: %s", values.Password)
|
||||
}
|
||||
|
||||
if values.ApiKey != "apiKey" {
|
||||
t.Errorf("Unexpected ApiKey: %s", values.ApiKey)
|
||||
if values.APIKey != "apiKey" {
|
||||
t.Errorf("Unexpected ApiKey: %s", values.APIKey)
|
||||
}
|
||||
|
||||
if values.AccessKeyID != "accessKeyID" {
|
||||
|
@ -96,8 +96,8 @@ func Test_Client(t *testing.T) {
|
|||
t.Errorf("Unexpected DSN: %s", values.DSN)
|
||||
}
|
||||
|
||||
if values.TypelessApi {
|
||||
t.Errorf("Unexpected TypelessApi: %t", values.TypelessApi)
|
||||
if values.TypelessAPI {
|
||||
t.Errorf("Unexpected TypelessApi: %t", values.TypelessAPI)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ type Options struct {
|
|||
target.ClientOptions
|
||||
Host string
|
||||
CustomLabels map[string]string
|
||||
Headers map[string]string
|
||||
HTTPClient http.Client
|
||||
Username string
|
||||
Password string
|
||||
|
@ -94,6 +95,7 @@ type client struct {
|
|||
host string
|
||||
client http.Client
|
||||
customLabels map[string]string
|
||||
headers map[string]string
|
||||
username string
|
||||
password string
|
||||
}
|
||||
|
@ -105,6 +107,10 @@ func (l *client) Send(result v1alpha2.PolicyReportResult) {
|
|||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
for k, v := range l.headers {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
if l.username != "" {
|
||||
req.SetBasicAuth(l.username, l.password)
|
||||
}
|
||||
|
@ -120,6 +126,7 @@ func NewClient(options Options) target.Client {
|
|||
options.Host,
|
||||
options.HTTPClient,
|
||||
options.CustomLabels,
|
||||
options.Headers,
|
||||
options.Username,
|
||||
options.Password,
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ func Test_LokiTarget(t *testing.T) {
|
|||
if contentType := req.Header.Get("Content-Type"); contentType != "application/json" {
|
||||
t.Errorf("Unexpected Content-Type: %s", contentType)
|
||||
}
|
||||
if header := req.Header.Get("X-Forward"); header != "http://loki" {
|
||||
t.Errorf("Unexpected Header Value: %s", header)
|
||||
}
|
||||
|
||||
if agend := req.Header.Get("User-Agent"); agend != "Policy-Reporter" {
|
||||
t.Errorf("Unexpected Host: %s", agend)
|
||||
|
@ -101,6 +104,7 @@ func Test_LokiTarget(t *testing.T) {
|
|||
HTTPClient: testClient{callback, 200},
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
Headers: map[string]string{"X-Forward": "http://loki"},
|
||||
})
|
||||
client.Send(fixtures.CompleteTargetSendResult)
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue