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:
parent
092f83493d
commit
e4bf66e756
20 changed files with 622 additions and 1046 deletions
89
.github/workflows/e2e-autogen-internals.yaml
vendored
89
.github/workflows/e2e-autogen-internals.yaml
vendored
|
@ -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
|
24
.github/workflows/e2e.yaml
vendored
24
.github/workflows/e2e.yaml
vendored
|
@ -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: |
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
## v1.9.0-rc.1
|
||||
|
||||
### Note
|
||||
|
||||
- Flag `autogenInternals` was removed, policy mutation has been removed.
|
||||
|
||||
## v1.8.1-rc3
|
||||
|
||||
### Note
|
||||
|
|
2
Makefile
2
Makefile
|
@ -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
|
||||
|
||||
|
|
|
@ -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. |
|
||||
|
|
|
@ -172,7 +172,6 @@ envVars: {}
|
|||
|
||||
# -- Extra arguments to give to the binary.
|
||||
extraArgs:
|
||||
- --autogenInternals=true
|
||||
- --loggingFormat=text
|
||||
|
||||
# -- Array of extra init containers
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -26118,7 +26118,6 @@ spec:
|
|||
containers:
|
||||
- args:
|
||||
- -v=2
|
||||
- --autogenInternals=true
|
||||
env:
|
||||
- name: INIT_CONFIG
|
||||
value: kyverno
|
||||
|
|
|
@ -83,7 +83,6 @@ spec:
|
|||
# configure the workers for generate controller
|
||||
# - --genWorkers=20
|
||||
- "-v=2"
|
||||
- --autogenInternals=true
|
||||
ports:
|
||||
- containerPort: 9443
|
||||
name: https
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue