From f0ed55470ecd5c4f5ec909b7e4bc640236105ee3 Mon Sep 17 00:00:00 2001 From: Alam Ahmad Date: Fri, 21 Nov 2025 16:04:41 +0000 Subject: [PATCH 1/3] atc-installer: configure validation webhook timeout Add support for configuring validation webhook timeout when installing the ATC. - Add ValidationWebhookTimeout field to installer Config - Pass timeout as VALIDATION_WEBHOOK_TIMEOUT environment variable - Load timeout from env var in ATC config - Apply timeout to all validation webhooks (default: 10s) Fixes #129 --- cmd/atc-installer/installer/run.go | 56 ++++++++++++++++++------------ cmd/atc/config.go | 5 +++ cmd/atc/resources.go | 8 ++++- internal/atc/atc.go | 13 ++++--- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/cmd/atc-installer/installer/run.go b/cmd/atc-installer/installer/run.go index 5fac074a..8385f2e4 100644 --- a/cmd/atc-installer/installer/run.go +++ b/cmd/atc-installer/installer/run.go @@ -23,17 +23,18 @@ import ( ) type Config struct { - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` - Image string `json:"image,omitzero" Description:"set the image you want to deploy"` - Version string `json:"version,omitzero" Description:"version of the deployed image"` - Port int `json:"port,omitzero"` - ServiceAccountName string `json:"serviceAccountName,omitzero"` - ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitzero"` - GenerateTLS bool `json:"generateTLS,omitzero" Description:"generate new tls certificates even if they already exist"` - DockerConfigSecretName string `json:"dockerConfigSecretName,omitzero" Description:"name of dockerconfig secret to allow atc to pull images from private registries"` - LogFormat string `json:"logFormat,omitzero" Enum:"json,text"` - Verbose bool `json:"verbose,omitzero" Description:"verbose logging"` + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + Image string `json:"image,omitzero" Description:"set the image you want to deploy"` + Version string `json:"version,omitzero" Description:"version of the deployed image"` + Port int `json:"port,omitzero"` + ServiceAccountName string `json:"serviceAccountName,omitzero"` + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitzero"` + GenerateTLS bool `json:"generateTLS,omitzero" Description:"generate new tls certificates even if they already exist"` + DockerConfigSecretName string `json:"dockerConfigSecretName,omitzero" Description:"name of dockerconfig secret to allow atc to pull images from private registries"` + LogFormat string `json:"logFormat,omitzero" Enum:"json,text"` + Verbose bool `json:"verbose,omitzero" Description:"verbose logging"` + ValidationWebhookTimeout *int32 `json:"validationWebhookTimeout,omitzero" Description:"timeout in seconds for validation webhooks (default: 10)"` } func Run(cfg Config) (flight.Resources, error) { @@ -209,18 +210,27 @@ func Run(cfg Config) (flight.Resources, error) { Name: "yokecd-atc", Image: cmp.Or(cfg.Image, "ghcr.io/yokecd/atc") + ":" + cfg.Version, ImagePullPolicy: cmp.Or(cfg.ImagePullPolicy, corev1.PullIfNotPresent), - Env: []corev1.EnvVar{ - {Name: "PORT", Value: strconv.Itoa(cfg.Port)}, - {Name: "TLS_CA_CERT", Value: "/conf/tls/ca.crt"}, - {Name: "TLS_SERVER_CERT", Value: "/conf/tls/server.crt"}, - {Name: "TLS_SERVER_KEY", Value: "/conf/tls/server.key"}, - {Name: "SVC_NAME", Value: svc.Name}, - {Name: "SVC_NAMESPACE", Value: svc.Namespace}, - {Name: "SVC_PORT", Value: strconv.Itoa(int(svc.Spec.Ports[0].Port))}, - {Name: "DOCKER_CONFIG_SECRET_NAME", Value: cfg.DockerConfigSecretName}, - {Name: "LOG_FORMAT", Value: cfg.LogFormat}, - {Name: "VERBOSE", Value: strconv.FormatBool(cfg.Verbose)}, - }, + Env: func() []corev1.EnvVar { + env := []corev1.EnvVar{ + {Name: "PORT", Value: strconv.Itoa(cfg.Port)}, + {Name: "TLS_CA_CERT", Value: "/conf/tls/ca.crt"}, + {Name: "TLS_SERVER_CERT", Value: "/conf/tls/server.crt"}, + {Name: "TLS_SERVER_KEY", Value: "/conf/tls/server.key"}, + {Name: "SVC_NAME", Value: svc.Name}, + {Name: "SVC_NAMESPACE", Value: svc.Namespace}, + {Name: "SVC_PORT", Value: strconv.Itoa(int(svc.Spec.Ports[0].Port))}, + {Name: "DOCKER_CONFIG_SECRET_NAME", Value: cfg.DockerConfigSecretName}, + {Name: "LOG_FORMAT", Value: cfg.LogFormat}, + {Name: "VERBOSE", Value: strconv.FormatBool(cfg.Verbose)}, + } + if cfg.ValidationWebhookTimeout != nil { + env = append(env, corev1.EnvVar{ + Name: "VALIDATION_WEBHOOK_TIMEOUT", + Value: strconv.FormatInt(int64(*cfg.ValidationWebhookTimeout), 10), + }) + } + return env + }(), VolumeMounts: []corev1.VolumeMount{ { Name: "tls-secrets", diff --git a/cmd/atc/config.go b/cmd/atc/config.go index 1fe2a120..bfc31ecd 100644 --- a/cmd/atc/config.go +++ b/cmd/atc/config.go @@ -20,6 +20,8 @@ type Config struct { Verbose bool + ValidationWebhookTimeout *int32 + TLS TLSConfig } @@ -55,6 +57,8 @@ func LoadConfig() (*Config, error) { conf.Var(parser, &cfg.Verbose, "VERBOSE") + conf.Var(parser, &cfg.ValidationWebhookTimeout, "VALIDATION_WEBHOOK_TIMEOUT") + if err := parser.Parse(); err != nil { return nil, err } @@ -70,6 +74,7 @@ func LoadConfig() (*Config, error) { } cfg.Service.CABundle = cfg.TLS.CA.Data + cfg.Service.ValidationWebhookTimeout = cfg.ValidationWebhookTimeout cfg.Concurrency = max(cfg.Concurrency, 1) return &cfg, nil diff --git a/cmd/atc/resources.go b/cmd/atc/resources.go index 960ecfea..114d193a 100644 --- a/cmd/atc/resources.go +++ b/cmd/atc/resources.go @@ -2,6 +2,7 @@ package main import ( "context" + "cmp" "fmt" "reflect" "strings" @@ -92,6 +93,9 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error return fmt.Errorf("failed to apply airway crd: %w", err) } + // Get timeout value, defaulting to 10 seconds if not configured + timeoutSeconds := cmp.Or(cfg.ValidationWebhookTimeout, ptr.To[int32](10)) + airwayValidation := &admissionregistrationv1.ValidatingWebhookConfiguration{ TypeMeta: metav1.TypeMeta{ APIVersion: admissionregistrationv1.SchemeGroupVersion.Identifier(), @@ -114,6 +118,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error }, SideEffects: ptr.To(admissionregistrationv1.SideEffectClassNone), AdmissionReviewVersions: []string{"v1"}, + TimeoutSeconds: timeoutSeconds, Rules: []admissionregistrationv1.RuleWithOperations{ { Operations: []admissionregistrationv1.OperationType{ @@ -156,6 +161,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error AdmissionReviewVersions: []string{"v1"}, FailurePolicy: ptr.To(admissionregistrationv1.Ignore), MatchPolicy: ptr.To(admissionregistrationv1.Exact), + TimeoutSeconds: timeoutSeconds, MatchConditions: []admissionregistrationv1.MatchCondition{ { Name: "managed-by-atc", @@ -212,7 +218,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error AdmissionReviewVersions: []string{"v1"}, FailurePolicy: ptr.To(admissionregistrationv1.Ignore), MatchPolicy: ptr.To(admissionregistrationv1.Exact), - TimeoutSeconds: ptr.To[int32](1), + TimeoutSeconds: timeoutSeconds, MatchConditions: []admissionregistrationv1.MatchCondition{ { Name: "all", diff --git a/internal/atc/atc.go b/internal/atc/atc.go index 35dfc7f5..6e7ed602 100644 --- a/internal/atc/atc.go +++ b/internal/atc/atc.go @@ -376,6 +376,9 @@ func (atc atc) Reconcile(ctx context.Context, event ctrl.Event) (result ctrl.Res ctrl.Client(ctx).Mapper.Reset() + // Get timeout value, defaulting to 10 seconds if not configured + timeoutSeconds := cmp.Or(atc.service.ValidationWebhookTimeout, ptr.To[int32](10)) + validationWebhook := admissionregistrationv1.ValidatingWebhookConfiguration{ TypeMeta: metav1.TypeMeta{ APIVersion: admissionregistrationv1.SchemeGroupVersion.Identifier(), @@ -406,6 +409,7 @@ func (atc atc) Reconcile(ctx context.Context, event ctrl.Event) (result ctrl.Res }, SideEffects: ptr.To(admissionregistrationv1.SideEffectClassNone), AdmissionReviewVersions: []string{"v1"}, + TimeoutSeconds: timeoutSeconds, Rules: []admissionregistrationv1.RuleWithOperations{ { Operations: []admissionregistrationv1.OperationType{ @@ -941,8 +945,9 @@ func ReleaseName(resource *unstructured.Unstructured) string { } type ServiceDef struct { - Name string - Namespace string - CABundle []byte - Port int32 + Name string + Namespace string + CABundle []byte + Port int32 + ValidationWebhookTimeout *int32 } From d530ce43d6d083f842d723e9e31f2db179344b1c Mon Sep 17 00:00:00 2001 From: Alam Ahmad Date: Sun, 23 Nov 2025 09:27:41 +0000 Subject: [PATCH 2/3] Address review feedback: use int32 instead of *int32, remove from ServiceDef - Change ValidationWebhookTimeout from *int32 to int32 in installer Config - Use strconv.Itoa instead of pointer dereferencing - Remove ValidationWebhookTimeout from ServiceDef (it's for k8s service definition) - Pass timeout as separate parameter to GetReconciler - Add timeout field to atc struct instead Addresses review comments from @davidmdm --- cmd/atc-installer/installer/run.go | 6 +++--- cmd/atc/config.go | 3 +-- cmd/atc/main.go | 2 +- cmd/atc/resources.go | 8 ++++++-- internal/atc/atc.go | 33 ++++++++++++++++++------------ 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/cmd/atc-installer/installer/run.go b/cmd/atc-installer/installer/run.go index 8385f2e4..2a05057d 100644 --- a/cmd/atc-installer/installer/run.go +++ b/cmd/atc-installer/installer/run.go @@ -34,7 +34,7 @@ type Config struct { DockerConfigSecretName string `json:"dockerConfigSecretName,omitzero" Description:"name of dockerconfig secret to allow atc to pull images from private registries"` LogFormat string `json:"logFormat,omitzero" Enum:"json,text"` Verbose bool `json:"verbose,omitzero" Description:"verbose logging"` - ValidationWebhookTimeout *int32 `json:"validationWebhookTimeout,omitzero" Description:"timeout in seconds for validation webhooks (default: 10)"` + ValidationWebhookTimeout int `json:"validationWebhookTimeout,omitzero" Description:"timeout in seconds for validation webhooks (default: 10)"` } func Run(cfg Config) (flight.Resources, error) { @@ -223,10 +223,10 @@ func Run(cfg Config) (flight.Resources, error) { {Name: "LOG_FORMAT", Value: cfg.LogFormat}, {Name: "VERBOSE", Value: strconv.FormatBool(cfg.Verbose)}, } - if cfg.ValidationWebhookTimeout != nil { + if cfg.ValidationWebhookTimeout > 0 { env = append(env, corev1.EnvVar{ Name: "VALIDATION_WEBHOOK_TIMEOUT", - Value: strconv.FormatInt(int64(*cfg.ValidationWebhookTimeout), 10), + Value: strconv.Itoa(cfg.ValidationWebhookTimeout), }) } return env diff --git a/cmd/atc/config.go b/cmd/atc/config.go index bfc31ecd..2dca4756 100644 --- a/cmd/atc/config.go +++ b/cmd/atc/config.go @@ -20,7 +20,7 @@ type Config struct { Verbose bool - ValidationWebhookTimeout *int32 + ValidationWebhookTimeout int32 TLS TLSConfig } @@ -74,7 +74,6 @@ func LoadConfig() (*Config, error) { } cfg.Service.CABundle = cfg.TLS.CA.Data - cfg.Service.ValidationWebhookTimeout = cfg.ValidationWebhookTimeout cfg.Concurrency = max(cfg.Concurrency, 1) return &cfg, nil diff --git a/cmd/atc/main.go b/cmd/atc/main.go index aa762e42..e6c224d9 100644 --- a/cmd/atc/main.go +++ b/cmd/atc/main.go @@ -117,7 +117,7 @@ func run() (err error) { airwayGK := schema.GroupKind{Group: "yoke.cd", Kind: "Airway"} - reconciler, teardown := atc.GetReconciler(cfg.Service, moduleCache, controllers, eventDispatcher, cfg.Concurrency) + reconciler, teardown := atc.GetReconciler(cfg.Service, moduleCache, controllers, eventDispatcher, cfg.Concurrency, cfg.ValidationWebhookTimeout) defer teardown() controller, err := ctrl.NewController(ctx, ctrl.Params{ diff --git a/cmd/atc/resources.go b/cmd/atc/resources.go index 114d193a..d5356025 100644 --- a/cmd/atc/resources.go +++ b/cmd/atc/resources.go @@ -2,7 +2,6 @@ package main import ( "context" - "cmp" "fmt" "reflect" "strings" @@ -94,7 +93,12 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error } // Get timeout value, defaulting to 10 seconds if not configured - timeoutSeconds := cmp.Or(cfg.ValidationWebhookTimeout, ptr.To[int32](10)) + timeoutSeconds := func() *int32 { + if cfg.ValidationWebhookTimeout > 0 { + return ptr.To(cfg.ValidationWebhookTimeout) + } + return ptr.To[int32](10) + }() airwayValidation := &admissionregistrationv1.ValidatingWebhookConfiguration{ TypeMeta: metav1.TypeMeta{ diff --git a/internal/atc/atc.go b/internal/atc/atc.go index 6e7ed602..a13859bb 100644 --- a/internal/atc/atc.go +++ b/internal/atc/atc.go @@ -68,14 +68,15 @@ func (controller Controller) FlightState(name, ns string) (FlightState, bool) { type ControllerCache = xsync.Map[string, Controller] -func GetReconciler(service ServiceDef, cache *wasm.ModuleCache, controllers *ControllerCache, dispatcher *EventDispatcher, concurrency int) (ctrl.HandleFunc, func()) { +func GetReconciler(service ServiceDef, cache *wasm.ModuleCache, controllers *ControllerCache, dispatcher *EventDispatcher, concurrency int, validationWebhookTimeout int32) (ctrl.HandleFunc, func()) { atc := atc{ - concurrency: concurrency, - service: service, - cleanups: map[string]func(){}, - moduleCache: cache, - controllers: controllers, - dispatcher: dispatcher, + concurrency: concurrency, + service: service, + cleanups: map[string]func(){}, + moduleCache: cache, + controllers: controllers, + dispatcher: dispatcher, + validationWebhookTimeout: validationWebhookTimeout, } return atc.Reconcile, atc.Teardown } @@ -88,6 +89,8 @@ type atc struct { service ServiceDef cleanups map[string]func() moduleCache *wasm.ModuleCache + + validationWebhookTimeout int32 } func (atc atc) Reconcile(ctx context.Context, event ctrl.Event) (result ctrl.Result, err error) { @@ -377,7 +380,12 @@ func (atc atc) Reconcile(ctx context.Context, event ctrl.Event) (result ctrl.Res ctrl.Client(ctx).Mapper.Reset() // Get timeout value, defaulting to 10 seconds if not configured - timeoutSeconds := cmp.Or(atc.service.ValidationWebhookTimeout, ptr.To[int32](10)) + timeoutSeconds := func() *int32 { + if atc.validationWebhookTimeout > 0 { + return ptr.To(atc.validationWebhookTimeout) + } + return ptr.To[int32](10) + }() validationWebhook := admissionregistrationv1.ValidatingWebhookConfiguration{ TypeMeta: metav1.TypeMeta{ @@ -945,9 +953,8 @@ func ReleaseName(resource *unstructured.Unstructured) string { } type ServiceDef struct { - Name string - Namespace string - CABundle []byte - Port int32 - ValidationWebhookTimeout *int32 + Name string + Namespace string + CABundle []byte + Port int32 } From 41233d9413da2389253fe45cf0f48d0657ce159a Mon Sep 17 00:00:00 2001 From: Alam Ahmad Date: Sun, 23 Nov 2025 15:04:12 +0000 Subject: [PATCH 3/3] Split validation webhooks by purpose with separate timeout configs - Replace single ValidationWebhookTimeout with three separate fields: - AirwayValidationWebhookTimeout (default: 10s) for airway instances - ResourceValidationWebhookTimeout (default: 5s) for event dispatching - ExternalResourceValidationWebhookTimeout (default: 30s) for external resources - Update installer Config and ATC Config to support separate timeouts - Apply appropriate timeout to each webhook type based on its purpose - Update GetReconciler to use AirwayValidationWebhookTimeout for per-Airway webhooks --- cmd/atc-installer/installer/run.go | 26 ++++++++++++++++++++------ cmd/atc/config.go | 8 ++++++-- cmd/atc/main.go | 2 +- cmd/atc/resources.go | 30 +++++++++++++++++++++++------- internal/atc/atc.go | 4 ++-- 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/cmd/atc-installer/installer/run.go b/cmd/atc-installer/installer/run.go index 2a05057d..bf072dd4 100644 --- a/cmd/atc-installer/installer/run.go +++ b/cmd/atc-installer/installer/run.go @@ -32,9 +32,11 @@ type Config struct { ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitzero"` GenerateTLS bool `json:"generateTLS,omitzero" Description:"generate new tls certificates even if they already exist"` DockerConfigSecretName string `json:"dockerConfigSecretName,omitzero" Description:"name of dockerconfig secret to allow atc to pull images from private registries"` - LogFormat string `json:"logFormat,omitzero" Enum:"json,text"` - Verbose bool `json:"verbose,omitzero" Description:"verbose logging"` - ValidationWebhookTimeout int `json:"validationWebhookTimeout,omitzero" Description:"timeout in seconds for validation webhooks (default: 10)"` + LogFormat string `json:"logFormat,omitzero" Enum:"json,text"` + Verbose bool `json:"verbose,omitzero" Description:"verbose logging"` + AirwayValidationWebhookTimeout int `json:"airwayValidationWebhookTimeout,omitzero" Description:"timeout in seconds for airway instance validation webhooks (default: 10)"` + ResourceValidationWebhookTimeout int `json:"resourceValidationWebhookTimeout,omitzero" Description:"timeout in seconds for resource/event dispatching validation webhooks (default: 5)"` + ExternalResourceValidationWebhookTimeout int `json:"externalResourceValidationWebhookTimeout,omitzero" Description:"timeout in seconds for external resource validation webhooks (default: 30)"` } func Run(cfg Config) (flight.Resources, error) { @@ -223,10 +225,22 @@ func Run(cfg Config) (flight.Resources, error) { {Name: "LOG_FORMAT", Value: cfg.LogFormat}, {Name: "VERBOSE", Value: strconv.FormatBool(cfg.Verbose)}, } - if cfg.ValidationWebhookTimeout > 0 { + if cfg.AirwayValidationWebhookTimeout > 0 { env = append(env, corev1.EnvVar{ - Name: "VALIDATION_WEBHOOK_TIMEOUT", - Value: strconv.Itoa(cfg.ValidationWebhookTimeout), + Name: "AIRWAY_VALIDATION_WEBHOOK_TIMEOUT", + Value: strconv.Itoa(cfg.AirwayValidationWebhookTimeout), + }) + } + if cfg.ResourceValidationWebhookTimeout > 0 { + env = append(env, corev1.EnvVar{ + Name: "RESOURCE_VALIDATION_WEBHOOK_TIMEOUT", + Value: strconv.Itoa(cfg.ResourceValidationWebhookTimeout), + }) + } + if cfg.ExternalResourceValidationWebhookTimeout > 0 { + env = append(env, corev1.EnvVar{ + Name: "EXTERNAL_RESOURCE_VALIDATION_WEBHOOK_TIMEOUT", + Value: strconv.Itoa(cfg.ExternalResourceValidationWebhookTimeout), }) } return env diff --git a/cmd/atc/config.go b/cmd/atc/config.go index 2dca4756..e4bf10a5 100644 --- a/cmd/atc/config.go +++ b/cmd/atc/config.go @@ -20,7 +20,9 @@ type Config struct { Verbose bool - ValidationWebhookTimeout int32 + AirwayValidationWebhookTimeout int32 + ResourceValidationWebhookTimeout int32 + ExternalResourceValidationWebhookTimeout int32 TLS TLSConfig } @@ -57,7 +59,9 @@ func LoadConfig() (*Config, error) { conf.Var(parser, &cfg.Verbose, "VERBOSE") - conf.Var(parser, &cfg.ValidationWebhookTimeout, "VALIDATION_WEBHOOK_TIMEOUT") + conf.Var(parser, &cfg.AirwayValidationWebhookTimeout, "AIRWAY_VALIDATION_WEBHOOK_TIMEOUT") + conf.Var(parser, &cfg.ResourceValidationWebhookTimeout, "RESOURCE_VALIDATION_WEBHOOK_TIMEOUT") + conf.Var(parser, &cfg.ExternalResourceValidationWebhookTimeout, "EXTERNAL_RESOURCE_VALIDATION_WEBHOOK_TIMEOUT") if err := parser.Parse(); err != nil { return nil, err diff --git a/cmd/atc/main.go b/cmd/atc/main.go index e6c224d9..8fa55ffc 100644 --- a/cmd/atc/main.go +++ b/cmd/atc/main.go @@ -117,7 +117,7 @@ func run() (err error) { airwayGK := schema.GroupKind{Group: "yoke.cd", Kind: "Airway"} - reconciler, teardown := atc.GetReconciler(cfg.Service, moduleCache, controllers, eventDispatcher, cfg.Concurrency, cfg.ValidationWebhookTimeout) + reconciler, teardown := atc.GetReconciler(cfg.Service, moduleCache, controllers, eventDispatcher, cfg.Concurrency, cfg.AirwayValidationWebhookTimeout) defer teardown() controller, err := ctrl.NewController(ctx, ctrl.Params{ diff --git a/cmd/atc/resources.go b/cmd/atc/resources.go index d5356025..161d80ec 100644 --- a/cmd/atc/resources.go +++ b/cmd/atc/resources.go @@ -92,14 +92,30 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error return fmt.Errorf("failed to apply airway crd: %w", err) } - // Get timeout value, defaulting to 10 seconds if not configured - timeoutSeconds := func() *int32 { - if cfg.ValidationWebhookTimeout > 0 { - return ptr.To(cfg.ValidationWebhookTimeout) + // Get timeout value for airway validation webhook, defaulting to 10 seconds if not configured + airwayTimeoutSeconds := func() *int32 { + if cfg.AirwayValidationWebhookTimeout > 0 { + return ptr.To(cfg.AirwayValidationWebhookTimeout) } return ptr.To[int32](10) }() + // Get timeout value for resource validation webhook (event dispatching), defaulting to 5 seconds if not configured + resourceTimeoutSeconds := func() *int32 { + if cfg.ResourceValidationWebhookTimeout > 0 { + return ptr.To(cfg.ResourceValidationWebhookTimeout) + } + return ptr.To[int32](5) + }() + + // Get timeout value for external resource validation webhook, defaulting to 30 seconds if not configured + externalResourceTimeoutSeconds := func() *int32 { + if cfg.ExternalResourceValidationWebhookTimeout > 0 { + return ptr.To(cfg.ExternalResourceValidationWebhookTimeout) + } + return ptr.To[int32](30) + }() + airwayValidation := &admissionregistrationv1.ValidatingWebhookConfiguration{ TypeMeta: metav1.TypeMeta{ APIVersion: admissionregistrationv1.SchemeGroupVersion.Identifier(), @@ -122,7 +138,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error }, SideEffects: ptr.To(admissionregistrationv1.SideEffectClassNone), AdmissionReviewVersions: []string{"v1"}, - TimeoutSeconds: timeoutSeconds, + TimeoutSeconds: airwayTimeoutSeconds, Rules: []admissionregistrationv1.RuleWithOperations{ { Operations: []admissionregistrationv1.OperationType{ @@ -165,7 +181,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error AdmissionReviewVersions: []string{"v1"}, FailurePolicy: ptr.To(admissionregistrationv1.Ignore), MatchPolicy: ptr.To(admissionregistrationv1.Exact), - TimeoutSeconds: timeoutSeconds, + TimeoutSeconds: resourceTimeoutSeconds, MatchConditions: []admissionregistrationv1.MatchCondition{ { Name: "managed-by-atc", @@ -222,7 +238,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error AdmissionReviewVersions: []string{"v1"}, FailurePolicy: ptr.To(admissionregistrationv1.Ignore), MatchPolicy: ptr.To(admissionregistrationv1.Exact), - TimeoutSeconds: timeoutSeconds, + TimeoutSeconds: externalResourceTimeoutSeconds, MatchConditions: []admissionregistrationv1.MatchCondition{ { Name: "all", diff --git a/internal/atc/atc.go b/internal/atc/atc.go index a13859bb..9817dcb1 100644 --- a/internal/atc/atc.go +++ b/internal/atc/atc.go @@ -68,7 +68,7 @@ func (controller Controller) FlightState(name, ns string) (FlightState, bool) { type ControllerCache = xsync.Map[string, Controller] -func GetReconciler(service ServiceDef, cache *wasm.ModuleCache, controllers *ControllerCache, dispatcher *EventDispatcher, concurrency int, validationWebhookTimeout int32) (ctrl.HandleFunc, func()) { +func GetReconciler(service ServiceDef, cache *wasm.ModuleCache, controllers *ControllerCache, dispatcher *EventDispatcher, concurrency int, airwayValidationWebhookTimeout int32) (ctrl.HandleFunc, func()) { atc := atc{ concurrency: concurrency, service: service, @@ -76,7 +76,7 @@ func GetReconciler(service ServiceDef, cache *wasm.ModuleCache, controllers *Con moduleCache: cache, controllers: controllers, dispatcher: dispatcher, - validationWebhookTimeout: validationWebhookTimeout, + validationWebhookTimeout: airwayValidationWebhookTimeout, } return atc.Reconcile, atc.Teardown }