1
0
Fork 0
mirror of https://github.com/kyverno/policy-reporter.git synced 2024-12-14 11:57:32 +00:00
policy-reporter/pkg/metrics/metrics.go
2021-02-20 11:00:10 +01:00

117 lines
3.6 KiB
Go

package metrics
import (
"sync"
"github.com/fjogeleit/policy-reporter/pkg/kubernetes"
"github.com/fjogeleit/policy-reporter/pkg/report"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"k8s.io/apimachinery/pkg/watch"
)
type Metrics struct {
client kubernetes.Client
cache map[string]report.PolicyReport
rwmutex *sync.RWMutex
}
func (m Metrics) getCachedReport(i string) report.PolicyReport {
m.rwmutex.RLock()
defer m.rwmutex.RUnlock()
return m.cache[i]
}
func (m Metrics) cachedReport(r report.PolicyReport) {
m.rwmutex.Lock()
m.cache[r.GetIdentifier()] = r
m.rwmutex.Unlock()
}
func (m Metrics) removeCachedReport(i string) {
m.rwmutex.Lock()
delete(m.cache, i)
m.rwmutex.Unlock()
}
func (m Metrics) GenerateMetrics() {
policyGauge := promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "policy_report_summary",
Help: "Summary of all PolicyReports",
}, []string{"namespace", "name", "status"})
ruleGauge := promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "policy_report_result",
Help: "List of all PolicyReport Results",
}, []string{"namespace", "rule", "policy", "kind", "name", "status"})
prometheus.Register(policyGauge)
prometheus.Register(ruleGauge)
m.client.WatchPolicyReports(func(e watch.EventType, r report.PolicyReport) {
go func(event watch.EventType, report report.PolicyReport) {
switch event {
case watch.Added:
updatePolicyGauge(policyGauge, report)
for _, rule := range report.Results {
res := rule.Resources[0]
ruleGauge.WithLabelValues(report.Namespace, rule.Rule, rule.Policy, res.Kind, res.Name, rule.Status).Set(1)
}
m.cachedReport(report)
case watch.Modified:
updatePolicyGauge(policyGauge, report)
for _, rule := range m.getCachedReport(report.GetIdentifier()).Results {
res := rule.Resources[0]
ruleGauge.WithLabelValues(report.Namespace, rule.Rule, rule.Policy, res.Kind, res.Name, rule.Status).Set(0)
}
for _, rule := range report.Results {
res := rule.Resources[0]
ruleGauge.WithLabelValues(report.Namespace, rule.Rule, rule.Policy, res.Kind, res.Name, rule.Status).Set(1)
}
case watch.Deleted:
policyGauge.WithLabelValues(report.Namespace, report.Name, "Pass").Set(0)
policyGauge.WithLabelValues(report.Namespace, report.Name, "Fail").Set(0)
policyGauge.WithLabelValues(report.Namespace, report.Name, "Warn").Set(0)
policyGauge.WithLabelValues(report.Namespace, report.Name, "Error").Set(0)
policyGauge.WithLabelValues(report.Namespace, report.Name, "Skip").Set(0)
for _, rule := range report.Results {
res := rule.Resources[0]
ruleGauge.WithLabelValues(report.Namespace, rule.Rule, rule.Policy, res.Kind, res.Name, rule.Status).Set(0)
}
m.removeCachedReport(report.GetIdentifier())
}
}(e, r)
})
}
func updatePolicyGauge(policyGauge *prometheus.GaugeVec, report report.PolicyReport) {
policyGauge.
WithLabelValues(report.Namespace, report.Name, "Pass").
Set(float64(report.Summary.Pass))
policyGauge.
WithLabelValues(report.Namespace, report.Name, "Fail").
Set(float64(report.Summary.Fail))
policyGauge.
WithLabelValues(report.Namespace, report.Name, "Warn").
Set(float64(report.Summary.Warn))
policyGauge.
WithLabelValues(report.Namespace, report.Name, "Error").
Set(float64(report.Summary.Error))
policyGauge.
WithLabelValues(report.Namespace, report.Name, "Skip").
Set(float64(report.Summary.Skip))
}
func NewMetrics(client kubernetes.Client) *Metrics {
return &Metrics{
client: client,
cache: make(map[string]report.PolicyReport),
rwmutex: new(sync.RWMutex),
}
}