1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-18 02:06:52 +00:00

feat: use context for toggles management ()

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-06-12 17:36:12 +02:00 committed by GitHub
parent 3d5ed2b4e5
commit 1401bcf2fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 78 additions and 36 deletions
api/kyverno/v1
cmd/kyverno
pkg
controllers/webhook
toggle
webhooks
resource
handlers.go
imageverification
validation
server.go

View file

@ -1,6 +1,7 @@
package v1
import (
"context"
"fmt"
"github.com/kyverno/kyverno/pkg/toggle"
@ -218,8 +219,8 @@ func (s *Spec) IsGenerateExisting() bool {
}
// GetFailurePolicy returns the failure policy to be applied
func (s *Spec) GetFailurePolicy() FailurePolicyType {
if toggle.ForceFailurePolicyIgnore.Enabled() {
func (s *Spec) GetFailurePolicy(ctx context.Context) FailurePolicyType {
if toggle.FromContext(ctx).ForceFailurePolicyIgnore() {
return Ignore
} else if s.FailurePolicy == nil {
return Fail

View file

@ -52,10 +52,10 @@ const (
exceptionWebhookControllerName = "exception-webhook-controller"
)
func showWarnings(logger logr.Logger) {
func showWarnings(ctx context.Context, logger logr.Logger) {
logger = logger.WithName("warnings")
// log if `forceFailurePolicyIgnore` flag has been set or not
if toggle.ForceFailurePolicyIgnore.Enabled() {
if toggle.FromContext(ctx).ForceFailurePolicyIgnore() {
logger.Info("'ForceFailurePolicyIgnore' is enabled, all policies with policy failures will be set to Ignore")
}
}
@ -222,7 +222,7 @@ func main() {
signalCtx, setup, sdown := internal.Setup(appConfig, "kyverno-admission-controller", false)
defer sdown()
// show version
showWarnings(setup.Logger)
showWarnings(signalCtx, setup.Logger)
// THIS IS AN UGLY FIX
// ELSE KYAML IS NOT THREAD SAFE
kyamlopenapi.Schema()
@ -434,6 +434,7 @@ func main() {
Namespace: internal.ExceptionNamespace(),
})
server := webhooks.NewServer(
signalCtx,
policyHandlers,
resourceHandlers,
exceptionHandlers,

View file

@ -339,12 +339,12 @@ func (c *controller) reconcileVerifyMutatingWebhookConfiguration(ctx context.Con
return c.reconcileMutatingWebhookConfiguration(ctx, true, c.buildVerifyMutatingWebhookConfiguration)
}
func (c *controller) reconcileValidatingWebhookConfiguration(ctx context.Context, autoUpdateWebhooks bool, build func(config.Configuration, []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error)) error {
func (c *controller) reconcileValidatingWebhookConfiguration(ctx context.Context, autoUpdateWebhooks bool, build func(context.Context, config.Configuration, []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error)) error {
caData, err := tls.ReadRootCASecret(c.secretLister.Secrets(config.KyvernoNamespace()))
if err != nil {
return err
}
desired, err := build(c.configuration, caData)
desired, err := build(ctx, c.configuration, caData)
if err != nil {
return err
}
@ -369,12 +369,12 @@ func (c *controller) reconcileValidatingWebhookConfiguration(ctx context.Context
return err
}
func (c *controller) reconcileMutatingWebhookConfiguration(ctx context.Context, autoUpdateWebhooks bool, build func(config.Configuration, []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error)) error {
func (c *controller) reconcileMutatingWebhookConfiguration(ctx context.Context, autoUpdateWebhooks bool, build func(context.Context, config.Configuration, []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error)) error {
caData, err := tls.ReadRootCASecret(c.secretLister.Secrets(config.KyvernoNamespace()))
if err != nil {
return err
}
desired, err := build(c.configuration, caData)
desired, err := build(ctx, c.configuration, caData)
if err != nil {
return err
}
@ -496,7 +496,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
return nil
}
func (c *controller) buildVerifyMutatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
func (c *controller) buildVerifyMutatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
return &admissionregistrationv1.MutatingWebhookConfiguration{
ObjectMeta: objectMeta(config.VerifyMutatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.MutatingWebhook{{
@ -523,7 +523,7 @@ func (c *controller) buildVerifyMutatingWebhookConfiguration(cfg config.Configur
nil
}
func (c *controller) buildPolicyMutatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
func (c *controller) buildPolicyMutatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
return &admissionregistrationv1.MutatingWebhookConfiguration{
ObjectMeta: objectMeta(config.PolicyMutatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.MutatingWebhook{{
@ -546,7 +546,7 @@ func (c *controller) buildPolicyMutatingWebhookConfiguration(cfg config.Configur
nil
}
func (c *controller) buildPolicyValidatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
func (c *controller) buildPolicyValidatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
return &admissionregistrationv1.ValidatingWebhookConfiguration{
ObjectMeta: objectMeta(config.PolicyValidatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.ValidatingWebhook{{
@ -568,7 +568,7 @@ func (c *controller) buildPolicyValidatingWebhookConfiguration(cfg config.Config
nil
}
func (c *controller) buildDefaultResourceMutatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
func (c *controller) buildDefaultResourceMutatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
return &admissionregistrationv1.MutatingWebhookConfiguration{
ObjectMeta: objectMeta(config.MutatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.MutatingWebhook{{
@ -614,7 +614,7 @@ func (c *controller) buildDefaultResourceMutatingWebhookConfiguration(cfg config
nil
}
func (c *controller) buildResourceMutatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
func (c *controller) buildResourceMutatingWebhookConfiguration(ctx context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {
result := admissionregistrationv1.MutatingWebhookConfiguration{
ObjectMeta: objectMeta(config.MutatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.MutatingWebhook{},
@ -630,7 +630,7 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(cfg config.Config
for _, p := range policies {
spec := p.GetSpec()
if spec.HasMutate() || spec.HasVerifyImages() {
if spec.GetFailurePolicy() == kyvernov1.Ignore {
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignore, p, false)
} else {
c.mergeWebhook(fail, p, false)
@ -684,7 +684,7 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(cfg config.Config
return &result, nil
}
func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(_ context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
sideEffects := &none
if c.admissionReports {
sideEffects = &noneOnDryRun
@ -736,7 +736,7 @@ func (c *controller) buildDefaultResourceValidatingWebhookConfiguration(cfg conf
nil
}
func (c *controller) buildResourceValidatingWebhookConfiguration(cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
func (c *controller) buildResourceValidatingWebhookConfiguration(ctx context.Context, cfg config.Configuration, caBundle []byte) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) {
result := admissionregistrationv1.ValidatingWebhookConfiguration{
ObjectMeta: objectMeta(config.ValidatingWebhookConfigurationName, cfg.GetWebhookAnnotations(), c.buildOwner()...),
Webhooks: []admissionregistrationv1.ValidatingWebhook{},
@ -752,7 +752,7 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(cfg config.Conf
for _, p := range policies {
spec := p.GetSpec()
if spec.HasValidate() || spec.HasGenerate() || spec.HasMutate() || spec.HasVerifyImageChecks() || spec.HasVerifyManifests() {
if spec.GetFailurePolicy() == kyvernov1.Ignore {
if spec.GetFailurePolicy(ctx) == kyvernov1.Ignore {
c.mergeWebhook(ignore, p, true)
} else {
c.mergeWebhook(fail, p, true)

35
pkg/toggle/context.go Normal file
View file

@ -0,0 +1,35 @@
package toggle
import (
"context"
)
var defaults Toggles = defaultToggles{}
type Toggles interface {
ProtectManagedResources() bool
ForceFailurePolicyIgnore() bool
}
type defaultToggles struct{}
func (defaultToggles) ProtectManagedResources() bool {
return ProtectManagedResources.enabled()
}
func (defaultToggles) ForceFailurePolicyIgnore() bool {
return ForceFailurePolicyIgnore.enabled()
}
type contextKey struct{}
func NewContext(ctx context.Context, toggles Toggles) context.Context {
return context.WithValue(ctx, contextKey{}, toggles)
}
func FromContext(ctx context.Context) Toggles {
if toggles, ok := ctx.Value(contextKey{}).(Toggles); ok {
return toggles
}
return defaults
}

View file

@ -23,18 +23,22 @@ var (
ForceFailurePolicyIgnore = newToggle(defaultForceFailurePolicyIgnore, forceFailurePolicyIgnoreEnvVar)
)
type Toggle interface {
Enabled() bool
type ToggleFlag interface {
Parse(string) error
}
type Toggle interface {
ToggleFlag
enabled() bool
}
type toggle struct {
value *bool
defaultValue bool
envVar string
}
func newToggle(defaultValue bool, envVar string) *toggle {
func newToggle(defaultValue bool, envVar string) Toggle {
return &toggle{
defaultValue: defaultValue,
envVar: envVar,
@ -50,7 +54,7 @@ func (t *toggle) Parse(in string) error {
}
}
func (t *toggle) Enabled() bool {
func (t *toggle) enabled() bool {
if t.value != nil {
return *t.value
}

View file

@ -169,7 +169,7 @@ func Test_toggle_Enabled(t *testing.T) {
}
tr := newToggle(tt.fields.defaultValue, tt.fields.envVar)
tr.Parse(tt.value)
got := tr.Enabled()
got := tr.enabled()
assert.Equal(t, tt.want, got)
})
}

View file

@ -110,10 +110,10 @@ func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, req
// timestamp at which this admission request got triggered
gvr := schema.GroupVersionResource(request.Resource)
policies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.ValidateEnforce, gvr, request.SubResource, request.Namespace)...)
mutatePolicies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
generatePolicies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.Generate, gvr, request.SubResource, request.Namespace)...)
imageVerifyValidatePolicies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesValidate, gvr, request.SubResource, request.Namespace)...)
policies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.ValidateEnforce, gvr, request.SubResource, request.Namespace)...)
mutatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
generatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Generate, gvr, request.SubResource, request.Namespace)...)
imageVerifyValidatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesValidate, gvr, request.SubResource, request.Namespace)...)
policies = append(policies, imageVerifyValidatePolicies...)
if len(policies) == 0 && len(mutatePolicies) == 0 && len(generatePolicies) == 0 {
@ -150,8 +150,8 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
logger = logger.WithValues("kind", kind)
logger.V(4).Info("received an admission request in mutating webhook")
gvr := schema.GroupVersionResource(request.Resource)
mutatePolicies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
verifyImagesPolicies := filterPolicies(failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesMutate, gvr, request.SubResource, request.Namespace)...)
mutatePolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.Mutate, gvr, request.SubResource, request.Namespace)...)
verifyImagesPolicies := filterPolicies(ctx, failurePolicy, h.pCache.GetPolicies(policycache.VerifyImagesMutate, gvr, request.SubResource, request.Namespace)...)
if len(mutatePolicies) == 0 && len(verifyImagesPolicies) == 0 {
logger.V(4).Info("no policies matched mutate admission request")
return admissionutils.ResponseSuccess(request.UID)
@ -188,15 +188,15 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
return admissionutils.MutationResponse(request.UID, patch, warnings...)
}
func filterPolicies(failurePolicy string, policies ...kyvernov1.PolicyInterface) []kyvernov1.PolicyInterface {
func filterPolicies(ctx context.Context, failurePolicy string, policies ...kyvernov1.PolicyInterface) []kyvernov1.PolicyInterface {
var results []kyvernov1.PolicyInterface
for _, policy := range policies {
if failurePolicy == "fail" {
if policy.GetSpec().GetFailurePolicy() == kyvernov1.Fail {
if policy.GetSpec().GetFailurePolicy(ctx) == kyvernov1.Fail {
results = append(results, policy)
}
} else if failurePolicy == "ignore" {
if policy.GetSpec().GetFailurePolicy() == kyvernov1.Ignore {
if policy.GetSpec().GetFailurePolicy(ctx) == kyvernov1.Ignore {
results = append(results, policy)
}
} else {

View file

@ -96,7 +96,7 @@ func (h *imageVerificationHandler) handleVerifyImages(
"",
fmt.Sprintf("POLICY %s/%s", policy.GetNamespace(), policy.GetName()),
func(ctx context.Context, span trace.Span) {
if policy.GetSpec().GetFailurePolicy() == kyvernov1.Fail {
if policy.GetSpec().GetFailurePolicy(ctx) == kyvernov1.Fail {
failurePolicy = kyvernov1.Fail
}

View file

@ -87,7 +87,7 @@ func (v *validationHandler) HandleValidation(
fmt.Sprintf("POLICY %s/%s", policy.GetNamespace(), policy.GetName()),
func(ctx context.Context, span trace.Span) {
policyContext := policyContext.WithPolicy(policy)
if policy.GetSpec().GetFailurePolicy() == kyvernov1.Fail {
if policy.GetSpec().GetFailurePolicy(ctx) == kyvernov1.Fail {
failurePolicy = kyvernov1.Fail
}

View file

@ -69,6 +69,7 @@ type TlsProvider func() ([]byte, []byte, error)
// NewServer creates new instance of server accordingly to given configuration
func NewServer(
ctx context.Context,
policyHandlers PolicyHandlers,
resourceHandlers ResourceHandlers,
exceptionHandlers ExceptionHandlers,
@ -97,7 +98,7 @@ func NewServer(
func(handler handlers.AdmissionHandler) handlers.HttpHandler {
return handler.
WithFilter(configuration).
WithProtection(toggle.ProtectManagedResources.Enabled()).
WithProtection(toggle.FromContext(ctx).ProtectManagedResources()).
WithDump(debugModeOpts.DumpPayload).
WithTopLevelGVK(discovery).
WithRoles(rbLister, crbLister).
@ -114,7 +115,7 @@ func NewServer(
func(handler handlers.AdmissionHandler) handlers.HttpHandler {
return handler.
WithFilter(configuration).
WithProtection(toggle.ProtectManagedResources.Enabled()).
WithProtection(toggle.FromContext(ctx).ProtectManagedResources()).
WithDump(debugModeOpts.DumpPayload).
WithTopLevelGVK(discovery).
WithRoles(rbLister, crbLister).