diff --git a/CHANGELOG.md b/CHANGELOG.md index 69301cd37..f082bf463 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Lists all changes with user impact. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). +## [0.22.4] +- Added possibility for configuring priorities per service + ## [0.22.3] ### Changed - Changed names of some metrics diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt index 6c64b7405..228e6c188 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt @@ -157,6 +157,7 @@ class LoadBalancingProperties { var policy = Cluster.LbPolicy.LEAST_REQUEST var useKeysSubsetFallbackPolicy = true var priorities = LoadBalancingPriorityProperties() + var servicePriorities: Map = mapOf() } class CanaryProperties { diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactory.kt index b6ab798e3..483911b19 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactory.kt @@ -188,7 +188,7 @@ class EnvoyEndpointsFactory( ?.map { createLbEndpoint(it, serviceInstances.serviceName, locality) } ?: emptyList()) - .setPriority(toEnvoyPriority(zone, locality)) + .setPriority(toEnvoyPriority(zone, locality, serviceInstances)) .build() } @@ -286,8 +286,14 @@ class EnvoyEndpointsFactory( false -> this } - private fun toEnvoyPriority(zone: String, locality: Locality): Int { - val zonePriorities = properties.loadBalancing.priorities.zonePriorities + private fun toEnvoyPriority(zone: String, locality: Locality, serviceInstances: ServiceInstances?): Int { + var zonePriorities = properties.loadBalancing.priorities.zonePriorities + serviceInstances?.let { + if (properties.loadBalancing.servicePriorities.containsKey(serviceInstances.serviceName)) { + zonePriorities = + properties.loadBalancing.servicePriorities[serviceInstances.serviceName]!!.zonePriorities + } + } return when (zonePriorities.isNotEmpty()) { true -> zonePriorities[currentZone]?.get(zone) ?: toEnvoyPriority(locality) false -> toEnvoyPriority(locality) diff --git a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactoryTest.kt b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactoryTest.kt index de151d627..b3c787a0e 100644 --- a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactoryTest.kt +++ b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/endpoints/EnvoyEndpointsFactoryTest.kt @@ -406,6 +406,40 @@ internal class EnvoyEndpointsFactoryTest { .anySatisfy { it.hasZoneWithPriority("DC3", 2) } } + @Test + fun `should create load assignment with service zone priorities`() { + val envoyEndpointsFactory = EnvoyEndpointsFactory( + snapshotPropertiesWithPriorities + ( + mapOf("DC2" to mapOf("DC1" to 1, "DC2" to 1, "DC3" to 1)), + mapOf("DC2" to mapOf("DC1" to 2, "DC2" to 2, "DC3" to 2)), + serviceName + ), + currentZone = "DC2" + ) + val loadAssignments = envoyEndpointsFactory.createLoadAssignment(setOf(serviceName), multiClusterStateDC2Local) + loadAssignments.assertHasLoadAssignment( + mapOf("DC1" to 2, "DC2" to 2, "DC3" to 2) + ) + } + + @Test + fun `should create load assignment with global zone priorities when no service config found`() { + val envoyEndpointsFactory = EnvoyEndpointsFactory( + snapshotPropertiesWithPriorities + ( + mapOf("DC2" to mapOf("DC1" to 1, "DC2" to 1, "DC3" to 1)), + mapOf("DC2" to mapOf("DC1" to 2, "DC2" to 2, "DC3" to 2)), + "another-service" + ), + currentZone = "DC2" + ) + val loadAssignments = envoyEndpointsFactory.createLoadAssignment(setOf(serviceName), multiClusterStateDC2Local) + loadAssignments.assertHasLoadAssignment( + mapOf("DC1" to 1, "DC2" to 1, "DC3" to 1) + ) + } + private fun List.assertHasLoadAssignment(map: Map) { assertThat(this) .isNotEmpty() @@ -453,13 +487,22 @@ internal class EnvoyEndpointsFactoryTest { assertThat(this.locality.zone).isEqualTo(zone) } - private fun snapshotPropertiesWithPriorities(priorities: Map>) = + private fun snapshotPropertiesWithPriorities( + priorities: Map>, + servicePriorities: Map> = mapOf(), + serviceName: String? = null + ) = SnapshotProperties().apply { loadBalancing = LoadBalancingProperties() .apply { this.priorities = LoadBalancingPriorityProperties().apply { zonePriorities = priorities } + serviceName?.let { + this.servicePriorities = mapOf(serviceName to LoadBalancingPriorityProperties().apply { + zonePriorities = servicePriorities + }) + } } }