Skip to content

Commit be03a6f

Browse files
committed
Merge remote-tracking branch 'origin/master' into delta-xds-hash-bytes
# Conflicts: # envoy-control-core/src/test/kotlin/pl/allegro/tech/servicemesh/envoycontrol/EnvoySnapshotFactoryTest.kt
2 parents ccd59a5 + 9588c84 commit be03a6f

File tree

23 files changed

+576
-179
lines changed

23 files changed

+576
-179
lines changed

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,44 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
55

66
## [Unreleased]
77

8+
### Changed
9+
10+
## [0.19.19]
11+
12+
### Changed
13+
- Add default access log filter configuration
14+
15+
## [0.19.18]
16+
17+
### Changed
18+
- Log authority and lua authority in lua filters
19+
20+
## [0.19.17]
21+
22+
### Changed
23+
- Added debug endpoint
24+
25+
## [0.19.16]
26+
27+
### Changed
28+
- Added tcp dumps for downstream
29+
30+
## [0.19.15]
31+
832
### Changed
933
- Added flags for lua filters
1034
- Added support for Delta XDS
1135

36+
## [0.19.14]
37+
38+
### Changed
39+
- Update java-control-plane - remove api v2
40+
41+
## [0.19.13]
42+
43+
### Changed
44+
- readiness metric
45+
1246
## [0.19.12]
1347

1448
### Changed

