diff --git a/pkg/ingress/controller/controller.go b/pkg/ingress/controller/controller.go index 97336a7c49..374332bdc3 100644 --- a/pkg/ingress/controller/controller.go +++ b/pkg/ingress/controller/controller.go @@ -108,6 +108,26 @@ const ( // IngressControllerTag is added to the related resources. IngressControllerTag = "octavia.ingress.kubernetes.io" + // IngressAnnotationTimeoutClientData is the timeout for frontend client inactivity. + // If not set, this value defaults to the Octavia configuration key `timeout_client_data`. + // Refer to https://docs.openstack.org/octavia/latest/configuration/configref.html#haproxy_amphora.timeout_client_data + IngressAnnotationTimeoutClientData = "octavia.ingress.kubernetes.io/timeout-client-data" + + // IngressAnnotationTimeoutMemberData is the timeout for backend member inactivity. + // If not set, this value defaults to the Octavia configuration key `timeout_member_data`. + // Refer to https://docs.openstack.org/octavia/latest/configuration/configref.html#haproxy_amphora.timeout_member_data + IngressAnnotationTimeoutMemberData = "octavia.ingress.kubernetes.io/timeout-member-data" + + // IngressAnnotationTimeoutMemberConnect is the timeout for backend member connection. + // If not set, this value defaults to the Octavia configuration key `timeout_member_connect`. + // Refer to https://docs.openstack.org/octavia/latest/configuration/configref.html#haproxy_amphora.timeout_member_connect + IngressAnnotationTimeoutMemberConnect = "octavia.ingress.kubernetes.io/timeout-member-connect" + + // IngressAnnotationTimeoutTCPInspect is the time to wait for TCP packets for content inspection. + // If not set, this value defaults to the Octavia configuration key `timeout_tcp_inspect`. + // Refer to https://docs.openstack.org/octavia/latest/configuration/configref.html#haproxy_amphora.timeout_tcp_inspect + IngressAnnotationTimeoutTCPInspect = "octavia.ingress.kubernetes.io/timeout-tcp-inspect" + // IngressSecretCertName is certificate key name defined in the secret data. IngressSecretCertName = "tls.crt" // IngressSecretKeyName is private key name defined in the secret data. @@ -728,8 +748,13 @@ func (c *Controller) ensureIngress(ing *nwv1.Ingress) error { // Create listener sourceRanges := getStringFromIngressAnnotation(ing, IngressAnnotationSourceRangesKey, "0.0.0.0/0") + timeoutClientData := maybeGetIntFromIngressAnnotation(ing, IngressAnnotationTimeoutClientData) + timeoutMemberConnect := maybeGetIntFromIngressAnnotation(ing, IngressAnnotationTimeoutMemberConnect) + timeoutMemberData := maybeGetIntFromIngressAnnotation(ing, IngressAnnotationTimeoutMemberData) + timeoutTCPInspect := maybeGetIntFromIngressAnnotation(ing, IngressAnnotationTimeoutTCPInspect) + listenerAllowedCIDRs := strings.Split(sourceRanges, ",") - listener, err := c.osClient.EnsureListener(resName, lb.ID, secretRefs, listenerAllowedCIDRs) + listener, err := c.osClient.EnsureListener(resName, lb.ID, secretRefs, listenerAllowedCIDRs, timeoutClientData, timeoutMemberData, timeoutTCPInspect, timeoutMemberConnect) if err != nil { return err } @@ -1017,6 +1042,23 @@ func getStringFromIngressAnnotation(ingress *nwv1.Ingress, annotationKey string, return defaultValue } +// maybeGetIntFromIngressAnnotation searches a given Ingress for a specific annotationKey and either returns the +// annotation's value +func maybeGetIntFromIngressAnnotation(ingress *nwv1.Ingress, annotationKey string) *int { + klog.V(4).Infof("maybeGetIntFromIngressAnnotation(%s/%s, %v33)", ingress.Namespace, ingress.Name, annotationKey) + if annotationValue, ok := ingress.Annotations[annotationKey]; ok { + klog.V(4).Infof("Found a Service Annotation for key: %v", annotationKey) + returnValue, err := strconv.Atoi(annotationValue) + if err != nil { + klog.V(4).Infof("Invalid integer found on Service Annotation: %v = %v", annotationKey, annotationValue) + return nil + } + return &returnValue + } + klog.V(4).Infof("Could not find a Service Annotation; falling back to default setting for annotation %v", annotationKey) + return nil +} + // privateKeyFromPEM converts a PEM block into a crypto.PrivateKey. func privateKeyFromPEM(pemData []byte) (crypto.PrivateKey, error) { var result *pem.Block diff --git a/pkg/ingress/controller/openstack/octavia.go b/pkg/ingress/controller/openstack/octavia.go index ed3a7b46f9..bdb5485ed6 100644 --- a/pkg/ingress/controller/openstack/octavia.go +++ b/pkg/ingress/controller/openstack/octavia.go @@ -330,7 +330,7 @@ func (os *OpenStack) UpdateLoadBalancerDescription(lbID string, newDescription s } // EnsureListener creates a loadbalancer listener in octavia if it does not exist, wait for the loadbalancer to be ACTIVE. -func (os *OpenStack) EnsureListener(name string, lbID string, secretRefs []string, listenerAllowedCIDRs []string) (*listeners.Listener, error) { +func (os *OpenStack) EnsureListener(name string, lbID string, secretRefs []string, listenerAllowedCIDRs []string, timeoutClientData, timeoutMemberData, timeoutTCPInspect, timeoutMemberConnect *int) (*listeners.Listener, error) { listener, err := openstackutil.GetListenerByName(os.Octavia, name, lbID) if err != nil { if err != cpoerrors.ErrNotFound { @@ -340,10 +340,14 @@ func (os *OpenStack) EnsureListener(name string, lbID string, secretRefs []strin log.WithFields(log.Fields{"lbID": lbID, "listenerName": name}).Info("creating listener") opts := listeners.CreateOpts{ - Name: name, - Protocol: "HTTP", - ProtocolPort: 80, // Ingress Controller only supports http/https for now - LoadbalancerID: lbID, + Name: name, + Protocol: "HTTP", + ProtocolPort: 80, // Ingress Controller only supports http/https for now + LoadbalancerID: lbID, + TimeoutClientData: timeoutClientData, + TimeoutMemberData: timeoutMemberData, + TimeoutMemberConnect: timeoutMemberConnect, + TimeoutTCPInspect: timeoutTCPInspect, } if len(secretRefs) > 0 { opts.DefaultTlsContainerRef = secretRefs[0]