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:
parent
1b7a295860
commit
afe98bb93c
7 changed files with 62 additions and 35 deletions
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue