Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 47 additions & 23 deletions cmd/atc-installer/installer/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ 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"`
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) {
Expand Down Expand Up @@ -209,18 +212,39 @@ 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.AirwayValidationWebhookTimeout > 0 {
env = append(env, corev1.EnvVar{
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
}(),
VolumeMounts: []corev1.VolumeMount{
{
Name: "tls-secrets",
Expand Down
8 changes: 8 additions & 0 deletions cmd/atc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type Config struct {

Verbose bool

AirwayValidationWebhookTimeout int32
ResourceValidationWebhookTimeout int32
ExternalResourceValidationWebhookTimeout int32

TLS TLSConfig
}

Expand Down Expand Up @@ -55,6 +59,10 @@ func LoadConfig() (*Config, error) {

conf.Var(parser, &cfg.Verbose, "VERBOSE")

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
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/atc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.AirwayValidationWebhookTimeout)
defer teardown()

controller, err := ctrl.NewController(ctx, ctrl.Params{
Expand Down
28 changes: 27 additions & 1 deletion cmd/atc/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +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 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(),
Expand All @@ -114,6 +138,7 @@ func ApplyResources(ctx context.Context, client *k8s.Client, cfg *Config) error
},
SideEffects: ptr.To(admissionregistrationv1.SideEffectClassNone),
AdmissionReviewVersions: []string{"v1"},
TimeoutSeconds: airwayTimeoutSeconds,
Rules: []admissionregistrationv1.RuleWithOperations{
{
Operations: []admissionregistrationv1.OperationType{
Expand Down Expand Up @@ -156,6 +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: resourceTimeoutSeconds,
MatchConditions: []admissionregistrationv1.MatchCondition{
{
Name: "managed-by-atc",
Expand Down Expand Up @@ -212,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: ptr.To[int32](1),
TimeoutSeconds: externalResourceTimeoutSeconds,
MatchConditions: []admissionregistrationv1.MatchCondition{
{
Name: "all",
Expand Down
26 changes: 19 additions & 7 deletions internal/atc/atc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, airwayValidationWebhookTimeout 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: airwayValidationWebhookTimeout,
}
return atc.Reconcile, atc.Teardown
}
Expand All @@ -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) {
Expand Down Expand Up @@ -376,6 +379,14 @@ 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 := func() *int32 {
if atc.validationWebhookTimeout > 0 {
return ptr.To(atc.validationWebhookTimeout)
}
return ptr.To[int32](10)
}()

validationWebhook := admissionregistrationv1.ValidatingWebhookConfiguration{
TypeMeta: metav1.TypeMeta{
APIVersion: admissionregistrationv1.SchemeGroupVersion.Identifier(),
Expand Down Expand Up @@ -406,6 +417,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{
Expand Down