Skip to content

Commit

Permalink
OCPBUGS-43745: Add support for idle connection termination policy
Browse files Browse the repository at this point in the history
Introduce logic in desiredRouterDeployment to set the environment
variable `ROUTER_IDLE_CLOSE_ON_RESPONSE` when the
`IdleConnectionTerminationPolicy` field in the IngressController spec is
set to `Deferred`. This change enables configuring HAProxy with the
`idle-close-on-response` option for better control over idle connection
termination behaviour.
  • Loading branch information
frobware committed Jan 8, 2025
1 parent f9817da commit c8b9671
Show file tree
Hide file tree
Showing 4 changed files with 633 additions and 5 deletions.
7 changes: 7 additions & 0 deletions pkg/operator/controller/ingress/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,13 @@ func desiredRouterDeployment(ci *operatorv1.IngressController, config *Config, i
)
}

if ci.Spec.IdleConnectionTerminationPolicy == operatorv1.IngressControllerConnectionTerminationPolicyDeferred {
env = append(env, corev1.EnvVar{
Name: "ROUTER_IDLE_CLOSE_ON_RESPONSE",
Value: "true",
})
}

// TODO: The only connections from the router that may need the cluster-wide proxy are those for downloading CRLs,
// which, as of writing this, will always be http. If https becomes necessary, the router will need to mount the
// trusted CA bundle that cluster-network-operator generates. The process for adding that is described here:
Expand Down
56 changes: 51 additions & 5 deletions pkg/operator/controller/ingress/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ func getRouterDeploymentComponents(t *testing.T) (*operatorv1.IngressController,
},
},
HTTPHeaders: &operatorv1.IngressControllerHTTPHeaders{

Actions: operatorv1.IngressControllerHTTPHeaderActions{
Response: []operatorv1.IngressControllerHTTPHeader{
{
Expand Down Expand Up @@ -306,14 +305,12 @@ func getRouterDeploymentComponents(t *testing.T) (*operatorv1.IngressController,
},
},
{

Name: headerNameXFrame,
Action: operatorv1.IngressControllerHTTPHeaderActionUnion{
Type: operatorv1.Delete,
},
},
{

Name: headerNameXSS,
Action: operatorv1.IngressControllerHTTPHeaderActionUnion{
Type: operatorv1.Delete,
Expand All @@ -332,7 +329,6 @@ func getRouterDeploymentComponents(t *testing.T) (*operatorv1.IngressController,
},
},
{

Name: "Accept-Encoding",
Action: operatorv1.IngressControllerHTTPHeaderActionUnion{
Type: operatorv1.Delete,
Expand Down Expand Up @@ -2538,7 +2534,6 @@ func TestDesiredRouterDeploymentDefaultPlacement(t *testing.T) {
}
})
}

}

func TestDesiredRouterDeploymentRouterExternalCertificate(t *testing.T) {
Expand Down Expand Up @@ -2574,3 +2569,54 @@ func TestDesiredRouterDeploymentRouterExternalCertificate(t *testing.T) {

checkDeploymentHasEnvSorted(t, deployment)
}

// Test_IdleConnectionTerminationPolicy validates that the ingress
// controller correctly sets the ROUTER_IDLE_CLOSE_ON_RESPONSE
// environment variable based on the setting of the
// IngressController's IdleConnectionTerminationPolicy.
func Test_IdleConnectionTerminationPolicy(t *testing.T) {
ic, ingressConfig, infraConfig, apiConfig, networkConfig, proxyNeeded, clusterProxyConfig := getRouterDeploymentComponents(t)

for _, tc := range []struct {
name string
policy operatorv1.IngressControllerConnectionTerminationPolicy
expectEnvVarPresent bool
expectedEnvVarValue string
}{{
name: "IdleConnectionTerminationPolicy is Deferred",
policy: operatorv1.IngressControllerConnectionTerminationPolicyDeferred,
expectEnvVarPresent: true,
expectedEnvVarValue: "true",
}, {
name: "IdleConnectionTerminationPolicy is not set",
policy: "",
expectEnvVarPresent: false,
expectedEnvVarValue: "",
}, {
name: "IdleConnectionTerminationPolicy is Immediate (default)",
policy: operatorv1.IngressControllerConnectionTerminationPolicyImmediate,
expectEnvVarPresent: false,
expectedEnvVarValue: "",
}} {
t.Run(tc.name, func(t *testing.T) {
ic.Spec.IdleConnectionTerminationPolicy = tc.policy

deployment, err := desiredRouterDeployment(ic, &Config{IngressControllerImage: ingressControllerImage}, ingressConfig, infraConfig, apiConfig, networkConfig, proxyNeeded, false, nil, clusterProxyConfig)
if err != nil {
t.Fatalf("failed to generate desired router Deployment: %v", err)
}

expectedEnv := []envData{{
name: "ROUTER_IDLE_CLOSE_ON_RESPONSE",
expectPresent: tc.expectEnvVarPresent,
expectedValue: tc.expectedEnvVarValue,
}}

if err := checkDeploymentEnvironment(t, deployment, expectedEnv); err != nil {
t.Errorf("environment variable check failed: %v", err)
}

checkDeploymentHasEnvSorted(t, deployment)
})
}
}
1 change: 1 addition & 0 deletions test/e2e/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func TestAll(t *testing.T) {
t.Run("TestUnmanagedAWSLBSubnets", TestUnmanagedAWSLBSubnets)
t.Run("TestAWSEIPAllocationsForNLB", TestAWSEIPAllocationsForNLB)
t.Run("TestUnmanagedAWSEIPAllocations", TestUnmanagedAWSEIPAllocations)
t.Run("Test_IdleConnectionTerminationPolicy", Test_IdleConnectionTerminationPolicy)
})

t.Run("serial", func(t *testing.T) {
Expand Down
Loading

0 comments on commit c8b9671

Please sign in to comment.