1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

feat: consider maxAPICallResponseLength (#9620)

* chore: move global context package out of engine

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

* feat: consider maxAPICallResponseLength

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

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2024-02-02 16:35:57 +01:00 committed by GitHub
parent b59353c657
commit 2b712107d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 47 additions and 18 deletions

View file

@ -335,6 +335,7 @@ The chart values are organised per component.
| features.forceFailurePolicyIgnore.enabled | bool | `false` | Enables the feature |
| features.generateValidatingAdmissionPolicy.enabled | bool | `false` | Enables the feature |
| features.globalContext.enabled | bool | `true` | Enables the feature |
| features.globalContext.maxApiCallResponseLength | int | `2000000` | Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended) |
| features.logging.format | string | `"text"` | Logging format |
| features.logging.verbosity | int | `2` | Logging verbosity |
| features.omitEvents.eventTypes | list | `["PolicyApplied","PolicySkipped"]` | Events which should not be emitted (possible values `PolicyViolation`, `PolicyApplied`, `PolicyError`, and `PolicySkipped`) |

View file

@ -48,6 +48,7 @@
{{- end -}}
{{- with .globalContext -}}
{{- $flags = append $flags (print "--enableGlobalContext=" .enabled) -}}
{{- $flags = append $flags (print "--maxAPICallResponseLength=" (int .maxApiCallResponseLength)) -}}
{{- end -}}
{{- with .logging -}}
{{- $flags = append $flags (print "--loggingFormat=" .format) -}}

View file

@ -632,6 +632,8 @@ features:
globalContext:
# -- Enables the feature
enabled: true
# -- Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended)
maxApiCallResponseLength: 2000000
logging:
# -- Logging format
format: text

View file

@ -161,6 +161,7 @@ func main() {
kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(),
setup.KyvernoDynamicClient,
store.New(),
maxAPICallResponseLength,
),
globalcontextcontroller.Workers,
) // this controller only subscribe to events, nothing is returned...

View file

@ -70,13 +70,14 @@ func sanityChecks(apiserverClient apiserver.Interface) error {
func main() {
var (
dumpPayload bool
serverIP string
servicePort int
webhookServerPort int
maxQueuedEvents int
interval time.Duration
renewBefore time.Duration
dumpPayload bool
serverIP string
servicePort int
webhookServerPort int
maxQueuedEvents int
interval time.Duration
renewBefore time.Duration
maxAPICallResponseLength int64
)
flagset := flag.NewFlagSet("cleanup-controller", flag.ExitOnError)
flagset.BoolVar(&dumpPayload, "dumpPayload", false, "Set this flag to activate/deactivate debug mode.")
@ -89,6 +90,7 @@ func main() {
flagset.StringVar(&caSecretName, "caSecretName", "", "Name of the secret containing CA.")
flagset.StringVar(&tlsSecretName, "tlsSecretName", "", "Name of the secret containing TLS pair.")
flagset.DurationVar(&renewBefore, "renewBefore", 15*24*time.Hour, "The certificate renewal time before expiration")
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 2*1000*1000, "Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended).")
// config
appConfig := internal.NewConfiguration(
internal.WithProfiling(),
@ -165,6 +167,7 @@ func main() {
kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(),
setup.KyvernoDynamicClient,
store.New(),
maxAPICallResponseLength,
),
globalcontextcontroller.Workers,
)

View file

@ -331,6 +331,7 @@ func main() {
kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(),
setup.KyvernoDynamicClient,
store.New(),
maxAPICallResponseLength,
),
globalcontextcontroller.Workers,
)

View file

@ -291,6 +291,7 @@ func main() {
kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(),
setup.KyvernoDynamicClient,
store.New(),
maxAPICallResponseLength,
),
globalcontextcontroller.Workers,
)

View file

@ -51837,6 +51837,7 @@ spec:
- --forceFailurePolicyIgnore=false
- --generateValidatingAdmissionPolicy=false
- --enableGlobalContext=true
- --maxAPICallResponseLength=2000000
- --loggingFormat=text
- --v=2
- --omitEvents=PolicyApplied,PolicySkipped
@ -51989,6 +51990,7 @@ spec:
- --enableConfigMapCaching=true
- --enableDeferredLoading=true
- --enableGlobalContext=true
- --maxAPICallResponseLength=2000000
- --loggingFormat=text
- --v=2
- --omitEvents=PolicyApplied,PolicySkipped
@ -52097,6 +52099,7 @@ spec:
- --enableDeferredLoading=true
- --dumpPayload=false
- --enableGlobalContext=true
- --maxAPICallResponseLength=2000000
- --loggingFormat=text
- --v=2
- --protectManagedResources=false
@ -52238,6 +52241,7 @@ spec:
- --enableConfigMapCaching=true
- --enableDeferredLoading=true
- --enableGlobalContext=true
- --maxAPICallResponseLength=2000000
- --loggingFormat=text
- --v=2
- --omitEvents=PolicyApplied,PolicySkipped

View file

@ -35,14 +35,16 @@ type controller struct {
queue workqueue.RateLimitingInterface
// state
dclient dclient.Interface
store store.Store
dclient dclient.Interface
store store.Store
maxResponseLength int64
}
func NewController(
gceInformer kyvernov2alpha1informers.GlobalContextEntryInformer,
dclient dclient.Interface,
storage store.Store,
maxResponseLength int64,
) controllers.Controller {
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
_, _, err := controllerutils.AddDefaultEventHandlers(logger, gceInformer.Informer(), queue)
@ -50,10 +52,11 @@ func NewController(
logger.Error(err, "failed to register event handlers")
}
return &controller{
gceLister: gceInformer.Lister(),
queue: queue,
dclient: dclient,
store: storage,
gceLister: gceInformer.Lister(),
queue: queue,
dclient: dclient,
store: storage,
maxResponseLength: maxResponseLength,
}
}
@ -98,5 +101,12 @@ func (c *controller) makeStoreEntry(ctx context.Context, gce *kyvernov2alpha1.Gl
}
return k8sresource.New(ctx, c.dclient.GetDynamicInterface(), gvr, gce.Spec.KubernetesResource.Namespace)
}
return externalapi.New(ctx, logger, adapters.Client(c.dclient), gce.Spec.APICall.APICall, gce.Spec.APICall.RefreshInterval.Duration)
return externalapi.New(
ctx,
logger,
adapters.Client(c.dclient),
gce.Spec.APICall.APICall,
gce.Spec.APICall.RefreshInterval.Duration,
c.maxResponseLength,
)
}

View file

@ -17,7 +17,14 @@ type entry struct {
stop func()
}
func New(ctx context.Context, logger logr.Logger, client apicall.ClientInterface, call kyvernov1.APICall, period time.Duration) (*entry, error) {
func New(
ctx context.Context,
logger logr.Logger,
client apicall.ClientInterface,
call kyvernov1.APICall,
period time.Duration,
maxResponseLength int64,
) (*entry, error) {
var group wait.Group
ctx, cancel := context.WithCancel(ctx)
stop := func() {
@ -31,11 +38,9 @@ func New(ctx context.Context, logger logr.Logger, client apicall.ClientInterface
}
group.StartWithContext(ctx, func(ctx context.Context) {
// TODO: make sure we have called it at least once before returning
// TODO: config
config := apicall.NewAPICallConfiguration(10000)
config := apicall.NewAPICallConfiguration(maxResponseLength)
caller := apicall.NewCaller(logger, "TODO", client, config)
wait.UntilWithContext(ctx, func(ctx context.Context) {
// TODO
if data, err := doCall(ctx, caller, call); err != nil {
logger.Error(err, "failed to get data from api caller")
} else {