Skip to content

Commit

Permalink
Configure DebounceTime for CleanupEvents (#33)
Browse files Browse the repository at this point in the history
* Configure DebounceTime for CleanupEvents
* Fix Chart
* Update Helm Charts
  • Loading branch information
fjogeleit authored Apr 30, 2021
1 parent 9cac2de commit 5b7a553
Show file tree
Hide file tree
Showing 16 changed files with 163 additions and 73 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 1.3.4

* Configure Debounce Time in seconds for Cleanup Events over Helm Chart
* Helm Value `cleanupDebounceTime` - default: 20
* Improved securityContext defaults

## 1.3.3

* Update Policy Reporter UI to v0.9.0
Expand Down
6 changes: 3 additions & 3 deletions charts/policy-reporter/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ dependencies:
version: 1.1.0
- name: ui
repository: ""
version: 1.3.0
digest: sha256:2e8942d0223c917557d3c6352a61baba02c15f26b1cad276c34c6609111b3682
generated: "2021-04-29T11:45:31.55116+02:00"
version: 1.3.1
digest: sha256:9d4e26e7bdc5a7feaab8bbdf23568151506640645da104afece06a27d1608560
generated: "2021-04-30T11:40:03.769829+02:00"
6 changes: 3 additions & 3 deletions charts/policy-reporter/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: 1.3.3
appVersion: 1.3.3
version: 1.3.4
appVersion: 1.3.4

dependencies:
- name: monitoring
Expand All @@ -16,4 +16,4 @@ dependencies:
- name: ui
condition: ui.enabled
repository: ""
version: "1.3.0"
version: "1.3.1"
2 changes: 1 addition & 1 deletion charts/policy-reporter/charts/ui/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ name: ui
description: Policy Reporter UI

type: application
version: 1.3.0
version: 1.3.1
appVersion: 0.9.0
16 changes: 9 additions & 7 deletions charts/policy-reporter/charts/ui/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ deploymentStrategy: {}
# maxUnavailable: 25%
# type: RollingUpdate

securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
securityContext:
runAsUser: 1234
runAsNonRoot: true
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- all

# Key/value pairs that are attached to pods.
podAnnotations: {}
Expand Down
1 change: 1 addition & 0 deletions charts/policy-reporter/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ spec:
args:
- --config=/app/config.yaml
- --crd-version={{ .Values.crdVersion }}
- --cleanup-debounce-time={{ .Values.cleanupDebounceTime }}
{{- if or .Values.api.enabled .Values.ui.enabled }}
- --apiPort=8080
{{- end }}
Expand Down
25 changes: 17 additions & 8 deletions charts/policy-reporter/values.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
image:
repository: fjogeleit/policy-reporter
pullPolicy: IfNotPresent
tag: 1.3.2
tag: 1.3.4

imagePullSecrets: []

Expand Down Expand Up @@ -43,13 +43,15 @@ service:
# integer nubmer. This is port for service
port: 2112

securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
securityContext:
runAsUser: 1234
runAsNonRoot: true
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- all

# Key/value pairs that are attached to pods.
podAnnotations: {}
Expand Down Expand Up @@ -90,6 +92,13 @@ global:
# PolicyReport CRD Version to use
crdVersion: v1alpha1

# Dounce Time in seconds for Modify Events after a cleanup event (Report with 0 Results)
# Used to prevent Policy Reporter from resending existing violations after Kyverno recreates PolicyReports
# When an existing Report get an Modify Event with 0 results it waits for the defined amount of time
# for new Report Events and process the latest incomming Event for this Report which should be the complete recreated Report
# the required amount of time can be different depending on the amount of validated resources and policies
cleanupDebounceTime: 20

api:
enabled: false

Expand Down
4 changes: 4 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ func loadConfig(cmd *cobra.Command) (*config.Config, error) {
v.BindPFlag("crdVersion", flag)
}

if flag := cmd.Flags().Lookup("cleanup-debounce-time"); flag != nil {
v.BindPFlag("cleanupDebounceTime", flag)
}

if flag := cmd.Flags().Lookup("apiPort"); flag != nil {
v.BindPFlag("api.port", flag)
v.BindPFlag("api.enabled", flag)
Expand Down
4 changes: 4 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"flag"
"log"
"net/http"

"github.com/fjogeleit/policy-reporter/pkg/config"
Expand All @@ -25,6 +26,8 @@ func newRunCMD() *cobra.Command {
return err
}

log.Printf("[INFO] Configured DebounceTime %d", c.CleanupDebounceTime)

var k8sConfig *rest.Config
if c.Kubeconfig != "" {
k8sConfig, err = clientcmd.BuildConfigFromFlags("", c.Kubeconfig)
Expand Down Expand Up @@ -96,6 +99,7 @@ func newRunCMD() *cobra.Command {
cmd.PersistentFlags().StringP("kubeconfig", "k", "", "absolute path to the kubeconfig file")
cmd.PersistentFlags().StringP("config", "c", "", "target configuration file")
cmd.PersistentFlags().StringP("crd-version", "v", "v1alpha1", "Policy Reporter CRD Version")
cmd.PersistentFlags().IntP("cleanup-debounce-time", "t", 20, "DebounceTime in Seconds after a Report cleanup started.")
cmd.PersistentFlags().IntP("apiPort", "a", 0, "http port for the optional rest api")

cmd.PersistentFlags().String("loki", "", "loki host: http://loki:3100")
Expand Down
21 changes: 11 additions & 10 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ type API struct {

// Config of the PolicyReporter
type Config struct {
Loki Loki `mapstructure:"loki"`
Elasticsearch Elasticsearch `mapstructure:"elasticsearch"`
Slack Slack `mapstructure:"slack"`
Discord Discord `mapstructure:"discord"`
Teams Teams `mapstructure:"teams"`
UI UI `mapstructure:"ui"`
API API `mapstructure:"api"`
Kubeconfig string `mapstructure:"kubeconfig"`
Namespace string `mapstructure:"namespace"`
CRDVersion string `mapstructure:"crdVersion"`
Loki Loki `mapstructure:"loki"`
Elasticsearch Elasticsearch `mapstructure:"elasticsearch"`
Slack Slack `mapstructure:"slack"`
Discord Discord `mapstructure:"discord"`
Teams Teams `mapstructure:"teams"`
UI UI `mapstructure:"ui"`
API API `mapstructure:"api"`
Kubeconfig string `mapstructure:"kubeconfig"`
Namespace string `mapstructure:"namespace"`
CRDVersion string `mapstructure:"crdVersion"`
CleanupDebounceTime int `mapstructure:"cleanupDebounceTime"`
}
2 changes: 2 additions & 0 deletions pkg/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func (r *Resolver) PolicyReportClient(ctx context.Context) (report.PolicyClient,
r.PolicyReportStore(),
mapper,
time.Now(),
time.Duration(r.config.CleanupDebounceTime),
)

r.policyClient = client
Expand Down Expand Up @@ -141,6 +142,7 @@ func (r *Resolver) ClusterPolicyReportClient(ctx context.Context) (report.Cluste
r.ClusterPolicyReportStore(),
mapper,
time.Now(),
time.Duration(r.config.CleanupDebounceTime),
)

return r.clusterPolicyClient, nil
Expand Down
46 changes: 32 additions & 14 deletions pkg/kubernetes/cluster_policy_report_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ type clusterPolicyReportEvent struct {
}

type clusterPolicyReportEventDebouncer struct {
events map[string]clusterPolicyReportEvent
channel chan<- clusterPolicyReportEvent
mutx *sync.Mutex
events map[string]clusterPolicyReportEvent
channel chan clusterPolicyReportEvent
mutx *sync.Mutex
debounceTime time.Duration
}

func (d *clusterPolicyReportEventDebouncer) Add(e clusterPolicyReportEvent) {
Expand All @@ -41,7 +42,7 @@ func (d *clusterPolicyReportEventDebouncer) Add(e clusterPolicyReportEvent) {
d.mutx.Unlock()

go func() {
time.Sleep(10 * time.Second)
time.Sleep(d.debounceTime * time.Second)

d.mutx.Lock()
if event, ok := d.events[e.report.GetIdentifier()]; ok {
Expand All @@ -65,6 +66,16 @@ func (d *clusterPolicyReportEventDebouncer) Add(e clusterPolicyReportEvent) {
d.channel <- e
}

func (d *clusterPolicyReportEventDebouncer) Reset() {
d.mutx.Lock()
d.events = make(map[string]clusterPolicyReportEvent)
d.mutx.Unlock()
}

func (d *clusterPolicyReportEventDebouncer) ReportChan() chan clusterPolicyReportEvent {
return d.channel
}

type clusterPolicyReportClient struct {
policyAPI PolicyReportAdapter
store *report.ClusterPolicyReportStore
Expand All @@ -75,6 +86,7 @@ type clusterPolicyReportClient struct {
skipExisting bool
started bool
modifyHash map[string]string
debouncer clusterPolicyReportEventDebouncer
}

func (c *clusterPolicyReportClient) RegisterCallback(cb report.ClusterPolicyReportCallback) {
Expand Down Expand Up @@ -124,8 +136,6 @@ func (c *clusterPolicyReportClient) StartWatching() error {
}

c.started = true
reportChan := make(chan clusterPolicyReportEvent)

errorChan := make(chan error)
go func() {
for {
Expand All @@ -135,16 +145,12 @@ func (c *clusterPolicyReportClient) StartWatching() error {
errorChan <- err
}

debouncer := clusterPolicyReportEventDebouncer{
events: make(map[string]clusterPolicyReportEvent, 0),
mutx: new(sync.Mutex),
channel: reportChan,
}
c.debouncer.Reset()

for result := range result.ResultChan() {
if item, ok := result.Object.(*unstructured.Unstructured); ok {
report := c.mapper.MapClusterPolicyReport(item.Object)
debouncer.Add(clusterPolicyReportEvent{report, result.Type})
c.debouncer.Add(clusterPolicyReportEvent{report, result.Type})
}
}

Expand All @@ -154,7 +160,7 @@ func (c *clusterPolicyReportClient) StartWatching() error {
}()

go func() {
for event := range reportChan {
for event := range c.debouncer.ReportChan() {
c.executeClusterPolicyReportHandler(event.eventType, event.report)
}

Expand Down Expand Up @@ -273,12 +279,24 @@ func (c *clusterPolicyReportClient) RegisterPolicyResultWatcher(skipExisting boo
}

// NewPolicyReportClient creates a new PolicyReportClient based on the kubernetes go-client
func NewClusterPolicyReportClient(client PolicyReportAdapter, store *report.ClusterPolicyReportStore, mapper Mapper, startUp time.Time) report.ClusterPolicyClient {
func NewClusterPolicyReportClient(
client PolicyReportAdapter,
store *report.ClusterPolicyReportStore,
mapper Mapper,
startUp time.Time,
debounceTime time.Duration,
) report.ClusterPolicyClient {
return &clusterPolicyReportClient{
policyAPI: client,
store: store,
mapper: mapper,
startUp: startUp,
modifyHash: make(map[string]string),
debouncer: clusterPolicyReportEventDebouncer{
events: make(map[string]clusterPolicyReportEvent, 0),
mutx: new(sync.Mutex),
channel: make(chan clusterPolicyReportEvent),
debounceTime: debounceTime,
},
}
}
Loading

0 comments on commit 5b7a553

Please sign in to comment.