Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,12 @@ class RouteSpecificationFactory(
}
val servicesNames = group.proxySettings.outgoing.getServiceDependencies().map { it.service }.toSet()
val definedTagsRoutes = globalSnapshot
.getTagsForDependency(group.proxySettings.outgoing) { servicesName, tagDependency ->
.getTagsForDependency(group.proxySettings.outgoing)
.map {
RouteSpecification(
clusterName = servicesName,
routeDomains = listOf(servicesName) + getServiceWithCustomDomain(servicesName),
settings = tagDependency.settings
clusterName = it.first,
routeDomains = listOf(it.first) + getServiceWithCustomDomain(it.first),
settings = it.second.settings
)
}.distinctBy { it.clusterName }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@ import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment
import pl.allegro.tech.servicemesh.envoycontrol.groups.Outgoing
import pl.allegro.tech.servicemesh.envoycontrol.groups.TagDependency

typealias ClusterName = String

data class GlobalSnapshot(
val clusters: Map<String, Cluster>,
val allServicesNames: Set<String>,
val endpoints: Map<String, ClusterLoadAssignment>,
val clusterConfigurations: Map<String, ClusterConfiguration>,
val securedClusters: Map<String, Cluster>,
val tags: Map<String, Set<String>>
val clusters: Map<ClusterName, Cluster>,
val allServicesNames: Set<ClusterName>,
val endpoints: Map<ClusterName, ClusterLoadAssignment>,
val clusterConfigurations: Map<ClusterName, ClusterConfiguration>,
val securedClusters: Map<ClusterName, Cluster>,
val tags: Map<ClusterName, Set<String>>
) {
fun <T> getTagsForDependency(
outgoing: Outgoing,
mapper: (String, TagDependency) -> T): List<T> {
fun getTagsForDependency(
outgoing: Outgoing
): List<Pair<ClusterName, TagDependency>> {
val serviceDependencies = outgoing.getServiceDependencies().map { it.service }.toSet()
return outgoing.getTagDependencies().flatMap { tagDependency ->
tags.filterKeys { !serviceDependencies.contains(it) }
.filterValues { it.contains(tagDependency.tag) }
.map { mapper(it.key, tagDependency) }
.map { it.key to tagDependency }
}
}
}
Expand All @@ -31,9 +33,9 @@ fun globalSnapshot(
clusters: Iterable<Cluster> = emptyList(),
endpoints: Iterable<ClusterLoadAssignment> = emptyList(),
properties: OutgoingPermissionsProperties = OutgoingPermissionsProperties(),
clusterConfigurations: Map<String, ClusterConfiguration> = emptyMap(),
clusterConfigurations: Map<ClusterName, ClusterConfiguration> = emptyMap(),
securedClusters: List<Cluster> = emptyList(),
tags: Map<String, Set<String>>
tags: Map<ClusterName, Set<String>>
): GlobalSnapshot {
val clusters = SnapshotResources.create<Cluster>(clusters, "").resources()
val securedClusters = SnapshotResources.create<Cluster>(securedClusters, "").resources()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,10 @@ class EnvoyClustersFactory(
.associateBy({ it.service }, { it.settings })

val serviceFromTagSettings = globalSnapshot
.getTagsForDependency(group.proxySettings.outgoing) { serviceName, tagDependency ->
serviceName to tagDependency.settings
}.reversed().associateBy({ it.first }, { it.second })
.getTagsForDependency(group.proxySettings.outgoing)
.map { it.first to it.second.settings }
.distinctBy { it.first }
.associateBy({ it.first }, { it.second })

val clustersForGroup = when (group) {
is ServicesGroup -> serviceSettings.mapNotNull {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class EnvoySnapshotFactoryTest {
fun `should return all tags when prefix is empty`() {
// given
val tagPrefix = ""
val serviceTags = mapOf("abc" to setOf("uws", "poc"), "xyz" to setOf("uj"), "qwerty" to setOf())
val state: MultiClusterState = MultiClusterState(listOf(
val serviceTags = mapOf(
serviceWithTags("abc", "uws", "poc"),
serviceWithTags("xyz", "uj"),
serviceWithTags("qwerty")
)
val state = MultiClusterState(listOf(
ClusterState(serviceState(serviceTags), Locality.LOCAL, "cluster")
))

Expand All @@ -31,8 +35,12 @@ class EnvoySnapshotFactoryTest {
@Test
fun `should return all tags with prefix`() {
val tagPrefix = "tag:"
val serviceTags = mapOf("abc" to setOf("tag:uws", "poc"), "xyz" to setOf("uj"), "qwerty" to setOf())
val state: MultiClusterState = MultiClusterState(listOf(
val serviceTags = mapOf(
serviceWithTags("abc", "tag:uws", "poc"),
serviceWithTags("xyz", "uj"),
serviceWithTags("qwerty")
)
val state = MultiClusterState(listOf(
ClusterState(serviceState(serviceTags), Locality.LOCAL, "cluster")
))

Expand All @@ -41,18 +49,24 @@ class EnvoySnapshotFactoryTest {

// then
assertThat(tags).isEqualTo(mapOf(
"abc" to setOf("tag:uws"),
"xyz" to emptySet(),
"qwerty" to emptySet()
serviceWithTags("abc", "tag:uws"),
serviceWithTags("xyz"),
serviceWithTags("qwerty")
))
}

@Test
fun `should merge multiple Cluster State`() {
// given
val tagPrefix = ""
val serviceTagsCluster1 = mapOf("abc" to setOf("uws", "poc"), "xyz" to setOf("uj"), "qwerty" to setOf())
val serviceTagsCluster2 = mapOf("abc" to setOf("lkj"), "xyz" to setOf(), "qwerty" to setOf("ban"))
val serviceTagsCluster1 = mapOf(
serviceWithTags("abc", "uws", "poc"),
serviceWithTags("xyz", "uj"),
serviceWithTags("qwerty"))
val serviceTagsCluster2 = mapOf(
serviceWithTags("abc", "lkj"),
serviceWithTags("xyz"),
serviceWithTags("qwerty", "ban"))
val state = MultiClusterState(listOf(
ClusterState(serviceState(serviceTagsCluster1), Locality.LOCAL, "cluster"),
ClusterState(serviceState(serviceTagsCluster2), Locality.LOCAL, "cluster2")
Expand All @@ -63,9 +77,9 @@ class EnvoySnapshotFactoryTest {

// then
assertThat(tags).isEqualTo(mapOf(
"abc" to setOf("uws", "poc", "lkj"),
"xyz" to setOf("uj"),
"qwerty" to setOf("ban")
serviceWithTags("abc", "uws", "poc", "lkj"),
serviceWithTags("xyz", "uj"),
serviceWithTags("qwerty", "ban")
))
}

Expand All @@ -76,3 +90,7 @@ class EnvoySnapshotFactoryTest {
return ServicesState(servicesInstances)
}
}

private fun serviceWithTags(serviceName: String, vararg tags: String): Pair<String, Set<String>> {
return serviceName to tags.toSet()
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ class EnvoyClusterFactoryTest {
val globalSnapshot = buildGlobalSnapshot(
services = services,
properties = properties,
tags = mapOf("service-A" to setOf("tag"), "service-C" to setOf("tag"))
tags = mapOf(
serviceWithTags("service-A", "tag"),
serviceWithTags("service-C", "tag")
)
)

// when
Expand Down Expand Up @@ -111,7 +114,11 @@ class EnvoyClusterFactoryTest {
val globalSnapshot = buildGlobalSnapshot(
services = services,
properties = properties,
tags = mapOf("service-A" to setOf("tag-1"), "service-C" to setOf("tag-1", "tag-2"), "service-B" to setOf("tag-2"))
tags = mapOf(
serviceWithTags("service-A","tag-1"),
serviceWithTags("service-C","tag-1", "tag-2"),
serviceWithTags("service-B","tag-2")
)
)

// when
Expand Down Expand Up @@ -152,7 +159,10 @@ class EnvoyClusterFactoryTest {
val globalSnapshot = buildGlobalSnapshot(
services = services,
properties = properties,
tags = mapOf("service-A" to setOf("tag"), "service-C" to setOf("tag"))
tags = mapOf(
serviceWithTags("service-A", "tag"),
serviceWithTags("service-C", "tag")
)
)

// when
Expand Down Expand Up @@ -239,7 +249,7 @@ class EnvoyClusterFactoryTest {
val globalSnapshot = buildGlobalSnapshot(
services = services,
properties = properties,
tags = mapOf("service-A" to setOf("tag")))
tags = mapOf(serviceWithTags("service-A", "tag")))

// when
val clustersForGroup = factory.getClustersForGroup(group, globalSnapshot)
Expand Down Expand Up @@ -279,3 +289,7 @@ private fun ObjectAssert<Cluster>.hasIdleTimeout(idleTimeout: Long): ObjectAsser
.isEqualTo(idleTimeout)
return this
}

private fun serviceWithTags(serviceName: String, vararg tags: String): Pair<String, Set<String>> {
return serviceName to tags.toSet()
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class EnvoyListenersFactoryTest {
endpoints = emptyMap(),
clusterConfigurations = emptyMap(),
securedClusters = emptyMap(),
tags = mapOf("service-B" to setOf("tag"))
tags = mapOf(serviceWithTags("service-B", "tag"))
)

// when
Expand All @@ -96,3 +96,7 @@ class EnvoyListenersFactoryTest {
.contains("0.0.0.0:80")
}
}

private fun serviceWithTags(serviceName: String, vararg tags: String): Pair<String, Set<String>> {
return serviceName to tags.toSet()
}