1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-09 09:26:54 +00:00
kyverno/pkg/webhooks/utils.go

154 lines
4.6 KiB
Go
Raw Normal View History

2019-06-18 11:47:45 -07:00
package webhooks
import (
2019-07-15 16:07:56 -07:00
"fmt"
2019-06-18 11:47:45 -07:00
"strings"
2019-06-19 14:05:23 -07:00
2019-07-19 12:47:20 -07:00
"github.com/golang/glog"
2019-11-13 13:41:08 -08:00
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
2019-08-23 18:34:23 -07:00
"github.com/nirmata/kyverno/pkg/engine"
"k8s.io/api/admission/v1beta1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
2019-06-18 11:47:45 -07:00
)
2019-10-08 10:57:24 -07:00
func isResponseSuccesful(engineReponses []engine.EngineResponse) bool {
2019-08-23 18:34:23 -07:00
for _, er := range engineReponses {
if !er.IsSuccesful() {
return false
}
}
return true
}
// returns true -> if there is even one policy that blocks resource request
2019-08-23 18:34:23 -07:00
// returns false -> if all the policies are meant to report only, we dont block resource request
2019-10-08 10:57:24 -07:00
func toBlockResource(engineReponses []engine.EngineResponse) bool {
2019-08-23 18:34:23 -07:00
for _, er := range engineReponses {
if er.PolicyResponse.ValidationFailureAction == Enforce {
glog.V(4).Infof("ValidationFailureAction set to enforce for policy %s , blocking resource request ", er.PolicyResponse.Policy)
2019-08-23 18:34:23 -07:00
return true
}
}
glog.V(4).Infoln("ValidationFailureAction set to audit, allowing resource request, reporting with policy violation")
2019-08-23 18:34:23 -07:00
return false
}
2019-10-08 10:57:24 -07:00
func getErrorMsg(engineReponses []engine.EngineResponse) string {
2019-08-23 18:34:23 -07:00
var str []string
var resourceInfo string
2019-08-23 18:34:23 -07:00
for _, er := range engineReponses {
if !er.IsSuccesful() {
// resource in engineReponses is identical as this was called per admission request
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
2019-08-30 01:08:54 -07:00
str = append(str, fmt.Sprintf("failed policy %s", er.PolicyResponse.Policy))
2019-08-23 18:34:23 -07:00
for _, rule := range er.PolicyResponse.Rules {
if !rule.Success {
str = append(str, rule.ToString())
}
}
}
}
return fmt.Sprintf("Resource %s: %s", resourceInfo, strings.Join(str, "\n"))
2019-08-23 18:34:23 -07:00
}
2019-07-23 00:55:45 -04:00
//ArrayFlags to store filterkinds
2019-06-18 11:47:45 -07:00
type ArrayFlags []string
func (i *ArrayFlags) String() string {
var sb strings.Builder
for _, str := range *i {
sb.WriteString(str)
}
return sb.String()
}
2019-07-23 00:55:45 -04:00
//Set setter for array flags
2019-06-18 11:47:45 -07:00
func (i *ArrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}
2019-06-19 14:05:23 -07:00
// extract the kinds that the policy rules apply to
func getApplicableKindsForPolicy(p *kyverno.ClusterPolicy) []string {
2019-06-19 14:05:23 -07:00
kinds := []string{}
// iterate over the rules an identify all kinds
2019-07-23 23:34:03 -04:00
// Matching
2019-06-19 14:05:23 -07:00
for _, rule := range p.Spec.Rules {
2019-07-23 23:34:03 -04:00
for _, k := range rule.MatchResources.Kinds {
2019-09-04 10:40:49 -07:00
kinds = append(kinds, k)
2019-07-23 23:34:03 -04:00
}
2019-06-19 14:05:23 -07:00
}
return kinds
}
// Policy Reporting Modes
const (
Enforce = "enforce" // blocks the request on failure
Audit = "audit" // dont block the request on failure, but report failiures as policy violations
)
2019-07-16 15:53:14 -07:00
2019-08-23 18:34:23 -07:00
func processResourceWithPatches(patch []byte, resource []byte) []byte {
if patch == nil {
return nil
}
2019-10-07 18:31:14 -07:00
2019-08-23 18:34:23 -07:00
resource, err := engine.ApplyPatchNew(resource, patch)
if err != nil {
2019-08-26 16:10:19 -07:00
glog.Errorf("failed to patch resource: %v", err)
2019-08-23 18:34:23 -07:00
return nil
}
return resource
}
2019-11-11 14:52:09 -08:00
func containRBACinfo(policies []kyverno.ClusterPolicy) bool {
2019-11-11 14:52:09 -08:00
for _, policy := range policies {
for _, rule := range policy.Spec.Rules {
if len(rule.MatchResources.Roles) > 0 || len(rule.MatchResources.ClusterRoles) > 0 {
2019-11-11 14:52:09 -08:00
return true
}
}
}
return false
}
// extracts the new and old resource as unstructured
func extractResources(request *v1beta1.AdmissionRequest) (unstructured.Unstructured, unstructured.Unstructured, error) {
var emptyResource unstructured.Unstructured
var err error
// New Resource
newRaw := request.Object.Raw
if newRaw == nil {
return emptyResource, emptyResource, fmt.Errorf("new resource is not defined")
}
new, err := convertToUnstructured(newRaw)
if err != nil {
return emptyResource, emptyResource, fmt.Errorf("failed to convert new raw to unstructured: %v", err)
}
new.SetGroupVersionKind(schema.GroupVersionKind{Group: request.Kind.Group, Version: request.Kind.Version, Kind: request.Kind.Kind})
new.SetNamespace(request.Namespace)
// Old Resource - Optional
oldRaw := request.OldObject.Raw
if oldRaw == nil {
return *new, emptyResource, nil
}
old, err := convertToUnstructured((oldRaw))
if err != nil {
return emptyResource, emptyResource, fmt.Errorf("failed to convert old raw to unstructured: %v", err)
}
old.SetGroupVersionKind(schema.GroupVersionKind{Group: request.Kind.Group, Version: request.Kind.Version, Kind: request.Kind.Kind})
old.SetNamespace(request.Namespace)
return *new, *old, err
}
func convertToUnstructured(data []byte) (*unstructured.Unstructured, error) {
resource := &unstructured.Unstructured{}
err := resource.UnmarshalJSON(data)
if err != nil {
glog.V(4).Infof("failed to unmarshall resource: %v", err)
return nil, err
}
return resource, nil
}