mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-07 00:17:13 +00:00
288 lines
8.8 KiB
Go
Executable file
288 lines
8.8 KiB
Go
Executable file
package policyreport
|
|
|
|
import (
|
|
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
|
policyreportv1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1"
|
|
client "github.com/nirmata/kyverno/pkg/dclient"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"sync"
|
|
)
|
|
|
|
type PolicyReport struct {
|
|
report *policyreportv1alpha1.PolicyReport
|
|
clusterReport *policyreportv1alpha1.ClusterPolicyReport
|
|
violation *kyverno.PolicyViolationTemplate
|
|
k8sClient *client.Client
|
|
mux sync.Mutex
|
|
}
|
|
|
|
func NewPolicyReport(report *policyreportv1alpha1.PolicyReport, clusterReport *policyreportv1alpha1.ClusterPolicyReport, violation *kyverno.PolicyViolationTemplate, client *client.Client) *PolicyReport {
|
|
return &PolicyReport{
|
|
report: report,
|
|
clusterReport: clusterReport,
|
|
violation: violation,
|
|
k8sClient: client,
|
|
}
|
|
}
|
|
|
|
// RemovePolicyViolation
|
|
func (p *PolicyReport) RemovePolicyViolation(name string, pvInfo []Info) *policyreportv1alpha1.PolicyReport {
|
|
defer func() {
|
|
p.mux.Unlock()
|
|
}()
|
|
p.mux.Lock()
|
|
if len(pvInfo) > 0 {
|
|
for _, info := range pvInfo {
|
|
for j, v := range pvInfo[0].Rules {
|
|
for i, result := range p.report.Results {
|
|
if result.Resource.Name == info.Resource.GetName() && result.Policy == info.PolicyName && result.Rule == v.Name {
|
|
_, err := p.k8sClient.GetResource(result.Resource.APIVersion, result.Resource.Kind, result.Resource.Namespace, result.Resource.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
p.report.Results = append(p.report.Results[:i], p.report.Results[i+1:]...)
|
|
p.DecreaseCount(string(result.Status), "NAMESPACE")
|
|
}
|
|
} else {
|
|
if v.Check != string(result.Status) {
|
|
result.Message = v.Message
|
|
p.DecreaseCount(string(result.Status), "NAMESPACE")
|
|
result.Status = policyreportv1alpha1.PolicyStatus(v.Check)
|
|
p.IncreaseCount(string(v.Check), "NAMESPACE")
|
|
}
|
|
|
|
info.Rules = append(info.Rules[:j], info.Rules[j+1:]...)
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for i, result := range p.report.Results {
|
|
if result.Policy == name {
|
|
p.report.Results = append(p.report.Results[:i], p.report.Results[i+1:]...)
|
|
p.DecreaseCount(string(result.Status), "NAMESPACE")
|
|
}
|
|
}
|
|
}
|
|
return p.report
|
|
}
|
|
|
|
//RemoveClusterPolicyViolation
|
|
func (p *PolicyReport) RemoveClusterPolicyViolation(name string, pvInfo []Info) *policyreportv1alpha1.ClusterPolicyReport {
|
|
defer func() {
|
|
p.mux.Unlock()
|
|
}()
|
|
p.mux.Lock()
|
|
if len(pvInfo) > 0 {
|
|
for _, info := range pvInfo {
|
|
for j, v := range info.Rules {
|
|
for i, result := range p.clusterReport.Results {
|
|
if result.Resource.Name == info.Resource.GetName() && result.Policy == info.PolicyName && result.Rule == v.Name {
|
|
_, err := p.k8sClient.GetResource(result.Resource.APIVersion, result.Resource.Kind, result.Resource.Namespace, result.Resource.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
p.report.Results = append(p.report.Results[:i], p.report.Results[i+1:]...)
|
|
p.DecreaseCount(string(result.Status), "CLUSTER")
|
|
}
|
|
} else {
|
|
if v.Check != string(result.Status) {
|
|
result.Message = v.Message
|
|
p.DecreaseCount(string(result.Status), "CLUSTER")
|
|
result.Status = policyreportv1alpha1.PolicyStatus(v.Check)
|
|
p.IncreaseCount(string(v.Check), "CLUSTER")
|
|
}
|
|
info.Rules = append(info.Rules[:j], info.Rules[j+1:]...)
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for i, result := range p.clusterReport.Results {
|
|
if result.Policy == name {
|
|
p.clusterReport.Results = append(p.clusterReport.Results[:i], p.clusterReport.Results[i+1:]...)
|
|
p.DecreaseCount(string(result.Status), "CLUSTER")
|
|
}
|
|
}
|
|
}
|
|
return p.clusterReport
|
|
}
|
|
|
|
// CreatePolicyViolationToPolicyReport
|
|
func (p *PolicyReport) CreatePolicyViolationToPolicyReport() *policyreportv1alpha1.PolicyReport {
|
|
defer func() {
|
|
p.mux.Unlock()
|
|
}()
|
|
p.mux.Lock()
|
|
for _, result := range p.report.Results {
|
|
for i, rule := range p.violation.Spec.ViolatedRules {
|
|
if result.Policy == p.violation.Spec.Policy && result.Rule == rule.Name && result.Resource.Name == p.violation.Spec.Name {
|
|
_, err := p.k8sClient.GetResource(result.Resource.APIVersion, result.Resource.Kind, result.Resource.Namespace, result.Resource.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
p.report.Results = append(p.report.Results[:i], p.report.Results[i+1:]...)
|
|
}
|
|
} else {
|
|
if rule.Check != string(result.Status) {
|
|
p.DecreaseCount(string(result.Status), "NAMESPACE")
|
|
p.IncreaseCount(rule.Check, "NAMESPACE")
|
|
result.Message = rule.Message
|
|
}
|
|
p.violation.Spec.ViolatedRules = append(p.violation.Spec.ViolatedRules[:i], p.violation.Spec.ViolatedRules[i+1:]...)
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
for _, rule := range p.violation.Spec.ViolatedRules {
|
|
_, err := p.k8sClient.GetResource(p.violation.Spec.APIVersion, p.violation.Spec.Kind, p.violation.Spec.Namespace, p.violation.Spec.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
continue
|
|
}
|
|
} else {
|
|
result := &policyreportv1alpha1.PolicyReportResult{
|
|
Policy: p.violation.Spec.Policy,
|
|
Rule: rule.Name,
|
|
Message: rule.Message,
|
|
Status: policyreportv1alpha1.PolicyStatus(rule.Check),
|
|
Resource: &corev1.ObjectReference{
|
|
Kind: p.violation.Spec.Kind,
|
|
Namespace: p.violation.Spec.Namespace,
|
|
APIVersion: p.violation.Spec.APIVersion,
|
|
Name: p.violation.Spec.Name,
|
|
},
|
|
}
|
|
p.IncreaseCount(rule.Check, "NAMESPACE")
|
|
p.report.Results = append(p.report.Results, result)
|
|
}
|
|
|
|
}
|
|
return p.report
|
|
}
|
|
|
|
// ClusterPolicyViolationsToClusterPolicyReport
|
|
func (p *PolicyReport) CreateClusterPolicyViolationsToClusterPolicyReport() *policyreportv1alpha1.ClusterPolicyReport {
|
|
defer func() {
|
|
p.mux.Unlock()
|
|
}()
|
|
p.mux.Lock()
|
|
for _, result := range p.clusterReport.Results {
|
|
for i, rule := range p.violation.Spec.ViolatedRules {
|
|
if result.Policy == p.violation.Spec.Policy && result.Rule == rule.Name && result.Resource.Name == p.violation.Spec.Name {
|
|
_, err := p.k8sClient.GetResource(result.Resource.APIVersion, result.Resource.Kind, result.Resource.Namespace, result.Resource.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
p.clusterReport.Results = append(p.clusterReport.Results[:i], p.clusterReport.Results[i+1:]...)
|
|
continue
|
|
}
|
|
} else {
|
|
if rule.Check != string(result.Status) {
|
|
result.Message = rule.Message
|
|
p.DecreaseCount(string(result.Status), "CLUSTER")
|
|
p.IncreaseCount(rule.Check, "CLUSTER")
|
|
}
|
|
p.violation.Spec.ViolatedRules = append(p.violation.Spec.ViolatedRules[:i], p.violation.Spec.ViolatedRules[i+1:]...)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for _, rule := range p.violation.Spec.ViolatedRules {
|
|
_, err := p.k8sClient.GetResource(p.violation.Spec.APIVersion, p.violation.Spec.Kind, p.violation.Spec.Namespace, p.violation.Spec.Name)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
continue
|
|
}
|
|
} else {
|
|
result := &policyreportv1alpha1.PolicyReportResult{
|
|
Policy: p.violation.Spec.Policy,
|
|
Rule: rule.Name,
|
|
Message: rule.Message,
|
|
Status: policyreportv1alpha1.PolicyStatus(rule.Check),
|
|
Resource: &corev1.ObjectReference{
|
|
Kind: p.violation.Spec.Kind,
|
|
Namespace: p.violation.Spec.Namespace,
|
|
APIVersion: p.violation.Spec.APIVersion,
|
|
Name: p.violation.Spec.Name,
|
|
},
|
|
}
|
|
p.IncreaseCount(rule.Check, "CLUSTER")
|
|
p.clusterReport.Results = append(p.clusterReport.Results, result)
|
|
}
|
|
|
|
}
|
|
return p.clusterReport
|
|
}
|
|
|
|
func (p *PolicyReport) DecreaseCount(status string, scope string) {
|
|
if scope == "CLUSTER" {
|
|
switch status {
|
|
case "Pass":
|
|
if p.clusterReport.Summary.Pass--; p.clusterReport.Summary.Pass < 0 {
|
|
p.clusterReport.Summary.Pass = 0
|
|
}
|
|
break
|
|
case "Fail":
|
|
if p.clusterReport.Summary.Fail--; p.clusterReport.Summary.Fail < 0 {
|
|
p.clusterReport.Summary.Fail = 0
|
|
}
|
|
break
|
|
default:
|
|
if p.clusterReport.Summary.Skip--; p.clusterReport.Summary.Skip < 0 {
|
|
p.clusterReport.Summary.Skip = 0
|
|
}
|
|
break
|
|
}
|
|
} else {
|
|
switch status {
|
|
case "Pass":
|
|
if p.report.Summary.Pass--; p.report.Summary.Pass < 0 {
|
|
p.report.Summary.Pass = 0
|
|
}
|
|
break
|
|
case "Fail":
|
|
if p.report.Summary.Fail--; p.report.Summary.Fail < 0 {
|
|
p.report.Summary.Fail = 0
|
|
}
|
|
break
|
|
default:
|
|
if p.report.Summary.Skip--; p.report.Summary.Skip < 0 {
|
|
p.report.Summary.Skip = 0
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (p *PolicyReport) IncreaseCount(status string, scope string) {
|
|
if scope == "CLUSTER" {
|
|
switch status {
|
|
case "Pass":
|
|
p.clusterReport.Summary.Pass++
|
|
break
|
|
case "Fail":
|
|
p.clusterReport.Summary.Fail++
|
|
break
|
|
default:
|
|
p.clusterReport.Summary.Skip++
|
|
break
|
|
}
|
|
} else {
|
|
switch status {
|
|
case "Pass":
|
|
p.report.Summary.Pass++
|
|
break
|
|
case "Fail":
|
|
p.report.Summary.Fail++
|
|
break
|
|
default:
|
|
p.report.Summary.Skip++
|
|
break
|
|
}
|
|
}
|
|
|
|
}
|