2019-08-14 14:56:53 -07:00
package namespace
import (
"fmt"
"github.com/golang/glog"
2019-11-13 13:41:08 -08:00
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
2019-08-26 13:34:42 -07:00
"github.com/nirmata/kyverno/pkg/engine"
2019-08-14 14:56:53 -07:00
"github.com/nirmata/kyverno/pkg/event"
2019-11-12 13:32:30 -08:00
"github.com/nirmata/kyverno/pkg/policyviolation"
2019-08-14 14:56:53 -07:00
)
2019-10-08 10:57:24 -07:00
func ( nsc * NamespaceController ) report ( engineResponses [ ] engine . EngineResponse ) {
2019-08-14 14:56:53 -07:00
// generate events
2019-11-12 14:41:29 -08:00
eventInfos := generateEvents ( engineResponses )
nsc . eventGen . Add ( eventInfos ... )
2019-08-14 14:56:53 -07:00
// generate policy violations
2019-11-12 14:41:29 -08:00
pvInfos := generatePVs ( engineResponses )
nsc . pvGenerator . Add ( pvInfos ... )
}
func generatePVs ( ers [ ] engine . EngineResponse ) [ ] policyviolation . Info {
var pvInfos [ ] policyviolation . Info
for _ , er := range ers {
// ignore creation of PV for resoruces that are yet to be assigned a name
if er . PolicyResponse . Resource . Name == "" {
glog . V ( 4 ) . Infof ( "resource %v, has not been assigned a name, not creating a policy violation for it" , er . PolicyResponse . Resource )
continue
}
if er . IsSuccesful ( ) {
continue
}
glog . V ( 4 ) . Infof ( "Building policy violation for engine response %v" , er )
// build policy violation info
pvInfos = append ( pvInfos , buildPVInfo ( er ) )
2019-08-14 14:56:53 -07:00
}
2019-11-12 14:41:29 -08:00
return pvInfos
2019-08-14 14:56:53 -07:00
}
2019-11-12 14:41:29 -08:00
func buildPVInfo ( er engine . EngineResponse ) policyviolation . Info {
info := policyviolation . Info {
Blocked : false ,
PolicyName : er . PolicyResponse . Policy ,
Resource : er . PatchedResource ,
Rules : buildViolatedRules ( er ) ,
2019-08-14 14:56:53 -07:00
}
2019-11-12 14:41:29 -08:00
return info
}
func buildViolatedRules ( er engine . EngineResponse ) [ ] kyverno . ViolatedRule {
var violatedRules [ ] kyverno . ViolatedRule
for _ , rule := range er . PolicyResponse . Rules {
2019-08-26 13:34:42 -07:00
if rule . Success {
2019-11-12 14:41:29 -08:00
continue
}
vrule := kyverno . ViolatedRule {
Name : rule . Name ,
Type : rule . Type ,
Message : rule . Message ,
}
violatedRules = append ( violatedRules , vrule )
}
return violatedRules
}
func generateEvents ( ers [ ] engine . EngineResponse ) [ ] event . Info {
var eventInfos [ ] event . Info
for _ , er := range ers {
if er . IsSuccesful ( ) {
continue
}
eventInfos = append ( eventInfos , generateEventsPerEr ( er ) ... )
}
return eventInfos
}
func generateEventsPerEr ( er engine . EngineResponse ) [ ] event . Info {
var eventInfos [ ] event . Info
glog . V ( 4 ) . Infof ( "reporting results for policy '%s' application on resource '%s/%s/%s'" , er . PolicyResponse . Policy , er . PolicyResponse . Resource . Kind , er . PolicyResponse . Resource . Namespace , er . PolicyResponse . Resource . Name )
for _ , rule := range er . PolicyResponse . Rules {
if rule . Success {
continue
2019-08-14 14:56:53 -07:00
}
// generate event on resource for each failed rule
2019-11-12 14:41:29 -08:00
glog . V ( 4 ) . Infof ( "generation event on resource '%s/%s' for policy '%s'" , er . PolicyResponse . Resource . Kind , er . PolicyResponse . Resource . Name , er . PolicyResponse . Policy )
2019-08-26 13:34:42 -07:00
e := event . Info { }
2019-11-12 14:41:29 -08:00
e . Kind = er . PolicyResponse . Resource . Kind
2019-09-12 15:04:35 -07:00
e . Namespace = "" // event generate on namespace resource
2019-11-12 14:41:29 -08:00
e . Name = er . PolicyResponse . Resource . Name
2019-08-14 14:56:53 -07:00
e . Reason = "Failure"
2019-11-12 14:41:29 -08:00
e . Message = fmt . Sprintf ( "policy '%s' (%s) rule '%s' failed to apply. %v" , er . PolicyResponse . Policy , rule . Type , rule . Name , rule . Message )
eventInfos = append ( eventInfos , e )
}
if er . IsSuccesful ( ) {
return eventInfos
2019-08-14 14:56:53 -07:00
}
// generate a event on policy for all failed rules
2019-11-12 14:41:29 -08:00
glog . V ( 4 ) . Infof ( "generation event on policy '%s'" , er . PolicyResponse . Policy )
2019-08-26 13:34:42 -07:00
e := event . Info { }
2019-09-12 15:04:35 -07:00
e . Kind = "ClusterPolicy"
2019-08-14 14:56:53 -07:00
e . Namespace = ""
2019-11-12 14:41:29 -08:00
e . Name = er . PolicyResponse . Policy
2019-08-14 14:56:53 -07:00
e . Reason = "Failure"
2019-11-12 14:41:29 -08:00
e . Message = fmt . Sprintf ( "failed to apply policy '%s' rules '%v' on resource '%s/%s/%s'" , er . PolicyResponse . Policy , er . GetFailedRules ( ) , er . PolicyResponse . Resource . Kind , er . PolicyResponse . Resource . Namespace , er . PolicyResponse . Resource . Name )
return eventInfos
2019-08-14 14:56:53 -07:00
}