1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-29 10:55:05 +00:00

Added set flag

This commit is contained in:
NoSkillGirl 2020-08-05 23:53:27 +05:30
parent 1b7a295860
commit afe98bb93c
7 changed files with 62 additions and 35 deletions

View file

@ -278,7 +278,7 @@ func main() {
// Sync openAPI definitions of resources
openAPISync := openapi.NewCRDSync(client, openAPIController)
supportMudateValidate := utils.HigherThanKubernetesVersion(client, log.Log, 1, 14, 0)
supportMutateValidate := utils.HigherThanKubernetesVersion(client, log.Log, 1, 14, 0)
// WEBHOOK
// - https server to provide endpoints called based on rules defined in Mutating & Validation webhook configuration
@ -304,7 +304,7 @@ func main() {
grgen,
rWebhookWatcher,
auditHandler,
supportMudateValidate,
supportMutateValidate,
cleanUp,
log.Log.WithName("WebhookServer"),
openAPIController,

View file

@ -5,8 +5,12 @@ import (
"errors"
"fmt"
"io/ioutil"
"github.com/nirmata/kyverno/pkg/engine/context"
"os"
"path/filepath"
"strings"
"time"
@ -50,7 +54,8 @@ func Command() *cobra.Command {
var cmd *cobra.Command
var resourcePaths []string
var cluster bool
var mutateLogPath string
var mutatelogPath, variablesString string
variables := make(map[string]string)
kubernetesConfig := genericclioptions.NewConfigFlags(true)
@ -63,11 +68,17 @@ func Command() *cobra.Command {
if err != nil {
if !sanitizedError.IsErrorSanitized(err) {
log.Log.Error(err, "failed to sanitize")
err = fmt.Errorf("Internal error")
err = fmt.Errorf("internal error")
}
}
}()
kvpairs := strings.Split(strings.Trim(variablesString, " "), ",")
for _, kvpair := range kvpairs {
kvs := strings.Split(strings.Trim(kvpair, " "), "=")
variables[strings.Trim(kvs[0], " ")] = strings.Trim(kvs[1], " ")
}
if len(resourcePaths) == 0 && !cluster {
return sanitizedError.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
}
@ -150,7 +161,7 @@ func Command() *cobra.Command {
}
for _, resource := range resources {
applyPolicyOnResource(policy, resource, rc)
err = applyPolicyOnResource(policy, resource, mutatelogPath, mutatelogPathIsDir, variables, rc)
if err != nil {
return sanitizedError.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
}
@ -170,7 +181,8 @@ func Command() *cobra.Command {
cmd.Flags().StringArrayVarP(&resourcePaths, "resource", "r", []string{}, "Path to resource files")
cmd.Flags().BoolVarP(&cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
cmd.Flags().StringVarP(&mutateLogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
cmd.Flags().StringVarP(&mutatelogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
cmd.Flags().StringVarP(&variablesString, "set", "s", "", "Variables that are required")
return cmd
}
@ -300,13 +312,29 @@ func getResource(path string) ([]*unstructured.Unstructured, error) {
}
// applyPolicyOnResource - function to apply policy on resource
func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, rc *resultCounts) {
func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, mutatelogPath string, mutatelogPathIsDir bool, variables map[string]string, rc *resultCounts) error {
responseError := false
resPath := fmt.Sprintf("%s/%s/%s", resource.GetNamespace(), resource.GetKind(), resource.GetName())
log.Log.V(3).Info("applying policy on resource", "policy", policy.Name, "resource", resPath)
mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource})
// build context
ctx := context.NewContext()
for key, value := range variables {
startString := ""
endString := ""
for _, k := range strings.Split(key, ".") {
startString += fmt.Sprintf(`{"%s":`, k)
endString += `}`
}
midString := fmt.Sprintf(`"%s"`, value)
finalString := startString + midString + endString
var jsonData = []byte(finalString)
ctx.AddJSON(jsonData)
}
mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource, Context: ctx})
if !mutateResponse.IsSuccessful() {
fmt.Printf("Failed to apply mutate policy %s -> resource %s", policy.Name, resPath)
for i, r := range mutateResponse.PolicyResponse.Rules {
@ -329,7 +357,7 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
}
}
validateResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: mutateResponse.PatchedResource})
validateResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: mutateResponse.PatchedResource, Context: ctx})
if !validateResponse.IsSuccessful() {
fmt.Printf("\npolicy %s -> resource %s failed: \n", policy.Name, resPath)
for i, r := range validateResponse.PolicyResponse.Rules {

View file

@ -9,7 +9,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
jsonpatch "github.com/evanphx/json-patch"
"github.com/go-logr/logr"
@ -69,10 +68,10 @@ func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
}
}
for i := range policies {
setFalse := false
policies[i].Spec.Background = &setFalse
}
// for i := range policies {
// setFalse := false
// policies[i].Spec.Background = &setFalse
// }
return policies, nil
}
@ -152,11 +151,11 @@ func GetPoliciesValidation(policyPaths []string) ([]*v1.ClusterPolicy, *openapi.
}
// PolicyHasVariables - check for variables in policy
func PolicyHasVariables(policy v1.ClusterPolicy) bool {
policyRaw, _ := json.Marshal(policy)
regex := regexp.MustCompile(`\{\{([^{}]*)\}\}`)
return len(regex.FindAllStringSubmatch(string(policyRaw), -1)) > 0
}
// func PolicyHasVariables(policy v1.ClusterPolicy) bool {
// policyRaw, _ := json.Marshal(policy)
// regex := regexp.MustCompile(`\{\{([^{}]*)\}\}`)
// return len(regex.FindAllStringSubmatch(string(policyRaw), -1)) > 0
// }
// MutatePolicy - applies mutation to a policy
func MutatePolicy(policy *v1.ClusterPolicy, logger logr.Logger) (*v1.ClusterPolicy, error) {

View file

@ -49,12 +49,12 @@ func Command() *cobra.Command {
invalidPolicyFound := false
for _, policy := range policies {
if common.PolicyHasVariables(*policy) {
invalidPolicyFound = true
fmt.Printf("Policy %s is invalid.\n", policy.Name)
log.Log.Error(errors.New("'validate' does not support policies with variables"), "Policy "+policy.Name+" is invalid")
continue
}
// if common.PolicyHasVariables(*policy) {
// invalidPolicyFound = true
// fmt.Printf("Policy %s is invalid.\n", policy.Name)
// log.Log.Error(errors.New("'validate' does not support policies with variables"), "Policy "+policy.Name+" is invalid")
// continue
// }
err := policy2.Validate(utils.MarshalPolicy(*policy), nil, true, openAPIController)
if err != nil {
fmt.Printf("Policy %s is invalid.\n", policy.Name)

View file

@ -79,7 +79,7 @@ func defaultvalidationFailureAction(policy *kyverno.ClusterPolicy, log logr.Logg
// set ValidationFailureAction to "audit" if not specified
Audit := common.Audit
if policy.Spec.ValidationFailureAction == "" {
log.V(4).Info("setting defautl value", "spec.validationFailureAction", Audit)
log.V(4).Info("setting default value", "spec.validationFailureAction", Audit)
jsonPatch := struct {
Path string `json:"path"`

View file

@ -18,7 +18,7 @@ func (ws *WebhookServer) policyMutation(request *v1beta1.AdmissionRequest) *v1be
//TODO: can this happen? wont this be picked by OpenAPI spec schema ?
if err := json.Unmarshal(raw, &policy); err != nil {
logger.Error(err, "faield to unmarshall policy admission request")
logger.Error(err, "failed to unmarshall policy admission request")
return &v1beta1.AdmissionResponse{
Allowed: true,
Result: &metav1.Status{

View file

@ -110,7 +110,7 @@ type WebhookServer struct {
log logr.Logger
openAPIController *openapi.Controller
supportMudateValidate bool
supportMutateValidate bool
}
// NewWebhookServer creates new instance of WebhookServer accordingly to given configuration
@ -133,7 +133,7 @@ func NewWebhookServer(
grGenerator *generate.Generator,
resourceWebhookWatcher *webhookconfig.ResourceWebhookRegister,
auditHandler AuditHandler,
supportMudateValidate bool,
supportMutateValidate bool,
cleanUp chan<- struct{},
log logr.Logger,
openAPIController *openapi.Controller,
@ -177,11 +177,11 @@ func NewWebhookServer(
auditHandler: auditHandler,
log: log,
openAPIController: openAPIController,
supportMudateValidate: supportMudateValidate,
supportMutateValidate: supportMutateValidate,
}
mux := httprouter.New()
mux.HandlerFunc("POST", config.MutatingWebhookServicePath, ws.handlerFunc(ws.resourceMutation, true))
mux.HandlerFunc("POST", config.MutatingWebhookServicePath, ws.handlerFunc(ws.ResourceMutation, true))
mux.HandlerFunc("POST", config.ValidatingWebhookServicePath, ws.handlerFunc(ws.resourceValidation, true))
mux.HandlerFunc("POST", config.PolicyMutatingWebhookServicePath, ws.handlerFunc(ws.policyMutation, true))
mux.HandlerFunc("POST", config.PolicyValidatingWebhookServicePath, ws.handlerFunc(ws.policyValidation, true))
@ -260,9 +260,9 @@ func writeResponse(rw http.ResponseWriter, admissionReview *v1beta1.AdmissionRev
}
}
func (ws *WebhookServer) resourceMutation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
func (ws *WebhookServer) ResourceMutation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
logger := ws.log.WithName("resourceMutation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
logger := ws.log.WithName("ResourceMutation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
if excludeKyvernoResources(request.Kind.Kind) {
return &v1beta1.AdmissionResponse{
@ -329,7 +329,7 @@ func (ws *WebhookServer) resourceMutation(request *v1beta1.AdmissionRequest) *v1
var patches []byte
patchedResource := request.Object.Raw
if ws.supportMudateValidate {
if ws.supportMutateValidate {
// MUTATION
// mutation failure should not block the resource creation
// any mutation failure is reported as the violation
@ -398,7 +398,7 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
}
}
if !ws.supportMudateValidate {
if !ws.supportMutateValidate {
logger.Info("mutate and validate rules are not supported prior to Kubernetes 1.14.0")
return &v1beta1.AdmissionResponse{
Allowed: true,