2019-11-08 20:45:26 -08:00
package policy
import (
"fmt"
"reflect"
2020-03-17 11:05:20 -07:00
"github.com/go-logr/logr"
2020-10-07 11:12:31 -07:00
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
2019-11-08 20:45:26 -08:00
"k8s.io/apimachinery/pkg/labels"
)
2020-03-17 11:05:20 -07:00
func ( pc * PolicyController ) cleanUp ( ers [ ] response . EngineResponse ) {
for _ , er := range ers {
2020-06-30 11:53:27 -07:00
if ! er . IsSuccessful ( ) {
2020-03-17 11:05:20 -07:00
continue
}
if len ( er . PolicyResponse . Rules ) == 0 {
continue
}
// clean up after the policy has been corrected
pc . cleanUpPolicyViolation ( er . PolicyResponse )
}
}
2019-12-12 15:02:59 -08:00
func ( pc * PolicyController ) cleanUpPolicyViolation ( pResponse response . PolicyResponse ) {
2020-03-17 11:05:20 -07:00
logger := pc . log
2020-01-06 17:07:11 -08:00
// - check if there is violation on resource (label:Selector)
2019-11-14 13:06:56 -08:00
if pResponse . Resource . Namespace == "" {
2020-03-17 11:05:20 -07:00
pv , err := getClusterPV ( pc . cpvLister , pResponse . Policy , pResponse . Resource . Kind , pResponse . Resource . Name , logger )
2019-11-14 13:06:56 -08:00
if err != nil {
2020-03-17 11:05:20 -07:00
logger . Error ( err , "failed to get cluster policy violation on policy and resource" , "policy" , pResponse . Policy , "kind" , pResponse . Resource . Kind , "name" , pResponse . Resource . Name )
2019-11-14 13:06:56 -08:00
return
}
2019-11-14 12:01:41 -08:00
2020-01-06 17:07:11 -08:00
if reflect . DeepEqual ( pv , kyverno . ClusterPolicyViolation { } ) {
return
}
if err := pc . pvControl . DeleteClusterPolicyViolation ( pv . Name ) ; err != nil {
2020-03-17 11:05:20 -07:00
logger . Error ( err , "failed to delete cluster policy violation" , "name" , pv . Name )
} else {
logger . Info ( "deleted cluster policy violation" , "name" , pv . Name )
2019-11-08 20:45:26 -08:00
}
2019-11-14 13:06:56 -08:00
return
}
2020-01-06 17:07:11 -08:00
// namespace policy violation
2020-03-17 11:05:20 -07:00
nspv , err := getNamespacedPV ( pc . nspvLister , pResponse . Policy , pResponse . Resource . Kind , pResponse . Resource . Namespace , pResponse . Resource . Name , logger )
2019-11-14 13:06:56 -08:00
if err != nil {
2020-03-17 11:05:20 -07:00
logger . Error ( err , "failed to get namespaced policy violation on policy and resource" , "policy" , pResponse . Policy , "kind" , pResponse . Resource . Kind , "namespace" , pResponse . Resource . Namespace , "name" , pResponse . Resource . Name )
2019-11-14 13:06:56 -08:00
return
}
2020-01-06 17:07:11 -08:00
if reflect . DeepEqual ( nspv , kyverno . PolicyViolation { } ) {
return
}
if err := pc . pvControl . DeleteNamespacedPolicyViolation ( nspv . Namespace , nspv . Name ) ; err != nil {
2020-03-17 11:05:20 -07:00
logger . Error ( err , "failed to delete cluster policy violation" , "name" , nspv . Name , "namespace" , nspv . Namespace )
} else {
logger . Info ( "deleted namespaced policy violation" , "name" , nspv . Name , "namespace" , nspv . Namespace )
2019-11-08 20:45:26 -08:00
}
}
2020-01-06 17:07:11 -08:00
// Wont do the claiming of objects, just lookup based on selectors
2020-03-17 11:05:20 -07:00
func getClusterPV ( pvLister kyvernolister . ClusterPolicyViolationLister , policyName , rkind , rname string , log logr . Logger ) ( kyverno . ClusterPolicyViolation , error ) {
2019-11-08 20:45:26 -08:00
var err error
// Check Violation on resource
2019-11-14 13:06:56 -08:00
pvs , err := pvLister . List ( labels . Everything ( ) )
if err != nil {
2020-03-17 11:05:20 -07:00
log . Error ( err , "failed to list cluster policy violations" )
2019-11-14 13:06:56 -08:00
return kyverno . ClusterPolicyViolation { } , fmt . Errorf ( "failed to list cluster pv: %v" , err )
}
for _ , pv := range pvs {
// find a policy on same resource and policy combination
if pv . Spec . Policy == policyName &&
2020-01-06 17:07:11 -08:00
pv . Spec . ResourceSpec . Kind == rkind &&
pv . Spec . ResourceSpec . Name == rname {
2019-11-14 13:06:56 -08:00
return * pv , nil
}
}
return kyverno . ClusterPolicyViolation { } , nil
}
2020-03-17 11:05:20 -07:00
func getNamespacedPV ( nspvLister kyvernolister . PolicyViolationLister , policyName , rkind , rnamespace , rname string , log logr . Logger ) ( kyverno . PolicyViolation , error ) {
2020-01-06 17:07:11 -08:00
nspvs , err := nspvLister . PolicyViolations ( rnamespace ) . List ( labels . Everything ( ) )
2019-11-08 20:45:26 -08:00
if err != nil {
2020-03-17 11:05:20 -07:00
log . Error ( err , "failed to list namespaced policy violation" )
2019-12-11 16:09:05 -08:00
return kyverno . PolicyViolation { } , fmt . Errorf ( "failed to list namespaced pv: %v" , err )
2019-11-08 20:45:26 -08:00
}
2019-11-12 16:01:09 -08:00
2019-11-14 12:01:41 -08:00
for _ , nspv := range nspvs {
2019-11-12 16:01:09 -08:00
// find a policy on same resource and policy combination
2019-11-14 12:01:41 -08:00
if nspv . Spec . Policy == policyName &&
2020-01-06 17:07:11 -08:00
nspv . Spec . ResourceSpec . Kind == rkind &&
nspv . Spec . ResourceSpec . Name == rname {
2019-11-14 12:01:41 -08:00
return * nspv , nil
2019-11-12 16:01:09 -08:00
}
2019-11-08 20:45:26 -08:00
}
2019-11-14 12:01:41 -08:00
2020-01-06 17:07:11 -08:00
return kyverno . PolicyViolation { } , nil
2019-11-08 20:45:26 -08:00
}