1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

feat: remove policy mutation for auto-gen rules (#5123)

* feat: remove policy mutation code

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* Fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* changelog

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-10-26 01:43:46 +02:00 committed by GitHub
parent 092f83493d
commit e4bf66e756
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 622 additions and 1046 deletions

View file

@ -1,89 +0,0 @@
name: e2e-autogen-internals
on:
push:
branches:
- 'main'
- 'release*'
paths-ignore:
- 'README.md'
- 'docs/**'
- '.github/config.yml'
pull_request:
branches:
- 'main'
- 'release*'
paths-ignore:
- 'README.md'
- '.github/config.yml'
permissions: read-all
jobs:
e2e-test:
strategy:
fail-fast: false
matrix:
k8s-version: [v1.22.13, v1.23.10, v1.24.4, v1.25.0]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
- name: Unshallow
run: git fetch --prune --unshallow
- name: Set up Go
uses: actions/setup-go@424fc82d43fa5a37540bae62709ddcc23d9520d4 # v2.1.5
with:
go-version: ~1.18.6
- name: Set up Helm
uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab # v1.1
with:
version: v3.5.0
- name: Set up chart-testing
uses: helm/chart-testing-action@b0d4458c71155b54fcf33e11dd465dc923550009 # v2.0.1
- name: Cache Go modules
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # pin@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Create dev images, kind cluster and setup kustomize
run: |
export KIND_IMAGE=kindest/node:${{ matrix.k8s-version }}
make create-e2e-infrastructure
- name: e2e testing
run: |
echo ">>> Install Kyverno"
cat ${GITHUB_WORKSPACE}/config/install.yaml | \
sed -e 's/imagePullPolicy:.*$/imagePullPolicy: IfNotPresent/g' | \
kubectl create -f -
kubectl apply -f ${GITHUB_WORKSPACE}/config/github/rbac.yaml
chmod a+x ${GITHUB_WORKSPACE}/scripts/verify-deployment.sh
sleep 50
echo ">>> Check kyverno"
kubectl get pods -n kyverno
${GITHUB_WORKSPACE}/scripts/verify-deployment.sh -n kyverno kyverno
sleep 20
echo ">>> Expose the Kyverno's service's metric server to the host"
kubectl port-forward svc/kyverno-svc-metrics -n kyverno 8000:8000 &
echo ">>> Run Kyverno e2e test"
make test-e2e
kubectl delete -f ${GITHUB_WORKSPACE}/config/install.yaml
- name: Debug failure
if: failure()
run: |
kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations
kubectl -n kyverno get pod
kubectl -n kyverno describe pod | grep -i events -A10
kubectl -n kyverno logs deploy/kyverno -p || true
kubectl -n kyverno logs deploy/kyverno

View file

@ -1,4 +1,4 @@
name: e2e
name: e2e-autogen-internals
on:
push:
branches:
@ -6,6 +6,7 @@ on:
- 'release*'
paths-ignore:
- 'README.md'
- 'docs/**'
- '.github/config.yml'
pull_request:
branches:
@ -22,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
k8s-version: [v1.24.4, v1.25.0]
k8s-version: [v1.22.13, v1.23.10, v1.24.4, v1.25.0]
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -54,7 +55,7 @@ jobs:
restore-keys: |
${{ runner.os }}-go-
- name : Create dev images, kind cluster and setup kustomize
- name: Create dev images, kind cluster and setup kustomize
run: |
export KIND_IMAGE=kindest/node:${{ matrix.k8s-version }}
make create-e2e-infrastructure
@ -64,7 +65,6 @@ jobs:
echo ">>> Install Kyverno"
cat ${GITHUB_WORKSPACE}/config/install.yaml | \
sed -e 's/imagePullPolicy:.*$/imagePullPolicy: IfNotPresent/g' | \
sed -e 's/--autogenInternals:true$/--autogenInternals:false/g' | \
kubectl create -f -
kubectl apply -f ${GITHUB_WORKSPACE}/config/github/rbac.yaml
chmod a+x ${GITHUB_WORKSPACE}/scripts/verify-deployment.sh
@ -76,25 +76,9 @@ jobs:
echo ">>> Expose the Kyverno's service's metric server to the host"
kubectl port-forward svc/kyverno-svc-metrics -n kyverno 8000:8000 &
echo ">>> Run Kyverno e2e test"
export FLAG_AUTOGEN_INTERNALS=false
make test-e2e
kubectl delete -f ${GITHUB_WORKSPACE}/config/install.yaml
- name: Update chart values
run: |
make helm-test-values
cat charts/kyverno/values.yaml
- name: Run chart-testing (install)
run: |
kubectl create namespace kyverno
ct install --target-branch=main --namespace=kyverno --charts charts/kyverno
- name: Run chart-testing (policies)
run: |
helm install kyverno charts/kyverno -n kyverno
ct install --target-branch=main --namespace=kyverno --charts charts/kyverno-policies
- name: Debug failure
if: failure()
run: |

View file

@ -1,3 +1,9 @@
## v1.9.0-rc.1
### Note
- Flag `autogenInternals` was removed, policy mutation has been removed.
## v1.8.1-rc3
### Note

View file

@ -723,7 +723,7 @@ kind-deploy-kyverno: $(HELM) kind-load-all ## Build images, load them in kind cl
--set initImage.repository=$(LOCAL_KYVERNOPRE_IMAGE) \
--set initImage.tag=$(IMAGE_TAG_DEV) \
--set initContainer.extraArgs={--loggingFormat=text} \
--set "extraArgs={--autogenInternals=true,--loggingFormat=text}"
--set "extraArgs={--loggingFormat=text}"
@echo Restart kyverno pods... >&2
@kubectl rollout restart deployment -n kyverno kyverno

View file

@ -160,7 +160,7 @@ The command removes all the Kubernetes components associated with the chart and
| dnsPolicy | string | `"ClusterFirst"` | `dnsPolicy` determines the manner in which DNS resolution happens in the cluster. In case of `hostNetwork: true`, usually, the `dnsPolicy` is suitable to be `ClusterFirstWithHostNet`. For further reference: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy. |
| envVarsInit | object | `{}` | Env variables for initContainers. |
| envVars | object | `{}` | Env variables for containers. |
| extraArgs | list | `["--autogenInternals=true","--loggingFormat=text"]` | Extra arguments to give to the binary. |
| extraArgs | list | `["--loggingFormat=text"]` | Extra arguments to give to the binary. |
| extraInitContainers | list | `[]` | Array of extra init containers |
| extraContainers | list | `[]` | Array of extra containers to run alongside kyverno |
| imagePullSecrets | object | `{}` | Image pull secrets for image verify and imageData policies. This will define the `--imagePullSecrets` Kyverno argument. |

View file

@ -172,7 +172,6 @@ envVars: {}
# -- Extra arguments to give to the binary.
extraArgs:
- --autogenInternals=true
- --loggingFormat=text
# -- Array of extra init containers

View file

@ -248,25 +248,18 @@ func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, reso
}
}
mutatedPolicies, err := common.MutatePolicies(policies)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to mutate policy", err)
}
}
err = common.PrintMutatedPolicy(mutatedPolicies)
err = common.PrintMutatedPolicy(policies)
if err != nil {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("failed to marsal mutated policy", err)
}
resources, err = common.GetResourceAccordingToResourcePath(fs, c.ResourcePaths, c.Cluster, mutatedPolicies, dClient, c.Namespace, c.PolicyReport, false, "")
resources, err = common.GetResourceAccordingToResourcePath(fs, c.ResourcePaths, c.Cluster, policies, dClient, c.Namespace, c.PolicyReport, false, "")
if err != nil {
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
os.Exit(1)
}
if (len(resources) > 1 || len(mutatedPolicies) > 1) && c.VariablesString != "" {
if (len(resources) > 1 || len(policies) > 1) && c.VariablesString != "" {
return rc, resources, skipInvalidPolicies, pvInfos, sanitizederror.NewWithError("currently `set` flag supports variable for single policy applied on single resource ", nil)
}
@ -283,7 +276,7 @@ func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, reso
}
if c.VariablesString != "" {
variables = common.SetInStoreContext(mutatedPolicies, variables)
variables = common.SetInStoreContext(policies, variables)
}
var policyRulesCount, mutatedPolicyRulesCount int
@ -291,7 +284,7 @@ func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, reso
policyRulesCount += len(policy.GetSpec().Rules)
}
for _, policy := range mutatedPolicies {
for _, policy := range policies {
mutatedPolicyRulesCount += len(policy.GetSpec().Rules)
}
@ -309,7 +302,7 @@ func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, reso
msgResources = fmt.Sprintf("%d resources", len(resources))
}
if len(mutatedPolicies) > 0 && len(resources) > 0 {
if len(policies) > 0 && len(resources) > 0 {
if !c.Stdin {
if mutatedPolicyRulesCount > policyRulesCount {
fmt.Printf("\nauto-generated pod policies\nApplying %s to %s...\n", msgPolicyRules, msgResources)
@ -323,7 +316,7 @@ func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, reso
skipInvalidPolicies.skipped = make([]string, 0)
skipInvalidPolicies.invalid = make([]string, 0)
for _, policy := range mutatedPolicies {
for _, policy := range policies {
_, err := policy2.Validate(policy, nil, true, openApiManager)
if err != nil {
log.Log.Error(err, "policy validation error")

View file

@ -936,19 +936,12 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
}
policies = filteredPolicies
mutatedPolicies, err := common.MutatePolicies(policies)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to mutate policy", err)
}
}
err = common.PrintMutatedPolicy(mutatedPolicies)
err = common.PrintMutatedPolicy(policies)
if err != nil {
return sanitizederror.NewWithError("failed to print mutated policy", err)
}
resources, err := common.GetResourceAccordingToResourcePath(fs, resourceFullPath, false, mutatedPolicies, dClient, "", false, isGit, policyResourcePath)
resources, err := common.GetResourceAccordingToResourcePath(fs, resourceFullPath, false, policies, dClient, "", false, isGit, policyResourcePath)
if err != nil {
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
os.Exit(1)
@ -971,7 +964,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
resources = filteredResources
msgPolicies := "1 policy"
if len(mutatedPolicies) > 1 {
if len(policies) > 1 {
msgPolicies = fmt.Sprintf("%d policies", len(policies))
}
@ -980,11 +973,11 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
msgResources = fmt.Sprintf("%d resources", len(resources))
}
if len(mutatedPolicies) > 0 && len(resources) > 0 {
if len(policies) > 0 && len(resources) > 0 {
fmt.Printf("\napplying %s to %s... \n", msgPolicies, msgResources)
}
for _, policy := range mutatedPolicies {
for _, policy := range policies {
_, err := policy2.Validate(policy, nil, true, openApiManager)
if err != nil {
log.Log.Error(err, "skipping invalid policy", "name", policy.GetName())

View file

@ -12,9 +12,7 @@ import (
"reflect"
"strings"
jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/go-git/go-billy/v5"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
@ -28,7 +26,6 @@ import (
"github.com/kyverno/kyverno/pkg/engine/response"
ut "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/policymutation"
"github.com/kyverno/kyverno/pkg/policyreport"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
yamlv2 "gopkg.in/yaml.v2"
@ -195,41 +192,6 @@ func GetPolicies(paths []string) (policies []kyvernov1.PolicyInterface, errors [
return policies, errors
}
// MutatePolicy - applies mutation to a policy
func MutatePolicy(policy kyvernov1.PolicyInterface, logger logr.Logger) (kyvernov1.PolicyInterface, error) {
patches, _ := policymutation.GenerateJSONPatchesForDefaults(policy, logger)
if len(patches) == 0 {
return policy, nil
}
patch, err := jsonpatch.DecodePatch(patches)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to decode patch for %s policy", policy.GetName()), err)
}
policyBytes, err := json.Marshal(policy)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to marshal %s policy", policy.GetName()), err)
}
modifiedPolicy, err := patch.Apply(policyBytes)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to apply %s policy", policy.GetName()), err)
}
if policy.IsNamespaced() {
var p kyvernov1.Policy
err = json.Unmarshal(modifiedPolicy, &p)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to unmarshal %s policy", policy.GetName()), err)
}
return &p, nil
} else {
var p kyvernov1.ClusterPolicy
err = json.Unmarshal(modifiedPolicy, &p)
if err != nil {
return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to unmarshal %s policy", policy.GetName()), err)
}
return &p, nil
}
}
// IsInputFromPipe - check if input is passed using pipe
func IsInputFromPipe() bool {
fileInfo, _ := os.Stdin.Stat()
@ -392,24 +354,6 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, nil
}
// MutatePolicies - function to apply mutation on policies
func MutatePolicies(policies []kyvernov1.PolicyInterface) ([]kyvernov1.PolicyInterface, error) {
newPolicies := make([]kyvernov1.PolicyInterface, 0)
logger := log.Log.WithName("apply")
for _, policy := range policies {
p, err := MutatePolicy(policy, logger)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return nil, sanitizederror.NewWithError("failed to mutate policy.", err)
}
return nil, err
}
newPolicies = append(newPolicies, p)
}
return newPolicies, nil
}
// ApplyPolicyOnResource - function to apply policy on resource
func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]*response.EngineResponse, policyreport.Info, error) {
var engineResponses []*response.EngineResponse

View file

@ -4,7 +4,6 @@ import (
"testing"
v1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/toggle"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
"gotest.tools/assert"
)
@ -111,11 +110,7 @@ func Test_NamespaceSelector(t *testing.T) {
assert.Equal(t, int64(rc.Pass), int64(tc.result.Pass))
assert.Equal(t, int64(rc.Fail), int64(tc.result.Fail))
// TODO: autogen rules seem to not be present when autogen internals is disabled
if toggle.AutogenInternals.Enabled() {
assert.Equal(t, int64(rc.Skip), int64(tc.result.Skip))
} else {
assert.Equal(t, int64(rc.Skip), int64(0))
}
assert.Equal(t, int64(rc.Skip), int64(tc.result.Skip))
assert.Equal(t, int64(rc.Warn), int64(tc.result.Warn))
assert.Equal(t, int64(rc.Error), int64(tc.result.Error))
}

View file

@ -123,7 +123,6 @@ func parseFlags() error {
flag.BoolVar(&autoUpdateWebhooks, "autoUpdateWebhooks", true, "Set this flag to 'false' to disable auto-configuration of the webhook.")
flag.Float64Var(&clientRateLimitQPS, "clientRateLimitQPS", 20, "Configure the maximum QPS to the Kubernetes API server from Kyverno. Uses the client default if zero.")
flag.IntVar(&clientRateLimitBurst, "clientRateLimitBurst", 50, "Configure the maximum burst for throttle. Uses the client default if zero.")
flag.Func(toggle.AutogenInternalsFlagName, toggle.AutogenInternalsDescription, toggle.AutogenInternals.Parse)
flag.DurationVar(&webhookRegistrationTimeout, "webhookRegistrationTimeout", 120*time.Second, "Timeout for webhook registration, e.g., 30s, 1m, 5m.")
flag.Func(toggle.ProtectManagedResourcesFlagName, toggle.ProtectManagedResourcesDescription, toggle.ProtectManagedResources.Parse)
flag.BoolVar(&backgroundScan, "backgroundScan", true, "Enable or disable backgound scan.")

View file

@ -26118,7 +26118,6 @@ spec:
containers:
- args:
- -v=2
- --autogenInternals=true
env:
- name: INIT_CONFIG
value: kyverno

View file

@ -83,7 +83,6 @@ spec:
# configure the workers for generate controller
# - --genWorkers=20
- "-v=2"
- --autogenInternals=true
ports:
- containerPort: 9443
name: https

View file

@ -7,7 +7,6 @@ import (
"strings"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/toggle"
"github.com/kyverno/kyverno/pkg/utils"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -279,10 +278,6 @@ func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
}
func ComputeRules(p kyvernov1.PolicyInterface) []kyvernov1.Rule {
if !toggle.AutogenInternals.Enabled() {
spec := p.GetSpec()
return spec.Rules
}
return computeRules(p)
}

View file

@ -17,7 +17,6 @@ import (
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/tls"
"github.com/kyverno/kyverno/pkg/toggle"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
runtimeutils "github.com/kyverno/kyverno/pkg/utils/runtime"
@ -431,11 +430,9 @@ func (c *controller) updatePolicyStatuses(ctx context.Context) error {
status := policy.GetStatus()
status.SetReady(ready)
status.Autogen.Rules = nil
if toggle.AutogenInternals.Enabled() {
for _, rule := range autogen.ComputeRules(policy) {
if strings.HasPrefix(rule.Name, "autogen-") {
status.Autogen.Rules = append(status.Autogen.Rules, rule)
}
for _, rule := range autogen.ComputeRules(policy) {
if strings.HasPrefix(rule.Name, "autogen-") {
status.Autogen.Rules = append(status.Autogen.Rules, rule)
}
}
return nil

View file

@ -12,7 +12,6 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
utilscommon "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"github.com/kyverno/kyverno/pkg/autogen"
common "github.com/kyverno/kyverno/pkg/background/common"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
@ -25,12 +24,10 @@ import (
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/toggle"
"github.com/kyverno/kyverno/pkg/utils"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
@ -163,16 +160,6 @@ func (pc *PolicyController) addPolicy(obj interface{}) {
logger.Info("policy created", "uid", p.UID, "kind", "ClusterPolicy", "name", p.Name)
if !toggle.AutogenInternals.Enabled() {
if p.Spec.Background == nil || p.Spec.ValidationFailureAction == "" || missingAutoGenRules(p, logger) {
pol, _ := utilscommon.MutatePolicy(p, logger)
_, err := pc.kyvernoClient.KyvernoV1().ClusterPolicies().Update(context.TODO(), pol.(*kyvernov1.ClusterPolicy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to add policy ")
}
}
}
if !pc.canBackgroundProcess(p) {
return
}
@ -186,16 +173,6 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
oldP := old.(*kyvernov1.ClusterPolicy)
curP := cur.(*kyvernov1.ClusterPolicy)
if !toggle.AutogenInternals.Enabled() {
if curP.Spec.Background == nil || curP.Spec.ValidationFailureAction == "" || missingAutoGenRules(curP, logger) {
pol, _ := utilscommon.MutatePolicy(curP, logger)
_, err := pc.kyvernoClient.KyvernoV1().ClusterPolicies().Update(context.TODO(), pol.(*kyvernov1.ClusterPolicy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update policy ")
}
}
}
if !pc.canBackgroundProcess(curP) {
return
}
@ -236,17 +213,6 @@ func (pc *PolicyController) addNsPolicy(obj interface{}) {
logger.Info("policy created", "uid", p.UID, "kind", "Policy", "name", p.Name, "namespaces", p.Namespace)
if !toggle.AutogenInternals.Enabled() {
spec := p.GetSpec()
if spec.Background == nil || spec.ValidationFailureAction == "" || missingAutoGenRules(p, logger) {
nsPol, _ := utilscommon.MutatePolicy(p, logger)
_, err := pc.kyvernoClient.KyvernoV1().Policies(p.Namespace).Update(context.TODO(), nsPol.(*kyvernov1.Policy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to add namespace policy")
}
}
}
if !pc.canBackgroundProcess(p) {
return
}
@ -259,16 +225,6 @@ func (pc *PolicyController) updateNsPolicy(old, cur interface{}) {
oldP := old.(*kyvernov1.Policy)
curP := cur.(*kyvernov1.Policy)
if !toggle.AutogenInternals.Enabled() {
if curP.Spec.Background == nil || curP.Spec.ValidationFailureAction == "" || missingAutoGenRules(curP, logger) {
nsPol, _ := utilscommon.MutatePolicy(curP, logger)
_, err := pc.kyvernoClient.KyvernoV1().Policies(curP.GetNamespace()).Update(context.TODO(), nsPol.(*kyvernov1.Policy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update namespace policy ")
}
}
}
if !pc.canBackgroundProcess(curP) {
return
}

View file

@ -1,169 +0,0 @@
package policymutation
import (
"fmt"
"strconv"
"strings"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/toggle"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
)
// GenerateJSONPatchesForDefaults generates default JSON patches for
// - ValidationFailureAction
// - Background
// - auto-gen annotation and rules
func GenerateJSONPatchesForDefaults(policy kyvernov1.PolicyInterface, log logr.Logger) ([]byte, []string) {
var patches [][]byte
var updateMsgs []string
spec := policy.GetSpec()
// if autogenInternals is enabled, we don't mutate most of the policy fields
if !toggle.AutogenInternals.Enabled() {
// default 'ValidationFailureAction'
if patch, updateMsg := defaultvalidationFailureAction(spec, log); patch != nil {
patches = append(patches, patch)
updateMsgs = append(updateMsgs, updateMsg)
}
// default 'Background'
if patch, updateMsg := defaultBackgroundFlag(spec, log); patch != nil {
patches = append(patches, patch)
updateMsgs = append(updateMsgs, updateMsg)
}
if patch, updateMsg := defaultFailurePolicy(spec, log); patch != nil {
patches = append(patches, patch)
updateMsgs = append(updateMsgs, updateMsg)
}
patch, errs := GeneratePodControllerRule(policy, log)
if len(errs) > 0 {
var errMsgs []string
for _, err := range errs {
errMsgs = append(errMsgs, err.Error())
log.Error(err, "failed to generate pod controller rule")
}
updateMsgs = append(updateMsgs, strings.Join(errMsgs, ";"))
}
patches = append(patches, patch...)
}
return jsonutils.JoinPatches(patches...), updateMsgs
}
func defaultBackgroundFlag(spec *kyvernov1.Spec, log logr.Logger) ([]byte, string) {
// set 'Background' flag to 'true' if not specified
if spec.Background == nil {
defaultVal := true
log.V(4).Info("setting default value", "spec.background", true)
patchByte, err := jsonutils.MarshalPatchOperation("/spec/background", "add", &defaultVal)
if err != nil {
log.Error(err, "failed to set default value", "spec.background", true)
return nil, ""
}
log.V(3).Info("generated JSON Patch to set default", "spec.background", true)
return patchByte, fmt.Sprintf("default 'Background' to '%s'", strconv.FormatBool(true))
}
return nil, ""
}
func defaultvalidationFailureAction(spec *kyvernov1.Spec, log logr.Logger) ([]byte, string) {
// set ValidationFailureAction to "audit" if not specified
if spec.ValidationFailureAction == "" {
audit := kyvernov1.Audit
log.V(4).Info("setting default value", "spec.validationFailureAction", audit)
patchByte, err := jsonutils.MarshalPatchOperation("/spec/validationFailureAction", "add", audit)
if err != nil {
log.Error(err, "failed to default value", "spec.validationFailureAction", audit)
return nil, ""
}
log.V(3).Info("generated JSON Patch to set default", "spec.validationFailureAction", audit)
return patchByte, fmt.Sprintf("default 'ValidationFailureAction' to '%s'", audit)
}
return nil, ""
}
func defaultFailurePolicy(spec *kyvernov1.Spec, log logr.Logger) ([]byte, string) {
// set failurePolicy to Fail if not present
if spec.FailurePolicy == nil {
failurePolicy := string(kyvernov1.Fail)
log.V(4).Info("setting default value", "spec.failurePolicy", failurePolicy)
patchByte, err := jsonutils.MarshalPatchOperation("/spec/failurePolicy", "add", failurePolicy)
if err != nil {
log.Error(err, "failed to set default value", "spec.failurePolicy", failurePolicy)
return nil, ""
}
log.V(3).Info("generated JSON Patch to set default", "spec.failurePolicy", failurePolicy)
return patchByte, fmt.Sprintf("default failurePolicy to '%s'", failurePolicy)
}
return nil, ""
}
// podControllersKey annotation could be:
// scenario A: not exist, set default to "all", which generates on all pod controllers
// - if name / selector exist in resource description -> skip
// as these fields may not be applicable to pod controllers
// scenario B: "none", user explicitly disable this feature -> skip
// scenario C: some certain controllers that user set -> generate on defined controllers
// copy entire match / exclude block, it's users' responsibility to
// make sure all fields are applicable to pod controllers
// GeneratePodControllerRule returns two patches: rulePatches and annotation patch(if necessary)
func GeneratePodControllerRule(policy kyvernov1.PolicyInterface, log logr.Logger) (patches [][]byte, errs []error) {
spec := policy.GetSpec()
applyAutoGen, desiredControllers := autogen.CanAutoGen(spec)
if !applyAutoGen {
desiredControllers = "none"
}
ann := policy.GetAnnotations()
actualControllers, ok := ann[kyvernov1.PodControllersAnnotation]
// - scenario A
// - predefined controllers are invalid, overwrite the value
if !ok || !applyAutoGen {
actualControllers = desiredControllers
annPatch, err := defaultPodControllerAnnotation(ann, actualControllers)
if err != nil {
errs = append(errs, fmt.Errorf("failed to generate pod controller annotation for policy '%s': %v", policy.GetName(), err))
} else {
patches = append(patches, annPatch)
}
} else {
if !applyAutoGen {
actualControllers = desiredControllers
}
}
// scenario B
if actualControllers == "none" {
return patches, nil
}
log.V(3).Info("auto generating rule for pod controllers", "controllers", actualControllers)
p, err := autogen.GenerateRulePatches(spec, actualControllers)
patches = append(patches, p...)
errs = append(errs, err...)
return
}
// defaultPodControllerAnnotation inserts an annotation
// "pod-policies.kyverno.io/autogen-controllers=<controllers>" to policy
func defaultPodControllerAnnotation(ann map[string]string, controllers string) ([]byte, error) {
if ann == nil {
ann = make(map[string]string)
ann[kyvernov1.PodControllersAnnotation] = controllers
patchByte, err := jsonutils.MarshalPatchOperation("/metadata/annotations", "add", ann)
if err != nil {
return nil, err
}
return patchByte, nil
}
patchByte, err := jsonutils.MarshalPatchOperation("/metadata/annotations/pod-policies.kyverno.io~1autogen-controllers", "add", controllers)
if err != nil {
return nil, err
}
return patchByte, nil
}

View file

@ -6,11 +6,6 @@ import (
)
const (
// autogen
AutogenInternalsFlagName = "autogenInternals"
AutogenInternalsDescription = "Enables autogen internal policies. When this is 'true' policy rules should not be mutated."
autogenInternalsEnvVar = "FLAG_AUTOGEN_INTERNALS"
defaultAutogenInternals = true
// protect managed resource
ProtectManagedResourcesFlagName = "protectManagedResources"
ProtectManagedResourcesDescription = "Set the flag to 'true', to enable managed resources protection."
@ -24,7 +19,6 @@ const (
)
var (
AutogenInternals = newToggle(defaultAutogenInternals, autogenInternalsEnvVar)
ProtectManagedResources = newToggle(defaultProtectManagedResources, protectManagedResourcesEnvVar)
ForceFailurePolicyIgnore = newToggle(defaultForceFailurePolicyIgnore, forceFailurePolicyIgnoreEnvVar)
)

View file

@ -2,15 +2,12 @@ package policy
import (
"fmt"
"strings"
"time"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/openapi"
policyvalidate "github.com/kyverno/kyverno/pkg/policy"
"github.com/kyverno/kyverno/pkg/policymutation"
"github.com/kyverno/kyverno/pkg/toggle"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
"github.com/kyverno/kyverno/pkg/webhooks"
admissionv1 "k8s.io/api/admission/v1"
@ -50,20 +47,5 @@ func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRe
}
func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequest, _ time.Time) *admissionv1.AdmissionResponse {
if toggle.AutogenInternals.Enabled() {
return admissionutils.Response(true)
}
if request.SubResource != "" {
logger.V(4).Info("skip policy validation on status update")
return admissionutils.Response(true)
}
policy, _, err := admissionutils.GetPolicies(request)
if err != nil {
logger.Error(err, "failed to unmarshal policies from admission request")
return admissionutils.ResponseWithMessage(true, fmt.Sprintf("failed to default value, check kyverno controller logs for details: %v", err))
}
if patches, updateMsgs := policymutation.GenerateJSONPatchesForDefaults(policy, logger); len(patches) != 0 {
return admissionutils.ResponseWithMessageAndPatch(true, strings.Join(updateMsgs, "'"), patches)
}
return admissionutils.Response(true)
}

File diff suppressed because it is too large Load diff