1
0
Fork 0
mirror of https://github.com/kyverno/policy-reporter.git synced 2024-12-14 11:57:32 +00:00

Add global.labels and health APIs (#40)

* Add global.labels and health APIs
* Fix manifest readme path
* go.mod update
This commit is contained in:
Frank Jogeleit 2021-05-29 10:57:06 +02:00 committed by GitHub
parent 4ee91e898f
commit 29049b7828
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 232 additions and 51 deletions

View file

@ -1,6 +1,13 @@
# Changelog
# 1.7.0
* Enable REST API by default
* Add `/healthz` and `/ready` APIs as new endpoints for readinessProbe and livenessProbe
* Helm Chart Updates
* Add `global.labels` to add `labels` on every resource created
* Add default labels on every resource
# 1.6.2
* Increase Result Caching Time to handle Kyverno issues with Policy reconcilation [Issue](https://github.com/kyverno/kyverno/issues/1921)
* Fix golint errors

View file

@ -1,12 +1,12 @@
dependencies:
- name: monitoring
repository: ""
version: 1.2.0
version: 1.3.0
- name: ui
repository: ""
version: 1.6.0
version: 1.7.0
- name: kyvernoPlugin
repository: ""
version: 0.2.0
digest: sha256:c32c38e295ebe08651a81937858ba920212bd075aa7605189919c20820067e85
generated: "2021-05-21T10:53:50.045598+02:00"
version: 0.3.0
digest: sha256:e5b478e8c16d73531126c3b4331c92c1fb8bc89db412a46ddce22f6d45b26ccc
generated: "2021-05-29T09:48:14.131726+02:00"

View file

@ -5,19 +5,19 @@ description: |
It creates Prometheus Metrics and can send rule validation events to different targets like Loki, Elasticsearch, Slack or Discord
type: application
version: 1.6.2
appVersion: 1.6.1
version: 1.7.0
appVersion: 1.7.0
dependencies:
- name: monitoring
condition: monitoring.enabled
repository: ""
version: "1.2.0"
version: "1.3.0"
- name: ui
condition: ui.enabled
repository: ""
version: "1.6.0"
version: "1.7.0"
- name: kyvernoPlugin
condition: kyvernoPlugin.enabled
repository: ""
version: "0.2.0"
version: "0.3.0"

View file

@ -3,5 +3,5 @@ name: kyvernoPlugin
description: Policy Reporter Kyverno Plugin
type: application
version: 0.2.0
version: 0.3.0
appVersion: 0.1.1

View file

@ -35,6 +35,9 @@ helm.sh/chart: {{ include "kyvernoplugin.chart" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.global.labels }}
{{ toYaml . }}
{{- end -}}
{{- end }}
{{/*

View file

@ -4,6 +4,7 @@ kind: ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
{{- include "kyvernoplugin.labels" . | nindent 4 }}
name: {{ include "kyvernoplugin.fullname" . }}
rules:
- apiGroups:

View file

@ -3,6 +3,8 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "kyvernoplugin.fullname" . }}
labels:
{{- include "kyvernoplugin.labels" . | nindent 4 }}
roleRef:
kind: ClusterRole
name: {{ include "kyvernoplugin.fullname" . }}

View file

@ -20,6 +20,9 @@ spec:
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.global.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.podAnnotations }}
annotations:
{{- with .Values.podAnnotations }}

View file

@ -3,5 +3,5 @@ name: monitoring
description: Policy Reporter Monitoring with predefined ServiceMonitor and Grafana Dashboards
type: application
version: 1.2.0
version: 1.3.0
appVersion: 0.0.0

View file

@ -13,3 +13,30 @@ If release name contains chart name it will be used as a full name.
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "monitoring.labels" -}}
helm.sh/chart: {{ include "policyreporter.chart" . }}
{{ include "monitoring.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.global.labels }}
{{ toYaml . }}
{{- end -}}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "monitoring.selectorLabels" -}}
app.kubernetes.io/name: {{ include "monitoring.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "monitoring.name" -}}
{{- "monitoring" }}
{{- end }}

View file

@ -5,6 +5,7 @@ metadata:
namespace: {{ .Values.namespace }}
labels:
grafana_dashboard: "1"
{{- include "monitoring.labels" . | nindent 4 }}
data:
cluster-policy-reporter-details-dashboard.json: |
{

View file

@ -3,10 +3,11 @@ apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "monitoring.fullname" . }}-kyverno-plugin
{{- if .Values.serviceMonitor.labels }}
labels:
{{- toYaml .Values.serviceMonitor.labels | nindent 4 }}
{{- end }}
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- include "monitoring.labels" . | nindent 4 }}
spec:
selector:
matchLabels:

View file

@ -5,6 +5,10 @@ metadata:
namespace: {{ .Values.namespace }}
labels:
grafana_dashboard: "1"
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- include "monitoring.labels" . | nindent 4 }}
data:
policy-reporter-dashboard.json: |
{

View file

@ -5,6 +5,10 @@ metadata:
namespace: {{ .Values.namespace }}
labels:
grafana_dashboard: "1"
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- include "monitoring.labels" . | nindent 4 }}
data:
policy-reporter-details-dashboard.json: |
{

View file

@ -2,10 +2,11 @@ apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "monitoring.fullname" . }}
{{- if .Values.serviceMonitor.labels }}
labels:
{{- toYaml .Values.serviceMonitor.labels | nindent 4 }}
{{- end }}
{{- include "monitoring.labels" . | nindent 4 }}
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:

View file

@ -3,5 +3,5 @@ name: ui
description: Policy Reporter UI
type: application
version: 1.6.0
version: 1.7.0
appVersion: 0.10.2

View file

@ -35,6 +35,9 @@ helm.sh/chart: {{ include "ui.chart" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.global.labels }}
{{ toYaml . }}
{{- end -}}
{{- end }}
{{/*

View file

@ -20,6 +20,9 @@ spec:
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.global.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.podAnnotations }}
annotations:
{{- with .Values.podAnnotations }}

View file

@ -10,7 +10,7 @@ kind: Ingress
metadata:
name: {{ include "ui.fullname" . }}
labels:
{{- include "ui.selectorLabels" . | nindent 4 }}
{{- include "ui.labels" . | nindent 4 }}
{{- with .Values.ingress.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}

View file

@ -35,6 +35,9 @@ helm.sh/chart: {{ include "policyreporter.chart" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.global.labels }}
{{ toYaml . }}
{{- end -}}
{{- end }}
{{/*

View file

@ -4,6 +4,7 @@ kind: ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
{{- include "policyreporter.labels" . | nindent 4 }}
name: {{ include "policyreporter.fullname" . }}
rules:
- apiGroups:

View file

@ -3,6 +3,8 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "policyreporter.fullname" . }}
labels:
{{- include "policyreporter.labels" . | nindent 4 }}
roleRef:
kind: ClusterRole
name: {{ include "policyreporter.fullname" . }}

View file

@ -24,6 +24,9 @@ spec:
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.global.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
annotations:
checksum/secret: {{ include (print .Template.BasePath "/targetssecret.yaml") . | sha256sum | quote }}
policy-priorities/enabled: {{ .Values.policyPriorities.enabled | quote }}

View file

@ -3,6 +3,8 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "policyreporter.fullname" . }}
labels:
{{- include "policyreporter.labels" . | nindent 4 }}
rules:
- apiGroups:
- ''

View file

@ -3,6 +3,8 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "policyreporter.fullname" . }}
labels:
{{- include "policyreporter.labels" . | nindent 4 }}
roleRef:
kind: Role
name: {{ include "policyreporter.fullname" . }}

View file

@ -1,7 +1,7 @@
image:
repository: fjogeleit/policy-reporter
pullPolicy: IfNotPresent
tag: 1.6.1
tag: 1.7.0
imagePullSecrets: []
@ -93,6 +93,8 @@ global:
# Service Port number
port: 8080
fullnameOverride: ""
# additional labels added on each resource
labels: {}
# DEPRECTED - Can be removed
# Policy Reporter watches now for both existing versions by default

View file

@ -26,7 +26,6 @@ func loadConfig(cmd *cobra.Command) (*config.Config, error) {
v := viper.New()
v.SetDefault("namespace", "policy-reporter")
v.SetDefault("api.port", 8080)
cfgFile := ""
@ -72,7 +71,6 @@ func loadConfig(cmd *cobra.Command) (*config.Config, error) {
if flag := cmd.Flags().Lookup("apiPort"); flag != nil {
v.BindPFlag("api.port", flag)
v.BindPFlag("api.enabled", flag)
}
c := &config.Config{}

View file

@ -66,9 +66,7 @@ func newRunCMD() *cobra.Command {
errorChan := make(chan error)
if c.API.Enabled {
go func() { errorChan <- resolver.APIServer().Start() }()
}
go func() { errorChan <- resolver.APIServer().Start() }()
go func() { errorChan <- client.StartWatching() }()
@ -85,7 +83,7 @@ func newRunCMD() *cobra.Command {
// For local usage
cmd.PersistentFlags().StringP("kubeconfig", "k", "", "absolute path to the kubeconfig file")
cmd.PersistentFlags().StringP("config", "c", "", "target configuration file")
cmd.PersistentFlags().IntP("apiPort", "a", 0, "http port for the optional rest api")
cmd.PersistentFlags().IntP("apiPort", "a", 8080, "http port for the optional rest api")
flag.Parse()

3
go.mod
View file

@ -7,7 +7,7 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/magiconair/properties v1.8.4 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/prometheus/client_golang v1.9.0
github.com/prometheus/client_model v0.2.0
@ -17,7 +17,6 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d // indirect
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b // indirect
golang.org/x/text v0.3.5 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect

1
go.sum
View file

@ -552,7 +552,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View file

@ -27,8 +27,8 @@ Configures Policy Reporter UI as Target for Policy Reporter.
### Installation
```bash
kubectl apply -f https://raw.githubusercontent.com/fjogeleit/policy-reporter/main/manifest/kyverno-policy-reporter-ui/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/fjogeleit/policy-reporter/main/manifest/kyverno-policy-reporter-ui/target-secret.yaml
kubectl apply -f https://raw.githubusercontent.com/fjogeleit/policy-reporter/main/manifest/default-policy-reporter-ui/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/fjogeleit/policy-reporter/main/manifest/default-policy-reporter-ui/target-secret.yaml
kubectl apply -f https://raw.githubusercontent.com/fjogeleit/policy-reporter/main/manifest/default-policy-reporter-ui/install.yaml
```

View file

@ -148,7 +148,7 @@ spec:
automountServiceAccountToken: true
containers:
- name: policy-reporter
image: "fjogeleit/policy-reporter:1.6.1"
image: "fjogeleit/policy-reporter:1.7.0"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
@ -161,7 +161,6 @@ spec:
runAsUser: 1234
args:
- --config=/app/config.yaml
- --apiPort=8080
ports:
- name: http
containerPort: 2112
@ -171,12 +170,12 @@ spec:
protocol: TCP
livenessProbe:
httpGet:
path: /metrics
port: http
path: /healthz
port: rest
readinessProbe:
httpGet:
path: /metrics
port: http
path: /ready
port: rest
resources:
{}
volumeMounts:

View file

@ -266,7 +266,7 @@ spec:
automountServiceAccountToken: true
containers:
- name: policy-reporter
image: "fjogeleit/policy-reporter:1.6.1"
image: "fjogeleit/policy-reporter:1.7.0"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
@ -279,7 +279,6 @@ spec:
runAsUser: 1234
args:
- --config=/app/config.yaml
- --apiPort=8080
ports:
- name: http
containerPort: 2112
@ -289,12 +288,12 @@ spec:
protocol: TCP
livenessProbe:
httpGet:
path: /metrics
port: http
path: /ready
port: rest
readinessProbe:
httpGet:
path: /metrics
port: http
path: /healthz
port: rest
resources:
{}
volumeMounts:

View file

@ -84,7 +84,7 @@ spec:
automountServiceAccountToken: true
containers:
- name: policy-reporter
image: "fjogeleit/policy-reporter:1.6.1"
image: "fjogeleit/policy-reporter:1.7.0"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
@ -101,14 +101,17 @@ spec:
- name: http
containerPort: 2112
protocol: TCP
- name: rest
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /metrics
port: http
path: /healthz
port: rest
readinessProbe:
httpGet:
path: /metrics
port: http
path: /ready
port: rest
resources:
{}
volumeMounts:

View file

@ -8,6 +8,34 @@ import (
"github.com/fjogeleit/policy-reporter/pkg/report"
)
// HealthzHandler for the Halthz REST API
func HealthzHandler() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "{}")
}
}
// ReadyHandler for the Halthz REST API
func ReadyHandler(s *report.PolicyReportStore) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
if len(s.List(report.PolicyReportType))+len(s.List(report.ClusterPolicyReportType)) == 0 {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusServiceUnavailable)
fmt.Fprint(w, "{}")
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "{}")
}
}
// PolicyReportHandler for the PolicyReport REST API
func PolicyReportHandler(s *report.PolicyReportStore) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {

View file

@ -195,3 +195,85 @@ func Test_ClusterPolicyReportAPI(t *testing.T) {
}
})
}
func Test_HealthzAPI(t *testing.T) {
t.Run("Respose", func(t *testing.T) {
req, err := http.NewRequest("GET", "/healthz", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.HealthzHandler())
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}
})
}
func Test_ReadyAPI(t *testing.T) {
t.Run("Success Respose", func(t *testing.T) {
req, err := http.NewRequest("GET", "/ready", nil)
if err != nil {
t.Fatal(err)
}
result := 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.ErrorPriority,
Status: report.Fail,
Category: "resources",
Scored: true,
Resource: report.Resource{
APIVersion: "v1",
Kind: "Deployment",
Name: "nginx",
Namespace: "test",
UID: "536ab69f-1b3c-4bd9-9ba4-274a56188409",
},
}
preport := report.PolicyReport{
Name: "polr-test",
Namespace: "test",
Results: map[string]report.Result{"": result},
Summary: report.Summary{},
CreationTimestamp: time.Now(),
}
store := report.NewPolicyReportStore()
store.Add(preport)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ReadyHandler(store))
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}
})
t.Run("Unavailable Respose", func(t *testing.T) {
req, err := http.NewRequest("GET", "/ready", nil)
if err != nil {
t.Fatal(err)
}
store := report.NewPolicyReportStore()
rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ReadyHandler(store))
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusServiceUnavailable {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusServiceUnavailable)
}
})
}

View file

@ -25,6 +25,8 @@ func (s *httpServer) registerHandler() {
s.mux.HandleFunc("/policy-reports", Gzip(PolicyReportHandler(s.store)))
s.mux.HandleFunc("/cluster-policy-reports", Gzip(ClusterPolicyReportHandler(s.store)))
s.mux.HandleFunc("/targets", Gzip(TargetsHandler(s.targets)))
s.mux.HandleFunc("/healthz", HealthzHandler())
s.mux.HandleFunc("/ready", ReadyHandler(s.store))
}
func (s *httpServer) Start() error {

View file

@ -46,8 +46,7 @@ type UI struct {
// API configuration
type API struct {
Enabled bool `mapstructure:"enabled"`
Port int `mapstructure:"port"`
Port int `mapstructure:"port"`
}
// Config of the PolicyReporter