Skip to content

Commit 18a3b75

Browse files
Enable TLS for SecureNetty4GrpcServerTransport (#17796)
- Adds SecureAuxTransportSettingsProvider to provide aux transports access to a javax SSLContext and cipher/client auth params for configuring TLS. - Implements SecureNetty4GrpcServerTransport to consume a SecureAuxTransportSettingsProvider for a TLS enabled gRPC transport. - Add aux transport type settings and port setttings for new secure transport. - Add logic to detect and register secure aux transports provided by plugins. - Integration tests for SecureNetty4GrpcServerTransport basic client cert authentication. Signed-off-by: Finn Carroll <[email protected]>
1 parent 967eee1 commit 18a3b75

File tree

24 files changed

+1239
-39
lines changed

24 files changed

+1239
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2323
- [Security Manager Replacement] Enhance Java Agent to intercept Runtime::halt ([#17757](https://github.com/opensearch-project/OpenSearch/pull/17757))
2424
- [Security Manager Replacement] Phase off SecurityManager usage in favor of Java Agent ([#17861](https://github.com/opensearch-project/OpenSearch/pull/17861))
2525
- Support AutoExpand for SearchReplica ([#17741](https://github.com/opensearch-project/OpenSearch/pull/17741))
26+
- Add TLS enabled SecureNetty4GrpcServerTransport ([#17796](https://github.com/opensearch-project/OpenSearch/pull/17796))
2627
- Implement fixed interval refresh task scheduling ([#17777](https://github.com/opensearch-project/OpenSearch/pull/17777))
2728
- [Tiered caching] Create a single cache manager for all the disk caches. ([#17513](https://github.com/opensearch-project/OpenSearch/pull/17513))
2829
- Add GRPC DocumentService and Bulk endpoint ([#17727](https://github.com/opensearch-project/OpenSearch/pull/17727))

plugins/arrow-flight-rpc/src/main/java/org/opensearch/arrow/flight/bootstrap/FlightService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ public StreamManager getStreamManager() {
134134
* Retrieves the bound address of the FlightService.
135135
* @return The BoundTransportAddress instance.
136136
*/
137+
@Override
137138
public BoundTransportAddress getBoundAddress() {
138139
return serverComponents.getBoundAddress();
139140
}

plugins/transport-grpc/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# transport-grpc
2+
3+
An auxiliary transport which runs in parallel to the REST API.
4+
The `transport-grpc` plugin initializes a new client/server transport implementing a gRPC protocol on Netty4.
5+
6+
Enable this transport with:
7+
8+
```
9+
setting 'aux.transport.types', '[experimental-transport-grpc]'
10+
setting 'aux.transport.experimental-transport-grpc.port', '9400-9500' //optional
11+
```
12+
13+
For the secure transport:
14+
15+
```
16+
setting 'aux.transport.types', '[experimental-secure-transport-grpc]'
17+
setting 'aux.transport.experimental-secure-transport-grpc.port', '9400-9500' //optional
18+
```
19+
20+
Other settings are agnostic as to the gRPC transport type:
21+
22+
```
23+
setting 'grpc.publish_port', '9400'
24+
setting 'grpc.host', '["0.0.0.0"]'
25+
setting 'grpc.bind_host', '["0.0.0.0", "::", "10.0.0.1"]'
26+
setting 'grpc.publish_host', '["thisnode.example.com"]'
27+
setting 'grpc.netty.worker_count', '2'
28+
```
29+
30+
## Testing
31+
32+
### Unit Tests
33+
34+
```
35+
./gradlew :plugins:transport-grpc:test
36+
```
37+
38+
### Integration Tests
39+
40+
```
41+
./gradlew :plugins:transport-grpc:internalClusterTest
42+
```

plugins/transport-grpc/build.gradle

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import org.gradle.api.attributes.java.TargetJvmEnvironment
2-
31
/*
42
* SPDX-License-Identifier: Apache-2.0
53
*
@@ -8,13 +6,21 @@ import org.gradle.api.attributes.java.TargetJvmEnvironment
86
* compatible open source license.
97
*/
108

9+
apply plugin: 'opensearch.testclusters'
1110
apply plugin: 'opensearch.internal-cluster-test'
1211

1312
opensearchplugin {
1413
description = 'gRPC based transport implementation'
1514
classname = 'org.opensearch.plugin.transport.grpc.GrpcPlugin'
1615
}
1716

17+
testClusters {
18+
integTest {
19+
plugin(project.path)
20+
setting 'aux.transport.types', '[experimental-transport-grpc]'
21+
}
22+
}
23+
1824
dependencies {
1925
compileOnly "com.google.code.findbugs:jsr305:3.0.2"
2026
runtimeOnly "com.google.guava:guava:${versions.guava}"
@@ -30,6 +36,7 @@ dependencies {
3036
implementation "io.grpc:grpc-util:${versions.grpc}"
3137
implementation "io.perfmark:perfmark-api:0.26.0"
3238
implementation "org.opensearch:protobufs:0.2.0"
39+
testImplementation project(':test:framework')
3340
}
3441

3542
tasks.named("dependencyLicenses").configure {

plugins/transport-grpc/src/internalClusterTest/java/org/opensearch/plugin/transport/grpc/GrpcTransportIT.java renamed to plugins/transport-grpc/src/internalClusterTest/java/org/opensearch/plugin/transport/grpc/Netty4GrpcServerTransportIT.java

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,45 @@
88

99
package org.opensearch.plugin.transport.grpc;
1010

11+
import org.opensearch.action.admin.cluster.health.ClusterHealthResponse;
12+
import org.opensearch.cluster.health.ClusterHealthStatus;
1113
import org.opensearch.common.network.NetworkAddress;
1214
import org.opensearch.common.settings.Settings;
1315
import org.opensearch.core.common.transport.TransportAddress;
16+
import org.opensearch.plugin.transport.grpc.ssl.NettyGrpcClient;
1417
import org.opensearch.plugins.Plugin;
1518
import org.opensearch.test.OpenSearchIntegTestCase;
1619

1720
import java.net.InetSocketAddress;
21+
import java.util.ArrayList;
1822
import java.util.Collection;
1923
import java.util.Collections;
24+
import java.util.List;
25+
26+
import io.grpc.health.v1.HealthCheckResponse;
2027

2128
import static org.opensearch.plugin.transport.grpc.Netty4GrpcServerTransport.GRPC_TRANSPORT_SETTING_KEY;
22-
import static org.opensearch.plugin.transport.grpc.Netty4GrpcServerTransport.SETTING_GRPC_PORT;
2329
import static org.opensearch.plugins.NetworkPlugin.AuxTransport.AUX_TRANSPORT_TYPES_KEY;
2430

25-
@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.TEST, numDataNodes = 2)
26-
public class GrpcTransportIT extends OpenSearchIntegTestCase {
31+
public class Netty4GrpcServerTransportIT extends OpenSearchIntegTestCase {
2732

28-
@Override
29-
protected Collection<Class<? extends Plugin>> nodePlugins() {
30-
return Collections.singletonList(GrpcPlugin.class);
33+
private TransportAddress randomNetty4GrpcServerTransportAddr() {
34+
List<TransportAddress> addresses = new ArrayList<>();
35+
for (Netty4GrpcServerTransport transport : internalCluster().getInstances(Netty4GrpcServerTransport.class)) {
36+
TransportAddress tAddr = new TransportAddress(transport.getBoundAddress().publishAddress().address());
37+
addresses.add(tAddr);
38+
}
39+
return randomFrom(addresses);
3140
}
3241

3342
@Override
3443
protected Settings nodeSettings(int nodeOrdinal) {
35-
return Settings.builder()
36-
.put(super.nodeSettings(nodeOrdinal))
37-
.put(SETTING_GRPC_PORT.getKey(), "0")
38-
.put(AUX_TRANSPORT_TYPES_KEY, GRPC_TRANSPORT_SETTING_KEY)
39-
.build();
44+
return Settings.builder().put(super.nodeSettings(nodeOrdinal)).put(AUX_TRANSPORT_TYPES_KEY, GRPC_TRANSPORT_SETTING_KEY).build();
45+
}
46+
47+
@Override
48+
protected Collection<Class<? extends Plugin>> nodePlugins() {
49+
return Collections.singleton(GrpcPlugin.class);
4050
}
4151

4252
public void testGrpcTransportStarted() {
@@ -46,7 +56,7 @@ public void testGrpcTransportStarted() {
4656
assertNotNull("gRPC transport should be started on node " + nodeName, transport);
4757

4858
// Verify that the transport is bound to an address
49-
TransportAddress[] boundAddresses = transport.boundAddress().boundAddresses();
59+
TransportAddress[] boundAddresses = transport.getBoundAddress().boundAddresses();
5060
assertTrue("gRPC transport should be bound to at least one address", boundAddresses.length > 0);
5161

5262
// Log the bound addresses for debugging
@@ -56,4 +66,15 @@ public void testGrpcTransportStarted() {
5666
}
5767
}
5868
}
69+
70+
public void testStartGrpcTransportClusterHealth() throws Exception {
71+
// REST api cluster health
72+
ClusterHealthResponse healthResponse = client().admin().cluster().prepareHealth().get();
73+
assertEquals(ClusterHealthStatus.GREEN, healthResponse.getStatus());
74+
75+
// gRPC transport service health
76+
try (NettyGrpcClient client = new NettyGrpcClient.Builder().setAddress(randomNetty4GrpcServerTransportAddr()).build()) {
77+
assertEquals(client.checkHealth(), HealthCheckResponse.ServingStatus.SERVING);
78+
}
79+
}
5980
}

0 commit comments

Comments
 (0)