mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +00:00
feat: Add support for server-side-apply in generate rules (#7705)
* feat: Add support for server-side-apply in generate rules Signed-off-by: Mike Bryant <mike@mikebryant.me.uk> * chore: run make codegen-all Signed-off-by: Mike Bryant <mike.bryant@mettle.co.uk> * chore: Remove unnecessary file I got from copy/paste Signed-off-by: Mike Bryant <mike.bryant@mettle.co.uk> --------- Signed-off-by: Mike Bryant <mike@mikebryant.me.uk> Signed-off-by: Mike Bryant <mike.bryant@mettle.co.uk> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
329c11a058
commit
fd67707c00
23 changed files with 357 additions and 10 deletions
|
@ -117,6 +117,12 @@ type Spec struct {
|
|||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
GenerateExisting bool `json:"generateExisting,omitempty" yaml:"generateExisting,omitempty"`
|
||||
|
||||
// UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
// If is set to "true" create & update for generate rules will use apply instead of create/update.
|
||||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
UseServerSideApply bool `json:"useServerSideApply,omitempty" yaml:"useServerSideApply,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Spec) SetRules(rules []Rule) {
|
||||
|
|
|
@ -78,6 +78,12 @@ type Spec struct {
|
|||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
GenerateExisting bool `json:"generateExisting,omitempty" yaml:"generateExisting,omitempty"`
|
||||
|
||||
// UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
// If is set to "true" create & update for generate rules will use apply instead of create/update.
|
||||
// Defaults to "false" if not specified.
|
||||
// +optional
|
||||
UseServerSideApply bool `json:"useServerSideApply,omitempty" yaml:"useServerSideApply,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Spec) SetRules(rules []Rule) {
|
||||
|
|
|
@ -7764,6 +7764,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -15606,6 +15612,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -23759,6 +23771,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -31603,6 +31621,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
|
|
@ -3947,6 +3947,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -11789,6 +11795,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
|
|
@ -3948,6 +3948,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -11792,6 +11798,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
|
|
@ -7967,6 +7967,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -15809,6 +15815,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -23962,6 +23974,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
@ -31806,6 +31824,12 @@ spec:
|
|||
as well as patched resources. Optional. The default value is set
|
||||
to "true", it must be set to "false" to disable the validation checks.
|
||||
type: boolean
|
||||
useServerSideApply:
|
||||
description: UseServerSideApply controls whether to use server-side
|
||||
apply for generate rules If is set to "true" create & update for
|
||||
generate rules will use apply instead of create/update. Defaults
|
||||
to "false" if not specified.
|
||||
type: boolean
|
||||
validationFailureAction:
|
||||
default: Audit
|
||||
description: ValidationFailureAction defines if a validation policy
|
||||
|
|
|
@ -275,6 +275,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -526,6 +540,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -3679,6 +3707,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
|
@ -6070,6 +6112,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -6320,6 +6376,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -7242,6 +7312,20 @@ If is set to “true” generate rule will be triggered and applied to e
|
|||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>useServerSideApply</code><br/>
|
||||
<em>
|
||||
bool
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>UseServerSideApply controls whether to use server-side apply for generate rules
|
||||
If is set to “true” create & update for generate rules will use apply instead of create/update.
|
||||
Defaults to “false” if not specified.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, policy kyvernov1.PolicyInterface, ur kyvernov1beta1.UpdateRequest, rule kyvernov1.Rule, client dclient.Interface) generateResponse {
|
||||
|
@ -50,6 +51,13 @@ func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, pol
|
|||
if sourceObjCopy.GetNamespace() != target.GetNamespace() && sourceObjCopy.GetOwnerReferences() != nil {
|
||||
sourceObjCopy.SetOwnerReferences(nil)
|
||||
}
|
||||
// Clean up parameters that shouldn't be copied
|
||||
sourceObjCopy.SetUID("")
|
||||
sourceObjCopy.SetSelfLink("")
|
||||
var emptyTime metav1.Time
|
||||
sourceObjCopy.SetCreationTimestamp(emptyTime)
|
||||
sourceObjCopy.SetManagedFields(nil)
|
||||
sourceObjCopy.SetResourceVersion("")
|
||||
|
||||
targetObj, err := client.GetResource(context.TODO(), target.GetAPIVersion(), target.GetKind(), target.GetNamespace(), target.GetName())
|
||||
if err != nil {
|
||||
|
@ -64,13 +72,15 @@ func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, pol
|
|||
}
|
||||
|
||||
if targetObj != nil {
|
||||
sourceObjCopy.SetUID(targetObj.GetUID())
|
||||
sourceObjCopy.SetSelfLink(targetObj.GetSelfLink())
|
||||
sourceObjCopy.SetCreationTimestamp(targetObj.GetCreationTimestamp())
|
||||
sourceObjCopy.SetManagedFields(targetObj.GetManagedFields())
|
||||
sourceObjCopy.SetResourceVersion(targetObj.GetResourceVersion())
|
||||
if datautils.DeepEqual(sourceObjCopy, targetObj) {
|
||||
return newSkipGenerateResponse(nil, target, nil)
|
||||
if !policy.GetSpec().UseServerSideApply {
|
||||
sourceObjCopy.SetUID(targetObj.GetUID())
|
||||
sourceObjCopy.SetSelfLink(targetObj.GetSelfLink())
|
||||
sourceObjCopy.SetCreationTimestamp(targetObj.GetCreationTimestamp())
|
||||
sourceObjCopy.SetManagedFields(targetObj.GetManagedFields())
|
||||
sourceObjCopy.SetResourceVersion(targetObj.GetResourceVersion())
|
||||
if datautils.DeepEqual(sourceObjCopy, targetObj) {
|
||||
return newSkipGenerateResponse(nil, target, nil)
|
||||
}
|
||||
}
|
||||
return newUpdateGenerateResponse(sourceObjCopy.UnstructuredContent(), target, nil)
|
||||
}
|
||||
|
|
|
@ -403,7 +403,11 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, t
|
|||
common.ManageLabels(newResource, trigger, policy, rule.Name)
|
||||
if response.GetAction() == Create {
|
||||
newResource.SetResourceVersion("")
|
||||
_, err = client.CreateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
if policy.GetSpec().UseServerSideApply {
|
||||
_, err = client.ApplyResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), targetMeta.GetName(), newResource, false, "generate")
|
||||
} else {
|
||||
_, err = client.CreateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
}
|
||||
if err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return newGenResources, err
|
||||
|
@ -415,7 +419,11 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, t
|
|||
generatedObj, err := client.GetResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), targetMeta.GetName())
|
||||
if err != nil {
|
||||
logger.V(2).Info("target resource not found, creating new target")
|
||||
_, err = client.CreateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
if policy.GetSpec().UseServerSideApply {
|
||||
_, err = client.ApplyResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), targetMeta.GetName(), newResource, false, "generate")
|
||||
} else {
|
||||
_, err = client.CreateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
}
|
||||
if err != nil {
|
||||
return newGenResources, err
|
||||
}
|
||||
|
@ -433,7 +441,11 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, t
|
|||
newResource.SetNamespace("default")
|
||||
}
|
||||
|
||||
_, err = client.UpdateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
if policy.GetSpec().UseServerSideApply {
|
||||
_, err = client.ApplyResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), targetMeta.GetName(), newResource, false, "generate")
|
||||
} else {
|
||||
_, err = client.UpdateResource(context.TODO(), targetMeta.GetAPIVersion(), targetMeta.GetKind(), targetMeta.GetNamespace(), newResource, false)
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to update resource")
|
||||
return newGenResources, err
|
||||
|
|
|
@ -37,6 +37,7 @@ type SpecApplyConfiguration struct {
|
|||
MutateExistingOnPolicyUpdate *bool `json:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
|
||||
GenerateExisting *bool `json:"generateExisting,omitempty"`
|
||||
UseServerSideApply *bool `json:"useServerSideApply,omitempty"`
|
||||
}
|
||||
|
||||
// SpecApplyConfiguration constructs an declarative configuration of the Spec type for use with
|
||||
|
@ -150,3 +151,11 @@ func (b *SpecApplyConfiguration) WithGenerateExisting(value bool) *SpecApplyConf
|
|||
b.GenerateExisting = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUseServerSideApply sets the UseServerSideApply field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UseServerSideApply field is set to the value of the last call.
|
||||
func (b *SpecApplyConfiguration) WithUseServerSideApply(value bool) *SpecApplyConfiguration {
|
||||
b.UseServerSideApply = &value
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ type SpecApplyConfiguration struct {
|
|||
MutateExistingOnPolicyUpdate *bool `json:"mutateExistingOnPolicyUpdate,omitempty"`
|
||||
GenerateExistingOnPolicyUpdate *bool `json:"generateExistingOnPolicyUpdate,omitempty"`
|
||||
GenerateExisting *bool `json:"generateExisting,omitempty"`
|
||||
UseServerSideApply *bool `json:"useServerSideApply,omitempty"`
|
||||
}
|
||||
|
||||
// SpecApplyConfiguration constructs an declarative configuration of the Spec type for use with
|
||||
|
@ -151,3 +152,11 @@ func (b *SpecApplyConfiguration) WithGenerateExisting(value bool) *SpecApplyConf
|
|||
b.GenerateExisting = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUseServerSideApply sets the UseServerSideApply field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UseServerSideApply field is set to the value of the last call.
|
||||
func (b *SpecApplyConfiguration) WithUseServerSideApply(value bool) *SpecApplyConfiguration {
|
||||
b.UseServerSideApply = &value
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ type Interface interface {
|
|||
UpdateResource(ctx context.Context, apiVersion string, kind string, namespace string, obj interface{}, dryRun bool, subresources ...string) (*unstructured.Unstructured, error)
|
||||
// UpdateStatusResource updates the resource "status" subresource
|
||||
UpdateStatusResource(ctx context.Context, apiVersion string, kind string, namespace string, obj interface{}, dryRun bool) (*unstructured.Unstructured, error)
|
||||
// ApplyResource applies object for the specified resource/namespace using server-side apply
|
||||
ApplyResource(ctx context.Context, apiVersion string, kind string, namespace string, name string, obj interface{}, dryRun bool, fieldManager string, subresources ...string) (*unstructured.Unstructured, error)
|
||||
// ApplyStatusResource applies the resource "status" subresource using server-side apply
|
||||
ApplyStatusResource(ctx context.Context, apiVersion string, kind string, namespace string, name string, obj interface{}, dryRun bool, fieldManager string) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
// Client enables interaction with k8 resource
|
||||
|
@ -226,6 +230,36 @@ func (c *client) UpdateStatusResource(ctx context.Context, apiVersion string, ki
|
|||
return nil, fmt.Errorf("unable to update resource ")
|
||||
}
|
||||
|
||||
// ApplyResource updates object for the specified resource/namespace
|
||||
func (c *client) ApplyResource(ctx context.Context, apiVersion string, kind string, namespace string, name string, obj interface{}, dryRun bool, fieldManager string, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
// We have a different field manager for different situations, so a generated object that then goes through admission control
|
||||
// won't have the changes wiped out by any use of server-side apply in the mutation path
|
||||
options := metav1.ApplyOptions{FieldManager: "kyverno-" + fieldManager, Force: true}
|
||||
if dryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
// convert typed to unstructured obj
|
||||
if unstructuredObj, err := kubeutils.ObjToUnstructured(obj); err == nil && unstructuredObj != nil {
|
||||
return c.getResourceInterface(apiVersion, kind, namespace).Apply(ctx, name, unstructuredObj, options, subresources...)
|
||||
}
|
||||
return nil, fmt.Errorf("unable to apply resource ")
|
||||
}
|
||||
|
||||
// ApplyStatusResource updates the resource "status" subresource
|
||||
func (c *client) ApplyStatusResource(ctx context.Context, apiVersion string, kind string, namespace string, name string, obj interface{}, dryRun bool, fieldManager string) (*unstructured.Unstructured, error) {
|
||||
// We have a different field manager for different situations, so a generated object that then goes through admission control
|
||||
// won't have the changes wiped out by any use of server-side apply in the mutation path
|
||||
options := metav1.ApplyOptions{FieldManager: "kyverno-" + fieldManager, Force: true}
|
||||
if dryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
// convert typed to unstructured obj
|
||||
if unstructuredObj, err := kubeutils.ObjToUnstructured(obj); err == nil && unstructuredObj != nil {
|
||||
return c.getResourceInterface(apiVersion, kind, namespace).ApplyStatus(ctx, name, unstructuredObj, options)
|
||||
}
|
||||
return nil, fmt.Errorf("unable to apply resource ")
|
||||
}
|
||||
|
||||
// Discovery return the discovery client implementation
|
||||
func (c *client) Discovery() IDiscovery {
|
||||
return c.disco
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# A pre-test sleep is needed here due to https://github.com/kudobuilder/kuttl/pull/422
|
||||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 3
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- ns.yaml
|
||||
assert:
|
||||
- cloned.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- editeddownstream.yaml
|
||||
assert:
|
||||
- finalsecret.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test ensures that modification of the downstream (cloned/generated) resource used by a ClusterPolicy `generate` rule with sync enabled using a clone declaration and server-side apply causes those changes to be merged from the state of the upstream/source.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
After the downstream resource is modified, the changes should be merged with the clone after synchronization occurs. If the downstream resource is synced with the state of the source resource, and also respects the modifications to other fields, the test passes. If the downstream resource doesn't retain the cloned fields and the directly modified fields, the test fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: myfoons
|
||||
type: Opaque
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: bm90YmFjaGhlcmU=
|
||||
foo2: bm90YmFjaGhlcmU=
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: myfoons
|
||||
type: Opaque
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
foo2: bm90YmFjaGhlcmU=
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: myfoons
|
||||
type: Opaque
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: myfoons
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v2beta1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: cpol-clone-sync-modify-downstream-apply
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,32 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: default
|
||||
type: Opaque
|
||||
---
|
||||
apiVersion: kyverno.io/v2beta1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: cpol-clone-sync-modify-downstream-apply
|
||||
spec:
|
||||
rules:
|
||||
- name: cpol-clone-sync-modify-downstream-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
generate:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: regcred
|
||||
namespace: "{{request.object.metadata.name}}"
|
||||
synchronize: true
|
||||
clone:
|
||||
namespace: default
|
||||
name: regcred
|
||||
useServerSideApply: true
|
||||
---
|
Loading…
Add table
Reference in a new issue