2019-05-13 18:17:28 -07:00
package engine
2019-05-09 22:26:22 -07:00
import (
2019-05-13 21:27:47 +03:00
kubepolicy "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
2019-05-13 18:17:28 -07:00
"github.com/nirmata/kube-policy/pkg/engine/mutation"
2019-05-09 22:26:22 -07:00
)
2019-05-13 21:27:47 +03:00
// Mutate performs mutation. Overlay first and then mutation patches
func ( p * policyEngine ) Mutate ( policy kubepolicy . Policy , rawResource [ ] byte ) [ ] mutation . PatchBytes {
2019-05-09 22:26:22 -07:00
var policyPatches [ ] mutation . PatchBytes
2019-05-13 21:27:47 +03:00
for i , rule := range policy . Spec . Rules {
// Checks for preconditions
// TODO: Rework PolicyEngine interface that it receives not a policy, but mutation object for
// Mutate, validation for Validate and so on. It will allow to bring this checks outside of PolicyEngine
// to common part as far as they present for all: mutation, validation, generation
2019-05-09 22:26:22 -07:00
err := rule . Validate ( )
if err != nil {
2019-05-13 21:27:47 +03:00
p . logger . Printf ( "Rule has invalid structure: rule number = %d, rule name = %s in policy %s, err: %v\n" , i , rule . Name , policy . ObjectMeta . Name , err )
2019-05-09 22:26:22 -07:00
continue
}
2019-05-13 21:27:47 +03:00
ok , err := mutation . IsRuleApplicableToResource ( rawResource , rule . ResourceDescription )
2019-05-09 22:26:22 -07:00
if err != nil {
2019-05-13 21:27:47 +03:00
p . logger . Printf ( "Rule has invalid data: rule number = %d, rule name = %s in policy %s, err: %v\n" , i , rule . Name , policy . ObjectMeta . Name , err )
continue
2019-05-09 22:26:22 -07:00
}
2019-05-13 21:27:47 +03:00
if ! ok {
p . logger . Printf ( "Rule is not applicable t the request: rule number = %d, rule name = %s in policy %s, err: %v\n" , i , rule . Name , policy . ObjectMeta . Name , err )
continue
2019-05-09 22:26:22 -07:00
}
2019-05-13 21:27:47 +03:00
// Process Overlay
2019-05-09 22:26:22 -07:00
2019-05-13 21:27:47 +03:00
if rule . Mutation . Overlay != nil {
overlayPatches , err := mutation . ProcessOverlay ( rule . Mutation . Overlay , rawResource )
if err != nil {
p . logger . Printf ( "Overlay application failed: rule number = %d, rule name = %s in policy %s, err: %v\n" , i , rule . Name , policy . ObjectMeta . Name , err )
} else {
policyPatches = append ( policyPatches , overlayPatches ... )
}
2019-05-09 22:26:22 -07:00
}
2019-05-13 21:27:47 +03:00
// Process Patches
2019-05-09 22:26:22 -07:00
2019-05-13 21:27:47 +03:00
if rule . Mutation . Patches != nil {
processedPatches , err := mutation . ProcessPatches ( rule . Mutation . Patches , rawResource )
if err != nil {
p . logger . Printf ( "Patches application failed: rule number = %d, rule name = %s in policy %s, err: %v\n" , i , rule . Name , policy . ObjectMeta . Name , err )
} else {
policyPatches = append ( policyPatches , processedPatches ... )
}
}
2019-05-09 22:26:22 -07:00
}
2019-05-13 21:27:47 +03:00
return policyPatches
2019-05-09 22:26:22 -07:00
}