Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create separrated status route with high priority #446

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Lists all changes with user impact.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [0.22.9]
### Changed
- separated ingress route for /status* paths

## [0.22.8]
### Changed
- added tests for missing and malformed JWT token scenarios
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.google.protobuf.util.Durations
import io.envoyproxy.envoy.config.core.v3.HeaderValue
import io.envoyproxy.envoy.config.core.v3.HeaderValueOption
import io.envoyproxy.envoy.config.core.v3.Metadata
import io.envoyproxy.envoy.config.core.v3.RoutingPriority
import io.envoyproxy.envoy.config.route.v3.HeaderMatcher
import io.envoyproxy.envoy.config.route.v3.RateLimit
import io.envoyproxy.envoy.config.route.v3.RetryPolicy
Expand Down Expand Up @@ -49,6 +50,7 @@ class EnvoyIngressRoutesFactory(
idleTimeout: Duration?,
clusterName: String = "local_service",
serviceName: String = "",
priority: RoutingPriority = RoutingPriority.DEFAULT,
rateLimitEndpoints: List<IncomingRateLimitEndpoint> = emptyList()
): RouteAction.Builder {
val timeoutResponse = responseTimeout ?: Durations.fromMillis(
Expand All @@ -59,6 +61,7 @@ class EnvoyIngressRoutesFactory(
.setCluster(clusterName)
.setTimeout(timeoutResponse)
.setIdleTimeout(timeoutIdle)
.setPriority(priority)
.addIngressRateLimits(serviceName, rateLimitEndpoints)
}

Expand All @@ -73,19 +76,25 @@ class EnvoyIngressRoutesFactory(
.addHeaders(createHeaderMatcher(endpoint.pathMatchingType, endpoint.path))

if (endpoint.methods.isNotEmpty()) {
match.addHeaders(HeaderMatcher.newBuilder()
.setRe2Match(endpoint.methods.joinToString(
separator = "|",
transform = { "^$it\$" }))
.setName(":method")
match.addHeaders(
HeaderMatcher.newBuilder()
.setRe2Match(
endpoint.methods.joinToString(
separator = "|",
transform = { "^$it\$" })
)
.setName(":method")
)
}
if (endpoint.clients.isNotEmpty() && endpoint.clients != allClients) {
match.addHeaders(HeaderMatcher.newBuilder()
.setRe2Match(endpoint.clients.joinToString(
separator = "|",
transform = { "^${it.compositeName()}\$" }))
.setName(properties.incomingPermissions.serviceNameHeader)
match.addHeaders(
HeaderMatcher.newBuilder()
.setRe2Match(
endpoint.clients.joinToString(
separator = "|",
transform = { "^${it.compositeName()}\$" })
)
.setName(properties.incomingPermissions.serviceNameHeader)
)
}
addRateLimits(
Expand Down Expand Up @@ -171,11 +180,29 @@ class EnvoyIngressRoutesFactory(
.map { HttpMethod.valueOf(it.key) to retryPolicy(it.value) }
.toMap()

private fun ingressRoutes(localRouteAction: RouteAction.Builder, group: Group): List<Route> {
private fun ingressRoutes(proxySettings: ProxySettings, group: Group): List<Route> {
return ingressRoute(proxySettings, group, RoutingPriority.HIGH, "/status/") +
ingressRoute(proxySettings, group, RoutingPriority.DEFAULT, "/")
}

private fun ingressRoute(
proxySettings: ProxySettings,
group: Group,
priority: RoutingPriority,
prefix: String
): List<Route> {
val localRouteAction = clusterRouteAction(
proxySettings.incoming.timeoutPolicy.responseTimeout,
proxySettings.incoming.timeoutPolicy.idleTimeout,
priority = priority,
serviceName = group.serviceName,
rateLimitEndpoints = proxySettings.incoming.rateLimitEndpoints
)

val nonRetryRoute = Route.newBuilder()
.setMatch(
RouteMatch.newBuilder()
.setPrefix("/")
.setPrefix(prefix)
)
.setRoute(localRouteAction)
val retryRoutes = perMethodRetryPolicies
Expand All @@ -184,7 +211,7 @@ class EnvoyIngressRoutesFactory(
.setMatch(
RouteMatch.newBuilder()
.addHeaders(httpMethodMatcher(method))
.setPrefix("/")
.setPrefix(prefix)
)
.setRoute(clusterRouteActionWithRetryPolicy(retryPolicy, localRouteAction))
}
Expand Down Expand Up @@ -228,6 +255,7 @@ class EnvoyIngressRoutesFactory(
true -> {
statusClusters + endpoints
}

false ->
emptyList()
}
Expand Down Expand Up @@ -275,16 +303,10 @@ class EnvoyIngressRoutesFactory(
}

private fun generateSecuredIngressRoutes(proxySettings: ProxySettings, group: Group): List<Route> {
val localRouteAction = clusterRouteAction(
proxySettings.incoming.timeoutPolicy.responseTimeout,
proxySettings.incoming.timeoutPolicy.idleTimeout,
serviceName = group.serviceName,
rateLimitEndpoints = proxySettings.incoming.rateLimitEndpoints
)

val customHealthCheckRoute = customHealthCheckRoute(proxySettings)

return customHealthCheckRoute + ingressRoutes(localRouteAction, group)
return customHealthCheckRoute + ingressRoutes(proxySettings, group)
}

private fun statusRouteVirtualClusterEnabled() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,18 @@ fun Route.hasRetryPolicy() {
assertThat(this.route.hasRetryPolicy()).isTrue()
}

fun Route.ingressRoute() {
fun Route.ingressServiceRoute() {
this.matchingOnPrefix("/")
.publicAccess()
.toCluster("local_service")
}

fun Route.ingresStatusRoute() {
this.matchingOnPrefix("/status/")
.publicAccess()
.toCluster("local_service")
}

fun Route.hasRateLimitsInOrder(vararg conditions: RateLimit.() -> Unit): Route = apply {
assertThat(this.route.rateLimitsList).hasSameSizeAs(conditions)
assertThat(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import pl.allegro.tech.servicemesh.envoycontrol.groups.hasRequestHeadersToRemove
import pl.allegro.tech.servicemesh.envoycontrol.groups.hasResponseHeaderToAdd
import pl.allegro.tech.servicemesh.envoycontrol.groups.hasSingleVirtualHostThat
import pl.allegro.tech.servicemesh.envoycontrol.groups.hasStatusVirtualClusters
import pl.allegro.tech.servicemesh.envoycontrol.groups.ingressRoute
import pl.allegro.tech.servicemesh.envoycontrol.groups.ingresStatusRoute
import pl.allegro.tech.servicemesh.envoycontrol.groups.ingressServiceRoute
import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnAnyMethod
import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnMethod
import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnPrefix
Expand Down Expand Up @@ -88,6 +89,7 @@ internal class EnvoyIngressRoutesFactoryTest {
private val currentZone = "dc1"

@Test
@Suppress("LongMethod")
fun `should create route config with health check and response timeout defined`() {
// given
val routesFactory = EnvoyIngressRoutesFactory(SnapshotProperties().apply {
Expand Down Expand Up @@ -164,7 +166,22 @@ internal class EnvoyIngressRoutesFactoryTest {
},
*adminRoutes,
{
ingressRoute()
ingresStatusRoute()
matchingOnMethod("GET")
matchingRetryPolicy(retryPolicyProps.perHttpMethod["GET"]!!)
},
{
ingresStatusRoute()
matchingOnMethod("HEAD")
matchingRetryPolicy(retryPolicyProps.perHttpMethod["HEAD"]!!)
},
{
ingresStatusRoute()
matchingOnAnyMethod()
hasNoRetryPolicy()
},
{
ingressServiceRoute()
matchingOnMethod("GET")
matchingRetryPolicy(retryPolicyProps.perHttpMethod["GET"]!!)
hasRateLimitsInOrder(
Expand All @@ -190,12 +207,12 @@ internal class EnvoyIngressRoutesFactoryTest {
)
},
{
ingressRoute()
ingressServiceRoute()
matchingOnMethod("HEAD")
matchingRetryPolicy(retryPolicyProps.perHttpMethod["HEAD"]!!)
},
{
ingressRoute()
ingressServiceRoute()
matchingOnAnyMethod()
hasNoRetryPolicy()
}
Expand Down
Loading