docs/configuration.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ Property
2525
Property | Description | Default value
2626
-------------------------------------------------------------------------------------------------------------| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------
2727
**envoy-control.envoy.snapshot.dynamic-listeners.enabled** | Enable or disable creating listeners using dynamic configuration | true
28+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.enabled** | Enable or disable access logs | false
2829
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.time-format** | Time format for access logs | "%START_TIME(%FT%T.%3fZ)%"
2930
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.message-format** | Message format for access logs | "%PROTOCOL% %REQ(:METHOD)% %REQ(:authority)% %REQ(:PATH)% %DOWNSTREAM_REMOTE_ADDRESS% -> %UPSTREAM_HOST%"
3031
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.level** | Logging level for access logs | "TRACE"
3132
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.logger** | Logger name for access logs | "envoy.AccessLog"
32-
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.custom-fields** | Custom fields, which should be included in access logs | "empty map()"
33+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.custom-fields** | Custom fields, which should be included in access logs | null
34+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.filters.status-code** | Default status code filter for access logs | null
35+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.filters.duration** | Default duration filter for access logs | null
36+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.filters.not-health-check** | Disable health checks filter for access logs | true
37+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.filters.response-flag** | Default response flag filter for access logs | null
38+
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.access-log.filters.header** | Default header filter for access logs | null
3339
**envoy-control.envoy.snapshot.dynamic-listeners.http-filters.ingress-xff-num-trusted-hops** | Number of trusted hops for ingress filter (refer to [envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers.html?highlight=xff_num_trusted_hops#x-forwarded-for)) | 1
3440
**envoy-control.envoy.snapshot.dynamic-listeners.local-reply-mapper.enabled** | Enable or disable creating local reply mapper configuration (refer to [envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/local_reply)) | false
3541
**envoy-control.envoy.snapshot.dynamic-listeners.local-reply-mapper.response-format.text-format** | Text message format with placeholders (refer to [envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators)) | ""

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/groups/MetadataNodeGroup.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ class MetadataNodeGroup(
7373
val ingressPortValue = metadata.fieldsMap["ingress_port"]
7474
val egressHostValue = metadata.fieldsMap["egress_host"]
7575
val egressPortValue = metadata.fieldsMap["egress_port"]
76+
val accessLogProperties = properties.dynamicListeners.httpFilters.accessLog
7677
val accessLogFilterSettings = AccessLogFilterSettings(
77-
metadata.fieldsMap["access_log_filter"]
78+
metadata.fieldsMap["access_log_filter"],
79+
accessLogProperties.filters
7880
)
7981

8082
val listenersHostPort = metadataToListenersHostPort(
@@ -96,7 +98,7 @@ class MetadataNodeGroup(
9698
val preserveExternalRequestId = metadata.fieldsMap["preserve_external_request_id"]?.boolValue
9799
?: ListenersConfig.defaultPreserveExternalRequestId
98100
val accessLogEnabled = metadata.fieldsMap["access_log_enabled"]?.boolValue
99-
?: ListenersConfig.defaultAccessLogEnabled
101+
?: accessLogProperties.enabled
100102
val enableLuaScript = metadata.fieldsMap["enable_lua_script"]?.boolValue
101103
?: ListenersConfig.defaultEnableLuaScript
102104
val accessLogPath = metadata.fieldsMap["access_log_path"]?.stringValue

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/groups/NodeMetadata.kt

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.google.protobuf.Value
66
import com.google.protobuf.util.Durations
77
import io.envoyproxy.controlplane.server.exception.RequestException
88
import io.grpc.Status
9+
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.AccessLogFiltersProperties
910
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties
1011
import pl.allegro.tech.servicemesh.envoycontrol.utils.AccessLogFilterParser
1112
import pl.allegro.tech.servicemesh.envoycontrol.utils.ComparisonFilterSettings
@@ -32,16 +33,16 @@ class NodeMetadata(metadata: Struct, properties: SnapshotProperties) {
3233
val proxySettings: ProxySettings = ProxySettings(metadata.fieldsMap["proxy_settings"], properties)
3334
}
3435

35-
data class AccessLogFilterSettings(val proto: Value?) {
36+
data class AccessLogFilterSettings(val proto: Value?, val properties: AccessLogFiltersProperties) {
3637
val statusCodeFilterSettings: ComparisonFilterSettings? = proto?.field("status_code_filter")
37-
.toComparisonFilter()
38+
.toComparisonFilter(properties.statusCode)
3839
val durationFilterSettings: ComparisonFilterSettings? = proto?.field("duration_filter")
39-
.toComparisonFilter()
40-
val notHealthCheckFilter: Boolean? = proto?.field("not_health_check_filter")?.boolValue
40+
.toComparisonFilter(properties.duration)
41+
val notHealthCheckFilter: Boolean? = proto?.field("not_health_check_filter")?.boolValue ?: properties.notHealthCheck
4142
val responseFlagFilter: Iterable<String>? = proto?.field("response_flag_filter")
42-
.toResponseFlagFilter()
43+
.toResponseFlagFilter(properties.responseFlag)
4344
val headerFilter: HeaderFilterSettings? = proto?.field("header_filter")
44-
.toHeaderFilter()
45+
.toHeaderFilter(properties.header)
4546
}
4647

4748
data class ProxySettings(
@@ -73,20 +74,20 @@ private fun getCommunicationMode(proto: Value?): CommunicationMode {
7374
}
7475
}
7576

76-
fun Value?.toComparisonFilter(): ComparisonFilterSettings? {
77-
return this?.stringValue?.let {
77+
fun Value?.toComparisonFilter(default: String? = null): ComparisonFilterSettings? {
78+
return (this?.stringValue ?: default)?.let {
7879
AccessLogFilterParser.parseComparisonFilter(it.uppercase())
7980
}
8081
}
8182

82-
fun Value?.toResponseFlagFilter(): Iterable<String>? {
83-
return this?.stringValue?.let {
83+
fun Value?.toResponseFlagFilter(default: String? = null): Iterable<String>? {
84+
return (this?.stringValue ?: default)?.let {
8485
AccessLogFilterParser.parseResponseFlagFilter(it.uppercase())
8586
}
8687
}
8788

88-
fun Value?.toHeaderFilter(): HeaderFilterSettings? {
89-
return this?.stringValue?.let {
89+
fun Value?.toHeaderFilter(default: String? = null): HeaderFilterSettings? {
90+
return (this?.stringValue ?: default)?.let {
9091
AccessLogFilterParser.parseHeaderFilter(it)
9192
}
9293
}

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/SnapshotProperties.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class SnapshotProperties {
3535
var rateLimit = RateLimitProperties()
3636
var deltaXdsEnabled = false
3737
var retryPolicy = RetryPolicyProperties()
38-
var shouldAuditGlobalSnapshot = false
38+
var tcpDumpsEnabled: Boolean = true
3939
}
4040

4141
class MetricsProperties {
@@ -54,12 +54,22 @@ class HttpFiltersProperties {
5454
}
5555

5656
class AccessLogProperties {
57+
var enabled = false
5758
var timeFormat = "%START_TIME(%FT%T.%3fZ)%"
5859
var messageFormat = "%PROTOCOL% %REQ(:METHOD)% %REQ(:authority)% %REQ(:PATH)% " +
5960
"%DOWNSTREAM_REMOTE_ADDRESS% -> %UPSTREAM_HOST%"
6061
var level = "TRACE"
6162
var logger = "envoy.AccessLog"
6263
var customFields = mapOf<String, String>()
64+
var filters = AccessLogFiltersProperties()
65+
}
66+
67+
class AccessLogFiltersProperties {
68+
var statusCode: String? = null
69+
var duration: String? = null
70+
var notHealthCheck: Boolean? = true
71+
var responseFlag: String? = null
72+
var header: String? = null
6373
}
6474

6575
class OutgoingPermissionsProperties {

envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/clusters/EnvoyClustersFactory.kt

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import io.envoyproxy.envoy.config.endpoint.v3.LbEndpoint
2727
import io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints
2828
import io.envoyproxy.envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
2929
import io.envoyproxy.envoy.extensions.common.dynamic_forward_proxy.v3.DnsCacheConfig
30+
import io.envoyproxy.envoy.extensions.common.tap.v3.AdminConfig
31+
import io.envoyproxy.envoy.extensions.common.tap.v3.CommonExtensionConfig
32+
import io.envoyproxy.envoy.extensions.transport_sockets.tap.v3.Tap
3033
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext
3134
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext
3235
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.SdsSecretConfig
@@ -61,12 +64,6 @@ class EnvoyClustersFactory(
6164
private val allThresholds = CircuitBreakers.newBuilder().addAllThresholds(thresholds).build()
6265
private val tlsProperties = properties.incomingPermissions.tlsAuthentication
6366
private val sanUriMatcher = SanUriMatcherFactory(tlsProperties)
64-
private val matchPlaintextContext = Cluster.TransportSocketMatch.newBuilder()
65-
.setName("plaintext_match")
66-
.setTransportSocket(
67-
TransportSocket.newBuilder().setName("envoy.transport_sockets.raw_buffer").build()
68-
)
69-
.build()
7067

7168
private val tlsContextMatch = Struct.newBuilder()
7269
.putFields(tlsProperties.tlsContextMetadataMatchKey, Value.newBuilder().setBoolValue(true).build())
@@ -94,14 +91,20 @@ class EnvoyClustersFactory(
9491
val matchTlsContext = Cluster.TransportSocketMatch.newBuilder()
9592
.setName("mtls_match")
9693
.setMatch(tlsContextMatch)
97-
.setTransportSocket(
94+
.setTransportSocket(wrapTransportSocket(cluster.name) {
9895
TransportSocket.newBuilder()
9996
.setName("envoy.transport_sockets.tls")
10097
.setTypedConfig(Any.pack(upstreamTlsContext))
101-
)
98+
.build()
99+
})
102100
.build()
103101

104-
secureCluster.addAllTransportSocketMatches(listOf(matchTlsContext, matchPlaintextContext))
102+
secureCluster.addAllTransportSocketMatches(
103+
listOf(
104+
matchTlsContext,
105+
createMatchPlainText("plaintext_${cluster.name}")
106+
)
107+
)
105108
.build()
106109
}
107110
}
@@ -135,7 +138,7 @@ class EnvoyClustersFactory(
135138
)
136139

137140
if (provider.jwksUri.scheme == "https") {
138-
cluster.setTransportSocket(
141+
cluster.transportSocket = wrapTransportSocket(cluster.name) {
139142
TransportSocket.newBuilder()
140143
.setName("envoy.transport_sockets.tls")
141144
.setTypedConfig(
@@ -151,8 +154,8 @@ class EnvoyClustersFactory(
151154
)
152155
).build()
153156
)
154-
)
155-
)
157+
).build()
158+
}
156159
} else {
157160
logger.warn("Jwks url [${provider.jwksUri}] is not using HTTPS scheme.")
158161
}
@@ -170,7 +173,8 @@ class EnvoyClustersFactory(
170173
return listOf(Cluster.newBuilder(cluster).build())
171174
}
172175

173-
logger.warn("ratelimit service [{}] cluster required for service [{}] has not been found.",
176+
logger.warn(
177+
"ratelimit service [{}] cluster required for service [{}] has not been found.",
174178
properties.rateLimit.serviceName,
175179
group.serviceName
176180
)
@@ -320,13 +324,15 @@ class EnvoyClustersFactory(
320324
).build()
321325

322326
val upstreamTlsContext = UpstreamTlsContext.newBuilder().setCommonTlsContext(commonTlsContext).build()
323-
val transportSocket = TransportSocket.newBuilder()
324-
.setTypedConfig(
325-
Any.pack(
326-
upstreamTlsContext
327+
val transportSocket = wrapTransportSocket(domainDependency.getClusterName()) {
328+
TransportSocket.newBuilder()
329+
.setTypedConfig(
330+
Any.pack(
331+
upstreamTlsContext
332+
)
327333
)
328-
)
329-
.setName("envoy.transport_sockets.tls").build()
334+
.setName("envoy.transport_sockets.tls").build()
335+
}
330336

331337
clusterBuilder
332338
.setTransportSocket(transportSocket)
@@ -560,23 +566,52 @@ class EnvoyClustersFactory(
560566
)
561567
)
562568
.setTransportSocket(
563-
TransportSocket.newBuilder()
564-
.setName("envoy.transport_sockets.tls")
565-
.setTypedConfig(
566-
Any.pack(
567-
UpstreamTlsContext.newBuilder()
568-
.setCommonTlsContext(
569-
CommonTlsContext.newBuilder()
570-
.setValidationContext(
571-
CertificateValidationContext.newBuilder()
572-
.setTrustedCa(
573-
DataSource.newBuilder().setFilename(properties.trustedCaFile)
574-
.build()
575-
)
576-
)
577-
).build()
578-
)
579-
)
569+
wrapTransportSocket(properties.dynamicForwardProxy.clusterName) {
570+
TransportSocket.newBuilder()
571+
.setName("envoy.transport_sockets.tls")
572+
.setTypedConfig(
573+
Any.pack(
574+
UpstreamTlsContext.newBuilder()
575+
.setCommonTlsContext(
576+
CommonTlsContext.newBuilder()
577+
.setValidationContext(
578+
CertificateValidationContext.newBuilder()
579+
.setTrustedCa(
580+
DataSource.newBuilder().setFilename(properties.trustedCaFile)
581+
.build()
582+
)
583+
)
584+
).build()
585+
)
586+
).build()
587+
}
580588
).build()
581589
}
590+
591+
private fun wrapTransportSocket(clusterName: String, supplier: () -> TransportSocket): TransportSocket {
592+
return if (properties.tcpDumpsEnabled) {
593+
TransportSocket.newBuilder()
594+
.setName("envoy.transport_sockets.tap")
595+
.setTypedConfig(
596+
Any.pack(
597+
Tap.newBuilder().setCommonConfig(
598+
CommonExtensionConfig.newBuilder().setAdminConfig(
599+
AdminConfig.newBuilder().setConfigId("${clusterName}_tap")
600+
)
601+
).setTransportSocket(supplier()).build()
602+
)
603+
).build()
604+
} else {
605+
supplier()
606+
}
607+
}
608+
609+
private fun createMatchPlainText(clusterName: String) = Cluster.TransportSocketMatch.newBuilder()
610+
.setName("plaintext_match")
611+
.setTransportSocket(
612+
wrapTransportSocket(clusterName) {
613+
TransportSocket.newBuilder().setName("envoy.transport_sockets.raw_buffer").build()
614+
}
615+
)
616+
.build()
582617
}

0 commit comments

Comments
 (0)