From 980e4392928230f2eac8016c84f1e7de53d98a29 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Thu, 17 Oct 2024 18:18:57 +0200 Subject: [PATCH 01/10] custom routes --- .../snapshot/SnapshotProperties.kt | 7 ++ .../resource/routes/AdminRoutesFactory.kt | 20 +++--- .../resource/routes/CustomRoutesFactory.kt | 36 ++++++++++ .../routes/EnvoyIngressRoutesFactory.kt | 6 +- .../routes/EnvoyIngressRoutesFactoryTest.kt | 20 ++++++ .../envoycontrol/CustomRouteTest.kt | 66 +++++++++++++++++++ .../config/envoy/EnvoyContainer.kt | 8 ++- .../config/envoy/EnvoyExtension.kt | 6 +- .../src/main/resources/envoy/bad_config.yaml | 11 ++++ .../src/main/resources/envoy/config_ads.yaml | 11 ++++ .../envoy/config_ads_all_dependencies.yaml | 11 ++++ .../envoy/config_ads_custom_health_check.yaml | 11 ++++ ...fig_ads_disabled_endpoint_permissions.yaml | 11 ++++ .../config_ads_dynamic_forward_proxy.yaml | 11 ++++ .../envoy/config_ads_no_dependencies.yaml | 11 ++++ .../envoy/config_ads_static_listeners.yaml | 12 +++- .../src/main/resources/envoy/config_auth.yaml | 11 ++++ .../main/resources/envoy/config_oauth.yaml | 11 ++++ .../src/main/resources/envoy/config_xds.yaml | 11 ++++ .../envoy/config_xds_compression.yaml | 11 ++++ .../src/main/resources/envoy/launch_envoy.sh | 4 +- 21 files changed, 286 insertions(+), 20 deletions(-) create mode 100644 envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt create mode 100644 envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt 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..d36feb317 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 @@ -188,6 +188,7 @@ class RoutesProperties { var admin = AdminRouteProperties() var status = StatusRouteProperties() var authorization = AuthorizationProperties() + var customs = emptyList() } class ClusterOutlierDetectionProperties { @@ -260,6 +261,12 @@ class AuthorizationProperties { var unauthorizedResponseMessage = "You have to be authorized" } +class CustomRuteProperties { + var enabled = false + var cluster = "custom" + var path = StringMatcher() +} + class ServiceTagsProperties { var enabled = false var metadataKey = "tag" diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/AdminRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/AdminRoutesFactory.kt index a0f11e2dd..6636aa334 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/AdminRoutesFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/AdminRoutesFactory.kt @@ -42,6 +42,15 @@ class AdminRoutesFactory( HttpMethod.POST ) + private val adminRoutes = guardAccessWithDisableHeader() + + generateSecuredAdminRoutes() + + listOfNotNull( + adminPostRoute.authorized.takeIf { properties.admin.publicAccessEnabled }, + adminPostRoute.unauthorized.takeIf { properties.admin.publicAccessEnabled }, + adminRoute.takeIf { properties.admin.publicAccessEnabled }, + adminRedirectRoute.takeIf { properties.admin.publicAccessEnabled } + ) + private fun generateSecuredAdminRoutes(): List { return properties.admin.securedPaths .flatMap { @@ -55,16 +64,7 @@ class AdminRoutesFactory( } } - fun generateAdminRoutes(): List { - return guardAccessWithDisableHeader() + - generateSecuredAdminRoutes() + - listOfNotNull( - adminPostRoute.authorized.takeIf { properties.admin.publicAccessEnabled }, - adminPostRoute.unauthorized.takeIf { properties.admin.publicAccessEnabled }, - adminRoute.takeIf { properties.admin.publicAccessEnabled }, - adminRedirectRoute.takeIf { properties.admin.publicAccessEnabled } - ) - } + fun generateAdminRoutes() = adminRoutes private fun createAuthorizedRoute( pathPrefix: String, diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt new file mode 100644 index 000000000..a72fc5346 --- /dev/null +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt @@ -0,0 +1,36 @@ +package pl.allegro.tech.servicemesh.envoycontrol.snapshot.resource.routes + +import io.envoyproxy.envoy.config.route.v3.Route +import io.envoyproxy.envoy.config.route.v3.RouteAction +import io.envoyproxy.envoy.config.route.v3.RouteMatch +import io.envoyproxy.envoy.type.matcher.v3.RegexMatcher +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.RoutesProperties +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcherType + +class CustomRoutesFactory(properties: RoutesProperties) { + + val routes: List = properties.customs.filter { it.enabled }.map { + val matcher = when(it.path.type) { + StringMatcherType.REGEX -> RouteMatch.newBuilder() + .setSafeRegex( + RegexMatcher.newBuilder() + .setRegex(it.path.value) + .setGoogleRe2(RegexMatcher.GoogleRE2.getDefaultInstance()) + ) + StringMatcherType.EXACT -> RouteMatch.newBuilder().setPath(it.path.value) + StringMatcherType.PREFIX -> RouteMatch.newBuilder().setPrefix(it.path.value) + } + RouteMatch.newBuilder() + Route.newBuilder() + .setName(it.cluster) + .setRoute(RouteAction.newBuilder() + .setCluster(it.cluster) + ) + .setMatch(matcher) + .build() + } + + fun generateCustomRoutes() = routes + + +} diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt index f92fe7fce..cdc80da5d 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt @@ -37,7 +37,8 @@ class EnvoyIngressRoutesFactory( envoyHttpFilters: EnvoyHttpFilters = EnvoyHttpFilters.emptyFilters, private val currentZone: String ) { - + private val adminRoutesFactory = AdminRoutesFactory(properties.routes) + private val customRoutesFactory = CustomRoutesFactory(properties.routes) private val allClients = setOf( ClientWithSelector.create(properties.incomingPermissions.tlsAuthentication.wildcardClientIdentifier) ) @@ -231,13 +232,12 @@ class EnvoyIngressRoutesFactory( emptyList() } - val adminRoutesFactory = AdminRoutesFactory(properties.routes) - val virtualHost = VirtualHost.newBuilder() .setName("secured_local_service") .addDomains("*") .addAllVirtualClusters(virtualClusters) .addAllRoutes(adminRoutesFactory.generateAdminRoutes()) + .addAllRoutes(customRoutesFactory.generateCustomRoutes()) .addAllRoutes(generateSecuredIngressRoutes(proxySettings, group)) .also { if (properties.localService.retryPolicy.default.enabled) { diff --git a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt index c9875872a..4c84db416 100644 --- a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt +++ b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt @@ -32,14 +32,20 @@ import pl.allegro.tech.servicemesh.envoycontrol.groups.hasStatusVirtualClusters import pl.allegro.tech.servicemesh.envoycontrol.groups.ingressRoute import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnAnyMethod import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnMethod +import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingOnPrefix import pl.allegro.tech.servicemesh.envoycontrol.groups.matchingRetryPolicy import pl.allegro.tech.servicemesh.envoycontrol.groups.pathMatcher import pl.allegro.tech.servicemesh.envoycontrol.groups.prefixPathMatcher +import pl.allegro.tech.servicemesh.envoycontrol.groups.publicAccess +import pl.allegro.tech.servicemesh.envoycontrol.groups.toCluster +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.CustomRuteProperties import pl.allegro.tech.servicemesh.envoycontrol.snapshot.EndpointMatch import pl.allegro.tech.servicemesh.envoycontrol.snapshot.LocalRetryPoliciesProperties import pl.allegro.tech.servicemesh.envoycontrol.snapshot.LocalRetryPolicyProperties import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SecuredRoute import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcher +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcherType import java.time.Duration internal class EnvoyIngressRoutesFactoryTest { @@ -95,6 +101,14 @@ internal class EnvoyIngressRoutesFactoryTest { pathPrefix = "/config_dump" method = "GET" }) + routes.customs = listOf(CustomRuteProperties().apply { + enabled = true + cluster = "wrapper" + path = StringMatcher().apply { + type = StringMatcherType.PREFIX + value = "/status/wrapper/" + } + }) }, currentZone = currentZone) val responseTimeout = Durations.fromSeconds(777) val idleTimeout = Durations.fromSeconds(61) @@ -144,6 +158,12 @@ internal class EnvoyIngressRoutesFactoryTest { hasOneDomain("*") hasOnlyRoutesInOrder( *adminRoutes, + { + matchingOnPrefix("/status/wrapper/") + .toCluster("wrapper") + .publicAccess() + + }, { ingressRoute() matchingOnMethod("GET") diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt new file mode 100644 index 000000000..390628994 --- /dev/null +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt @@ -0,0 +1,66 @@ +package pl.allegro.tech.servicemesh.envoycontrol + +import okhttp3.Headers.Companion.toHeaders +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody +import okhttp3.Response +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension +import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension +import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtension +import pl.allegro.tech.servicemesh.envoycontrol.config.service.EchoServiceExtension +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.CustomRuteProperties +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SecuredRoute +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcher +import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcherType +import java.util.stream.Stream + +internal class CustomRouteTest { + companion object { + + private val properties = mapOf( + "envoy-control.envoy.snapshot.routes.customs" to listOf(CustomRuteProperties().apply { + enabled = true + cluster = "wrapper" + path = StringMatcher().apply { + type = StringMatcherType.PREFIX + value = "/status/wrapper/" + } + }), + ) + + @JvmField + @RegisterExtension + val consul = ConsulExtension() + + @JvmField + @RegisterExtension + val envoyControl = EnvoyControlExtension(consul, properties) + + @JvmField + @RegisterExtension + val service = EchoServiceExtension() + + @JvmField + @RegisterExtension + val wrapper = EchoServiceExtension() + + @JvmField + @RegisterExtension + val envoy = EnvoyExtension(envoyControl, service, wrapperService = wrapper) + } + @Test + fun `should redirect to wrapper`() { + // when + val response = envoy.ingressOperations.callLocalService( + endpoint = "/status/wrapper/prometheus" + ) + // then + assertThat(response.isSuccessful).isTrue() + } +} diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt index 92466b0c5..a6e0e1c8c 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt @@ -16,7 +16,8 @@ class EnvoyContainer( private val envoyControl1XdsPort: Int, private val envoyControl2XdsPort: Int = envoyControl1XdsPort, private val logLevel: String = "info", - image: String = DEFAULT_IMAGE + image: String = DEFAULT_IMAGE, + private val wrapperServiceIp: () -> String = {"127.0.0.1"}, ) : SSLGenericContainer( dockerfileBuilder = DockerfileBuilder() .from(image) @@ -72,14 +73,15 @@ class EnvoyContainer( withCommand( "/bin/sh", "/usr/local/bin/launch_envoy.sh", - Integer.toString(envoyControl1XdsPort), - Integer.toString(envoyControl2XdsPort), + envoyControl1XdsPort.toString(), + envoyControl2XdsPort.toString(), CONFIG_DEST, localServiceIp(), config.trustedCa, config.certificateChain, config.privateKey, config.serviceName, + wrapperServiceIp(), "--config-yaml", config.configOverride, "-l", logLevel ) diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt index f80f5e77a..75e8dd62f 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt @@ -21,7 +21,8 @@ import java.util.concurrent.TimeUnit class EnvoyExtension( private val envoyControl: EnvoyControlExtensionBase, private val localService: ServiceExtension<*>? = null, - config: EnvoyConfig = RandomConfigFile + config: EnvoyConfig = RandomConfigFile, + private val wrapperService: ServiceExtension<*>? = null ) : BeforeAllCallback, AfterAllCallback, AfterEachCallback { companion object { @@ -31,7 +32,8 @@ class EnvoyExtension( val container: EnvoyContainer = EnvoyContainer( config, { localService?.container()?.ipAddress() ?: "127.0.0.1" }, - envoyControl.app.grpcPort + envoyControl.app.grpcPort, + wrapperServiceIp = { wrapperService?.container()?.ipAddress() ?: "127.0.0.1" }, ).withNetwork(Network.SHARED) val ingressOperations: IngressOperations = IngressOperations(container) diff --git a/envoy-control-tests/src/main/resources/envoy/bad_config.yaml b/envoy-control-tests/src/main/resources/envoy/bad_config.yaml index 0c4356ed3..76739c2a7 100644 --- a/envoy-control-tests/src/main/resources/envoy/bad_config.yaml +++ b/envoy-control-tests/src/main/resources/envoy/bad_config.yaml @@ -75,6 +75,17 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 listeners: - name: default_listener address: diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads.yaml index 5eb15b086..39ab64c95 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads.yaml @@ -117,3 +117,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_all_dependencies.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_all_dependencies.yaml index b7e90b3b5..b7a93275c 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_all_dependencies.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_all_dependencies.yaml @@ -90,3 +90,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_custom_health_check.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_custom_health_check.yaml index 1372ec468..2c0902b49 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_custom_health_check.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_custom_health_check.yaml @@ -85,6 +85,17 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 listeners: - name: default_listener address: diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_disabled_endpoint_permissions.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_disabled_endpoint_permissions.yaml index ddee4bdbc..67f109b24 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_disabled_endpoint_permissions.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_disabled_endpoint_permissions.yaml @@ -89,3 +89,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_dynamic_forward_proxy.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_dynamic_forward_proxy.yaml index 21062f4cf..2b4d9d852 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_dynamic_forward_proxy.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_dynamic_forward_proxy.yaml @@ -90,3 +90,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_no_dependencies.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_no_dependencies.yaml index 3f34c2520..791cc468a 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_no_dependencies.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_no_dependencies.yaml @@ -83,3 +83,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_ads_static_listeners.yaml b/envoy-control-tests/src/main/resources/envoy/config_ads_static_listeners.yaml index 758984277..a40f13d64 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_ads_static_listeners.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_ads_static_listeners.yaml @@ -69,7 +69,17 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 - + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 listeners: - name: default_listener address: diff --git a/envoy-control-tests/src/main/resources/envoy/config_auth.yaml b/envoy-control-tests/src/main/resources/envoy/config_auth.yaml index b6c8c5ff8..d35f18253 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_auth.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_auth.yaml @@ -101,3 +101,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_oauth.yaml b/envoy-control-tests/src/main/resources/envoy/config_oauth.yaml index 70fea9b1f..92194cb8a 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_oauth.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_oauth.yaml @@ -101,3 +101,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_xds.yaml b/envoy-control-tests/src/main/resources/envoy/config_xds.yaml index 511b28e73..3d90e234a 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_xds.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_xds.yaml @@ -117,3 +117,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/config_xds_compression.yaml b/envoy-control-tests/src/main/resources/envoy/config_xds_compression.yaml index a3c842718..c0d194818 100644 --- a/envoy-control-tests/src/main/resources/envoy/config_xds_compression.yaml +++ b/envoy-control-tests/src/main/resources/envoy/config_xds_compression.yaml @@ -124,3 +124,14 @@ static_resources: port_value: 10000 connect_timeout: seconds: 1 + - name: wrapper + type: STATIC + load_assignment: + cluster_name: wrapper + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: WRAPPER_SERVICE_IP + port_value: 5678 diff --git a/envoy-control-tests/src/main/resources/envoy/launch_envoy.sh b/envoy-control-tests/src/main/resources/envoy/launch_envoy.sh index a2d442fa2..726a69143 100755 --- a/envoy-control-tests/src/main/resources/envoy/launch_envoy.sh +++ b/envoy-control-tests/src/main/resources/envoy/launch_envoy.sh @@ -20,6 +20,7 @@ TRUSTED_CA="$5" CERTIFICATE_CHAIN="$6" PRIVATE_KEY="$7" SERVICE_NAME="$8" +WRAPPER_SERVICE_IP="$9" echo "debug: " "$@" @@ -32,10 +33,11 @@ echo "${CONFIG}" | sed \ -e "s;CERTIFICATE_CHAIN;${CERTIFICATE_CHAIN};g" \ -e "s;PRIVATE_KEY;${PRIVATE_KEY};g" \ -e "s;SERVICE_NAME;${SERVICE_NAME};g" \ + -e "s;WRAPPER_SERVICE_IP;${WRAPPER_SERVICE_IP};g" \ > "${CONFIG_FILE}" cat "${CONFIG_FILE}" -shift 8 +shift 9 /usr/local/bin/envoy --drain-time-s 1 -c "${CONFIG_FILE}" "$@" rm -rf "${CONFIG_DIR}" From ca7afc87c580635cdbb94ffc4e8a57a060c5825d Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Thu, 17 Oct 2024 18:26:00 +0200 Subject: [PATCH 02/10] fix linting --- .../snapshot/resource/routes/CustomRoutesFactory.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt index a72fc5346..bf4bcf7f5 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt @@ -10,7 +10,7 @@ import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcherType class CustomRoutesFactory(properties: RoutesProperties) { val routes: List = properties.customs.filter { it.enabled }.map { - val matcher = when(it.path.type) { + val matcher = when (it.path.type) { StringMatcherType.REGEX -> RouteMatch.newBuilder() .setSafeRegex( RegexMatcher.newBuilder() @@ -31,6 +31,4 @@ class CustomRoutesFactory(properties: RoutesProperties) { } fun generateCustomRoutes() = routes - - } From f4cc5bade5e86c948e3e91b0d6b3534ddb0dfd07 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Thu, 17 Oct 2024 18:27:45 +0200 Subject: [PATCH 03/10] fix linting --- .../snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt index 4c84db416..e30c8438e 100644 --- a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt +++ b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt @@ -162,7 +162,6 @@ internal class EnvoyIngressRoutesFactoryTest { matchingOnPrefix("/status/wrapper/") .toCluster("wrapper") .publicAccess() - }, { ingressRoute() From 7fb4b8e304ef9199f4cd6df830334de9cf285be7 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Thu, 17 Oct 2024 18:29:44 +0200 Subject: [PATCH 04/10] fix linting --- .../tech/servicemesh/envoycontrol/CustomRouteTest.kt | 9 --------- .../envoycontrol/config/envoy/EnvoyContainer.kt | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt index 390628994..917644b32 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt @@ -1,24 +1,15 @@ package pl.allegro.tech.servicemesh.envoycontrol -import okhttp3.Headers.Companion.toHeaders -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.RequestBody -import okhttp3.Response import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.Arguments -import org.junit.jupiter.params.provider.MethodSource import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtension import pl.allegro.tech.servicemesh.envoycontrol.config.service.EchoServiceExtension import pl.allegro.tech.servicemesh.envoycontrol.snapshot.CustomRuteProperties -import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SecuredRoute import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcher import pl.allegro.tech.servicemesh.envoycontrol.snapshot.StringMatcherType -import java.util.stream.Stream internal class CustomRouteTest { companion object { diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt index a6e0e1c8c..94e1bad3a 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyContainer.kt @@ -17,7 +17,7 @@ class EnvoyContainer( private val envoyControl2XdsPort: Int = envoyControl1XdsPort, private val logLevel: String = "info", image: String = DEFAULT_IMAGE, - private val wrapperServiceIp: () -> String = {"127.0.0.1"}, + private val wrapperServiceIp: () -> String = { "127.0.0.1" }, ) : SSLGenericContainer( dockerfileBuilder = DockerfileBuilder() .from(image) From 38583fea32ec48feb49eb000a1630fde6d0489ee Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Tue, 12 Nov 2024 12:34:06 +0100 Subject: [PATCH 05/10] add prefix rewrite --- .../servicemesh/envoycontrol/snapshot/SnapshotProperties.kt | 1 + .../snapshot/resource/routes/CustomRoutesFactory.kt | 5 +++++ 2 files changed, 6 insertions(+) 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 d36feb317..d94f3305f 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 @@ -264,6 +264,7 @@ class AuthorizationProperties { class CustomRuteProperties { var enabled = false var cluster = "custom" + var prefixRewrite = "" var path = StringMatcher() } diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt index bf4bcf7f5..6858cfced 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/CustomRoutesFactory.kt @@ -25,6 +25,11 @@ class CustomRoutesFactory(properties: RoutesProperties) { .setName(it.cluster) .setRoute(RouteAction.newBuilder() .setCluster(it.cluster) + .also { route -> + if (it.prefixRewrite != "") { + route.setPrefixRewrite(it.prefixRewrite) + } + } ) .setMatch(matcher) .build() From fc51904bc52611c6b7e7227b55d6d20085879674 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Fri, 15 Nov 2024 15:08:37 +0100 Subject: [PATCH 06/10] put custom routes before admin --- .../snapshot/resource/routes/EnvoyIngressRoutesFactory.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt index cdc80da5d..52468d9d9 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactory.kt @@ -236,8 +236,8 @@ class EnvoyIngressRoutesFactory( .setName("secured_local_service") .addDomains("*") .addAllVirtualClusters(virtualClusters) - .addAllRoutes(adminRoutesFactory.generateAdminRoutes()) .addAllRoutes(customRoutesFactory.generateCustomRoutes()) + .addAllRoutes(adminRoutesFactory.generateAdminRoutes()) .addAllRoutes(generateSecuredIngressRoutes(proxySettings, group)) .also { if (properties.localService.retryPolicy.default.enabled) { From 0c707e204d9716f0f5fb5cd55cfc7050ab6190a6 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Mon, 18 Nov 2024 10:56:50 +0100 Subject: [PATCH 07/10] fix test --- .../allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt index 917644b32..2b9065eb4 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt @@ -3,6 +3,8 @@ package pl.allegro.tech.servicemesh.envoycontrol import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension +import pl.allegro.tech.servicemesh.envoycontrol.assertions.isFrom +import pl.allegro.tech.servicemesh.envoycontrol.assertions.isOk import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtension @@ -52,6 +54,6 @@ internal class CustomRouteTest { endpoint = "/status/wrapper/prometheus" ) // then - assertThat(response.isSuccessful).isTrue() + assertThat(response).isOk().isFrom(wrapper) } } From fdbda5b97b13a468b0558807980dbf0173f8eda3 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Mon, 18 Nov 2024 11:13:00 +0100 Subject: [PATCH 08/10] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25dd586c6..45e518bb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Lists all changes with user impact. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). +## [0.22.3] +### Changed +- Add possibility to create custom routes + ## [0.22.2] ### Changed - Migrated metrics to prometheus From f60d93ebcca7011a80a06dbf26b58c565ce6d940 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Mon, 18 Nov 2024 12:31:41 +0100 Subject: [PATCH 09/10] fix test --- .../allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt | 4 +++- .../servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt index 2b9065eb4..e81304ab1 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/CustomRouteTest.kt @@ -45,6 +45,7 @@ internal class CustomRouteTest { @JvmField @RegisterExtension + // val envoy = EnvoyExtension(envoyControl, service) val envoy = EnvoyExtension(envoyControl, service, wrapperService = wrapper) } @Test @@ -54,6 +55,7 @@ internal class CustomRouteTest { endpoint = "/status/wrapper/prometheus" ) // then - assertThat(response).isOk().isFrom(wrapper) + assertThat(response).isOk() + .isFrom(wrapper) } } diff --git a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt index 75e8dd62f..4b13e9b95 100644 --- a/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt +++ b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/envoy/EnvoyExtension.kt @@ -41,6 +41,7 @@ class EnvoyExtension( override fun beforeAll(context: ExtensionContext) { localService?.beforeAll(context) + wrapperService?.beforeAll(context) envoyControl.beforeAll(context) try { container.start() From 7895670fe94e430eea4175651485433b4300e211 Mon Sep 17 00:00:00 2001 From: Kamil Smigielski Date: Mon, 18 Nov 2024 13:12:39 +0100 Subject: [PATCH 10/10] fix test --- .../snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt index e30c8438e..40a37ed86 100644 --- a/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt +++ b/envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/routes/EnvoyIngressRoutesFactoryTest.kt @@ -157,12 +157,12 @@ internal class EnvoyIngressRoutesFactoryTest { hasStatusVirtualClusters() hasOneDomain("*") hasOnlyRoutesInOrder( - *adminRoutes, { matchingOnPrefix("/status/wrapper/") .toCluster("wrapper") .publicAccess() }, + *adminRoutes, { ingressRoute() matchingOnMethod("GET")