mirror of
https://github.com/kyverno/policy-reporter.git
synced 2024-12-14 11:57:32 +00:00
117 lines
3.6 KiB
Go
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),
|
|
}
|
|
}
|