From ba14f4ec05fede78ef62c230c0b887339fb9121d Mon Sep 17 00:00:00 2001 From: Fernando Royo Date: Wed, 23 Oct 2024 17:53:29 +0200 Subject: [PATCH] Add configurable httpd timeout This patch adds an apiTimeout field to the OctaviaSpecCore to the already OctaviaSpec one to allow configure the timeouts for HAProxy and Apache. Inherit from the controller in case it is not specified by the user. Also fixing *core* API spec version of the new GetDefaultRouteAnnotations function. Jira: https://issues.redhat.com/browse/OSPRH-6713 --- .../octavia.openstack.org_octaviaapis.yaml | 4 +++ api/bases/octavia.openstack.org_octavias.yaml | 8 ++++- api/v1beta1/octavia_types.go | 9 ++--- api/v1beta1/octavia_webhook.go | 35 ++++++++++++++++--- api/v1beta1/octaviaapi_types.go | 4 +++ .../octavia.openstack.org_octaviaapis.yaml | 4 +++ .../bases/octavia.openstack.org_octavias.yaml | 8 ++++- config/default/manager_default_images.yaml | 2 -- controllers/octavia_controller.go | 2 ++ controllers/octaviaapi_controller.go | 2 ++ templates/octaviaapi/config/httpd.conf | 2 ++ 11 files changed, 67 insertions(+), 13 deletions(-) diff --git a/api/bases/octavia.openstack.org_octaviaapis.yaml b/api/bases/octavia.openstack.org_octaviaapis.yaml index a7fad9ca..2213b38a 100644 --- a/api/bases/octavia.openstack.org_octaviaapis.yaml +++ b/api/bases/octavia.openstack.org_octaviaapis.yaml @@ -48,6 +48,10 @@ spec: spec: description: OctaviaAPISpec defines the desired state of OctaviaAPI properties: + apiTimeout: + description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore + APITimeout (seconds) + type: integer containerImage: description: Octavia Container Image URL type: string diff --git a/api/bases/octavia.openstack.org_octavias.yaml b/api/bases/octavia.openstack.org_octavias.yaml index 359d8fdc..e55ddef1 100644 --- a/api/bases/octavia.openstack.org_octavias.yaml +++ b/api/bases/octavia.openstack.org_octavias.yaml @@ -75,8 +75,9 @@ spec: description: Apache Container Image URL type: string apiTimeout: + default: 120 description: Octavia API timeout - type: string + type: integer customServiceConfig: default: '# add your customization here' description: CustomServiceConfig - customize the service config using @@ -150,6 +151,10 @@ spec: description: OctaviaAPI - Spec definition for the API service of the Octavia deployment properties: + apiTimeout: + description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore + APITimeout (seconds) + type: integer containerImage: description: Octavia Container Image URL type: string @@ -1381,6 +1386,7 @@ spec: type: string required: - apacheContainerImage + - apiTimeout - databaseInstance - octaviaAPI - octaviaNetworkAttachment diff --git a/api/v1beta1/octavia_types.go b/api/v1beta1/octavia_types.go index b3d46ebe..e95e6a1e 100644 --- a/api/v1beta1/octavia_types.go +++ b/api/v1beta1/octavia_types.go @@ -42,7 +42,7 @@ const ( ApacheContainerImage = "registry.redhat.io/ubi9/httpd-24:latest" // Octavia API timeout - APITimeout = "120" + APITimeout = 120 ) // OctaviaSpec defines the desired state of Octavia @@ -204,9 +204,10 @@ type OctaviaSpecBase struct { // Apache Container Image URL ApacheContainerImage string `json:"apacheContainerImage"` - // +kubebuilder:validation:Optional + // +kubebuilder:validation:Required + // +kubebuilder:default=120 // Octavia API timeout - APITimeout string `json:"apiTimeout,omitempty"` + APITimeout int `json:"apiTimeout"` // +kubebuilder:validation:Required // +kubebuilder:default=octavia @@ -366,7 +367,7 @@ func SetupDefaults() { HealthManagerContainerImageURL: util.GetEnvVar("RELATED_IMAGE_OCTAVIA_HEALTHMANAGER_IMAGE_URL_DEFAULT", OctaviaHealthManagerContainerImage), WorkerContainerImageURL: util.GetEnvVar("RELATED_IMAGE_OCTAVIA_WORKER_IMAGE_URL_DEFAULT", OctaviaWorkerContainerImage), ApacheContainerImageURL: util.GetEnvVar("RELATED_IMAGE_OCTAVIA_APACHE_IMAGE_URL_DEFAULT", ApacheContainerImage), - OctaviaAPIRouteTimeout: util.GetEnvVar("OCTAVIA_API_TIMEOUT", APITimeout), + OctaviaAPIRouteTimeout: APITimeout, // No default for AmphoraImageContainerImageURL } diff --git a/api/v1beta1/octavia_webhook.go b/api/v1beta1/octavia_webhook.go index fa43cd7f..f42bc034 100644 --- a/api/v1beta1/octavia_webhook.go +++ b/api/v1beta1/octavia_webhook.go @@ -37,7 +37,7 @@ type OctaviaDefaults struct { HealthManagerContainerImageURL string WorkerContainerImageURL string ApacheContainerImageURL string - OctaviaAPIRouteTimeout string + OctaviaAPIRouteTimeout int } var octaviaDefaults OctaviaDefaults @@ -198,9 +198,34 @@ func (r *Octavia) ValidateDelete() (admission.Warnings, error) { return nil, nil } -func (spec *OctaviaSpec) GetDefaultRouteAnnotations() (annotations map[string]string) { - annotations = map[string]string{ - "haproxy.router.openshift.io/timeout": octaviaDefaults.OctaviaAPIRouteTimeout, +func (spec *OctaviaSpecCore) GetDefaultRouteAnnotations() (annotations map[string]string) { + return map[string]string{ + "haproxy.router.openshift.io/timeout": fmt.Sprintf("%ds", octaviaDefaults.OctaviaAPIRouteTimeout), } - return +} + +// SetDefaultRouteAnnotations sets HAProxy timeout values of the route +func (spec *OctaviaSpecCore) SetDefaultRouteAnnotations(annotations map[string]string) { + const haProxyAnno = "haproxy.router.openshift.io/timeout" + // Use a custom annotation to flag when the operator has set the default HAProxy timeout + // With the annotation func determines when to overwrite existing HAProxy timeout with the APITimeout + const octaviaAnno = "api.octavia.openstack.org/timeout" + + valOctavia, okOctavia := annotations[octaviaAnno] + valHAProxy, okHAProxy := annotations[haProxyAnno] + + // Human operator set the HAProxy timeout manually + if !okOctavia && okHAProxy { + return + } + + // Human operator modified the HAProxy timeout manually without removing the Octavia flag + if okOctavia && okHAProxy && valOctavia != valHAProxy { + delete(annotations, octaviaAnno) + return + } + + timeout := fmt.Sprintf("%ds", spec.APITimeout) + annotations[octaviaAnno] = timeout + annotations[haProxyAnno] = timeout } diff --git a/api/v1beta1/octaviaapi_types.go b/api/v1beta1/octaviaapi_types.go index 2323590e..73c28179 100644 --- a/api/v1beta1/octaviaapi_types.go +++ b/api/v1beta1/octaviaapi_types.go @@ -141,6 +141,10 @@ type OctaviaAPISpecCore struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // TLS - Parameters related to the TLS TLS OctaviaApiTLS `json:"tls,omitempty"` + + // +kubebuilder:validation:Optional + // APITimeout for HAProxy and Apache defaults to OctaviaSpecCore APITimeout (seconds) + APITimeout int `json:"apiTimeout"` } type OctaviaApiTLS struct { diff --git a/config/crd/bases/octavia.openstack.org_octaviaapis.yaml b/config/crd/bases/octavia.openstack.org_octaviaapis.yaml index a7fad9ca..2213b38a 100644 --- a/config/crd/bases/octavia.openstack.org_octaviaapis.yaml +++ b/config/crd/bases/octavia.openstack.org_octaviaapis.yaml @@ -48,6 +48,10 @@ spec: spec: description: OctaviaAPISpec defines the desired state of OctaviaAPI properties: + apiTimeout: + description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore + APITimeout (seconds) + type: integer containerImage: description: Octavia Container Image URL type: string diff --git a/config/crd/bases/octavia.openstack.org_octavias.yaml b/config/crd/bases/octavia.openstack.org_octavias.yaml index 359d8fdc..e55ddef1 100644 --- a/config/crd/bases/octavia.openstack.org_octavias.yaml +++ b/config/crd/bases/octavia.openstack.org_octavias.yaml @@ -75,8 +75,9 @@ spec: description: Apache Container Image URL type: string apiTimeout: + default: 120 description: Octavia API timeout - type: string + type: integer customServiceConfig: default: '# add your customization here' description: CustomServiceConfig - customize the service config using @@ -150,6 +151,10 @@ spec: description: OctaviaAPI - Spec definition for the API service of the Octavia deployment properties: + apiTimeout: + description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore + APITimeout (seconds) + type: integer containerImage: description: Octavia Container Image URL type: string @@ -1381,6 +1386,7 @@ spec: type: string required: - apacheContainerImage + - apiTimeout - databaseInstance - octaviaAPI - octaviaNetworkAttachment diff --git a/config/default/manager_default_images.yaml b/config/default/manager_default_images.yaml index 05009258..33b65576 100644 --- a/config/default/manager_default_images.yaml +++ b/config/default/manager_default_images.yaml @@ -21,5 +21,3 @@ spec: value: quay.io/podified-antelope-centos9/openstack-octavia-worker:current-podified - name: RELATED_IMAGE_OCTAVIA_APACHE_IMAGE_URL_DEFAULT value: registry.redhat.io/ubi9/httpd-24:latest - - name: OCTAVIA_API_TIMEOUT - value: "120" diff --git a/controllers/octavia_controller.go b/controllers/octavia_controller.go index 15b07c8e..6c3c94df 100644 --- a/controllers/octavia_controller.go +++ b/controllers/octavia_controller.go @@ -1481,6 +1481,8 @@ func (r *OctaviaReconciler) apiDeploymentCreateOrUpdate(instance *octaviav1.Octa deployment.Spec.Secret = instance.Spec.Secret deployment.Spec.ServiceAccount = instance.RbacResourceName() deployment.Spec.TLS = instance.Spec.OctaviaAPI.TLS + deployment.Spec.APITimeout = instance.Spec.APITimeout + if len(deployment.Spec.NodeSelector) == 0 { deployment.Spec.NodeSelector = instance.Spec.NodeSelector } diff --git a/controllers/octaviaapi_controller.go b/controllers/octaviaapi_controller.go index 782c4d93..d76fe1b6 100644 --- a/controllers/octaviaapi_controller.go +++ b/controllers/octaviaapi_controller.go @@ -978,6 +978,8 @@ func (r *OctaviaAPIReconciler) generateServiceSecrets( } templateParameters["OVNDB_TLS"] = instance.Spec.TLS.Ovn.Enabled() + templateParameters["TimeOut"] = instance.Spec.APITimeout + // create httpd vhost template parameters httpdVhostConfig := map[string]interface{}{} for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { diff --git a/templates/octaviaapi/config/httpd.conf b/templates/octaviaapi/config/httpd.conf index 45f233f9..0720a327 100644 --- a/templates/octaviaapi/config/httpd.conf +++ b/templates/octaviaapi/config/httpd.conf @@ -35,6 +35,8 @@ CustomLog /dev/stdout proxy env=forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded + TimeOut {{ $.TimeOut }} + {{- if $vhost.TLS }} SetEnvIf X-Forwarded-Proto https HTTPS=1