fix: de-duplicate backend servers list mapped from topology
All checks were successful
Run Check Script / check (pull_request) Successful in 1m11s

This commit is contained in:
Ian Letourneau 2025-09-03 21:55:23 -04:00
parent 3d8dd4d8e6
commit 3ecda84530
3 changed files with 19 additions and 17 deletions

View File

@ -108,8 +108,7 @@ pub(crate) fn haproxy_xml_config_to_harmony_loadbalancer(
} }
None => { None => {
warn!( warn!(
"HAProxy config could not find a matching backend for frontend {:?}", "HAProxy config could not find a matching backend for frontend {frontend:?}"
frontend
); );
} }
} }

View File

@ -67,6 +67,8 @@ impl OKDBootstrapLoadBalancerScore {
address: topology.bootstrap_host.ip.to_string(), address: topology.bootstrap_host.ip.to_string(),
port, port,
}); });
backend.dedup();
backend backend
} }
} }

View File

@ -47,9 +47,22 @@ impl<'a> LoadBalancerConfig<'a> {
healthcheck: Option<HAProxyHealthCheck>, healthcheck: Option<HAProxyHealthCheck>,
) { ) {
self.remove_service_by_bind_address(&frontend.bind); self.remove_service_by_bind_address(&frontend.bind);
self.remove_servers(&servers);
self.add_new_service(frontend, backend, servers, healthcheck); self.add_new_service(frontend, backend, servers, healthcheck);
} }
// Remove the corresponding real servers based on their name if they already exist.
fn remove_servers(&mut self, servers: &[HAProxyServer]) {
let server_names: HashSet<_> = servers.iter().map(|s| s.name.clone()).collect();
self.with_haproxy(|haproxy| {
haproxy
.servers
.servers
.retain(|s| !server_names.contains(&s.name));
});
}
/// Removes a service and its dependent components based on the frontend's bind address. /// Removes a service and its dependent components based on the frontend's bind address.
/// This performs a cascading delete of the frontend, backend, servers, and health check. /// This performs a cascading delete of the frontend, backend, servers, and health check.
fn remove_service_by_bind_address(&mut self, bind_address: &str) { fn remove_service_by_bind_address(&mut self, bind_address: &str) {
@ -63,7 +76,7 @@ impl<'a> LoadBalancerConfig<'a> {
}; };
remove_healthcheck(haproxy, &old_backend); remove_healthcheck(haproxy, &old_backend);
remove_servers(haproxy, &old_backend); remove_linked_servers(haproxy, &old_backend);
}); });
} }
@ -81,19 +94,7 @@ impl<'a> LoadBalancerConfig<'a> {
haproxy.healthchecks.healthchecks.push(check); haproxy.healthchecks.healthchecks.push(check);
} }
let mut existing_server_names: HashSet<_> = haproxy haproxy.servers.servers.extend(servers);
.servers
.servers
.iter()
.map(|s| s.name.clone())
.collect();
for server in servers {
if existing_server_names.insert(server.name.clone()) {
haproxy.servers.servers.push(server);
}
}
haproxy.backends.backends.push(backend); haproxy.backends.backends.push(backend);
haproxy.frontends.frontend.push(frontend); haproxy.frontends.frontend.push(frontend);
}); });
@ -162,7 +163,7 @@ fn remove_healthcheck(haproxy: &mut HAProxy, backend: &HAProxyBackend) {
} }
/// Remove the backend's servers. This assumes servers are not shared between services. /// Remove the backend's servers. This assumes servers are not shared between services.
fn remove_servers(haproxy: &mut HAProxy, backend: &HAProxyBackend) { fn remove_linked_servers(haproxy: &mut HAProxy, backend: &HAProxyBackend) {
if let Some(server_uuids_str) = &backend.linked_servers.content { if let Some(server_uuids_str) = &backend.linked_servers.content {
let server_uuids_to_remove: HashSet<_> = server_uuids_str.split(',').collect(); let server_uuids_to_remove: HashSet<_> = server_uuids_str.split(',').collect();
haproxy haproxy