Skip to content

Commit

Permalink
Get mesh_id local label from "CSM_MESH_ID" environment variable, rath…
Browse files Browse the repository at this point in the history
…er than parsing from bootstrap file (#11621)
  • Loading branch information
DNVindhya authored Oct 16, 2024
1 parent b692b9d commit 84d30af
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.grpc.gcp.csm.observability;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.io.BaseEncoding;
import com.google.protobuf.Struct;
Expand All @@ -29,12 +28,9 @@
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.Status;
import io.grpc.internal.JsonParser;
import io.grpc.internal.JsonUtil;
import io.grpc.opentelemetry.InternalOpenTelemetryPlugin;
import io.grpc.protobuf.ProtoUtils;
import io.grpc.xds.ClusterImplLoadBalancerProvider;
import io.grpc.xds.InternalGrpcBootstrapperImpl;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
Expand All @@ -43,16 +39,13 @@
import java.net.URI;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* OpenTelemetryPlugin implementing metadata-based workload property exchange for both client and
* server. Is responsible for determining the metadata, communicating the metadata, and adding local
* and remote details to metrics.
*/
final class MetadataExchanger implements InternalOpenTelemetryPlugin {
private static final Logger logger = Logger.getLogger(MetadataExchanger.class.getName());

private static final AttributeKey<String> CLOUD_PLATFORM =
AttributeKey.stringKey("cloud.platform");
Expand Down Expand Up @@ -89,11 +82,10 @@ final class MetadataExchanger implements InternalOpenTelemetryPlugin {
public MetadataExchanger() {
this(
addOtelResourceAttributes(new GCPResourceProvider().getAttributes()),
System::getenv,
InternalGrpcBootstrapperImpl::getJsonContent);
System::getenv);
}

MetadataExchanger(Attributes platformAttributes, Lookup env, Supplier<String> xdsBootstrap) {
MetadataExchanger(Attributes platformAttributes, Lookup env) {
String type = platformAttributes.get(CLOUD_PLATFORM);
String canonicalService = env.get("CSM_CANONICAL_SERVICE_NAME");
Struct.Builder struct = Struct.newBuilder();
Expand Down Expand Up @@ -121,7 +113,7 @@ public MetadataExchanger() {
localMetadata = BaseEncoding.base64().encode(struct.build().toByteArray());

localAttributes = Attributes.builder()
.put("csm.mesh_id", nullIsUnknown(getMeshId(xdsBootstrap)))
.put("csm.mesh_id", nullIsUnknown(env.get("CSM_MESH_ID")))
.put("csm.workload_canonical_service", nullIsUnknown(canonicalService))
.build();
}
Expand Down Expand Up @@ -162,29 +154,6 @@ private static Attributes addOtelResourceAttributes(Attributes platformAttribute
return builder.build();
}

@VisibleForTesting
static String getMeshId(Supplier<String> xdsBootstrap) {
try {
@SuppressWarnings("unchecked")
Map<String, ?> rawBootstrap = (Map<String, ?>) JsonParser.parse(xdsBootstrap.get());
Map<String, ?> node = JsonUtil.getObject(rawBootstrap, "node");
String id = JsonUtil.getString(node, "id");
Preconditions.checkNotNull(id, "id");
String[] parts = id.split("/", 6);
if (!(parts.length == 6
&& parts[0].equals("projects")
&& parts[2].equals("networks")
&& parts[3].startsWith("mesh:")
&& parts[4].equals("nodes"))) {
throw new Exception("node id didn't match mesh format: " + id);
}
return parts[3].substring("mesh:".length());
} catch (Exception e) {
logger.log(Level.INFO, "Failed to determine mesh ID for CSM", e);
return null;
}
}

private void addLabels(AttributesBuilder to, Struct struct) {
to.putAll(localAttributes);
Map<String, Value> remote = struct.getFieldsMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,14 @@ public void tearDown() {

@Test
public void unknownDataExchange() throws Exception {
String xdsBootstrap = "";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder().build(),
ImmutableMap.<String, String>of()::get,
() -> xdsBootstrap);
ImmutableMap.<String, String>of()::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());
MetadataExchanger serverExchanger = new MetadataExchanger(
Attributes.builder().build(),
ImmutableMap.<String, String>of()::get,
() -> xdsBootstrap);
ImmutableMap.<String, String>of()::get);
CsmObservability.Builder serverCsmBuilder = new CsmObservability.Builder(serverExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down Expand Up @@ -140,11 +137,9 @@ public void unknownDataExchange() throws Exception {

@Test
public void nonCsmServer() throws Exception {
String xdsBootstrap = "";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder().build(),
ImmutableMap.<String, String>of()::get,
() -> xdsBootstrap);
ImmutableMap.<String, String>of()::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down Expand Up @@ -205,19 +200,16 @@ public void nonCsmServer() throws Exception {

@Test
public void nonCsmClient() throws Exception {
String xdsBootstrap = "";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_kubernetes_engine")
.build(),
ImmutableMap.<String, String>of()::get,
() -> xdsBootstrap);
ImmutableMap.<String, String>of()::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());
MetadataExchanger serverExchanger = new MetadataExchanger(
Attributes.builder().build(),
ImmutableMap.<String, String>of()::get,
() -> xdsBootstrap);
ImmutableMap.<String, String>of()::get);
CsmObservability.Builder serverCsmBuilder = new CsmObservability.Builder(serverExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down Expand Up @@ -262,11 +254,6 @@ public void nonCsmClient() throws Exception {

@Test
public void k8sExchange() throws Exception {
// Purposefully use a different project ID in the bootstrap than the resource, as the mesh could
// be in a different project than the running account.
String clientBootstrap = "{\"node\": {"
+ "\"id\": \"projects/12/networks/mesh:mymesh/nodes/a6420022-cbc5-4e10-808c-507e3fc95f2e\""
+ "}}";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_kubernetes_engine")
Expand All @@ -277,13 +264,10 @@ public void k8sExchange() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "canon-service-is-a-client",
"CSM_WORKLOAD_NAME", "best-client")::get,
() -> clientBootstrap);
"CSM_WORKLOAD_NAME", "best-client",
"CSM_MESH_ID", "mymesh")::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());
String serverBootstrap = "{\"node\": {"
+ "\"id\": \"projects/34/networks/mesh:meshhh/nodes/4969ef19-24b6-44c0-baf3-86d188ff5967\""
+ "}}";
MetadataExchanger serverExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_kubernetes_engine")
Expand All @@ -295,8 +279,8 @@ public void k8sExchange() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "server-has-a-single-name",
"CSM_WORKLOAD_NAME", "fast-server")::get,
() -> serverBootstrap);
"CSM_WORKLOAD_NAME", "fast-server",
"CSM_MESH_ID", "meshhh")::get);
CsmObservability.Builder serverCsmBuilder = new CsmObservability.Builder(serverExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down Expand Up @@ -366,11 +350,6 @@ public void k8sExchange() throws Exception {

@Test
public void gceExchange() throws Exception {
// Purposefully use a different project ID in the bootstrap than the resource, as the mesh could
// be in a different project than the running account.
String clientBootstrap = "{\"node\": {"
+ "\"id\": \"projects/12/networks/mesh:mymesh/nodes/a6420022-cbc5-4e10-808c-507e3fc95f2e\""
+ "}}";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_compute_engine")
Expand All @@ -379,13 +358,10 @@ public void gceExchange() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "canon-service-is-a-client",
"CSM_WORKLOAD_NAME", "best-client")::get,
() -> clientBootstrap);
"CSM_WORKLOAD_NAME", "best-client",
"CSM_MESH_ID", "mymesh")::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());
String serverBootstrap = "{\"node\": {"
+ "\"id\": \"projects/34/networks/mesh:meshhh/nodes/4969ef19-24b6-44c0-baf3-86d188ff5967\""
+ "}}";
MetadataExchanger serverExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_compute_engine")
Expand All @@ -395,8 +371,8 @@ public void gceExchange() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "server-has-a-single-name",
"CSM_WORKLOAD_NAME", "fast-server")::get,
() -> serverBootstrap);
"CSM_WORKLOAD_NAME", "fast-server",
"CSM_MESH_ID", "meshhh")::get);
CsmObservability.Builder serverCsmBuilder = new CsmObservability.Builder(serverExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down Expand Up @@ -456,9 +432,6 @@ public void gceExchange() throws Exception {

@Test
public void trailersOnly() throws Exception {
String clientBootstrap = "{\"node\": {"
+ "\"id\": \"projects/12/networks/mesh:mymesh/nodes/a6420022-cbc5-4e10-808c-507e3fc95f2e\""
+ "}}";
MetadataExchanger clientExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_compute_engine")
Expand All @@ -467,13 +440,11 @@ public void trailersOnly() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "canon-service-is-a-client",
"CSM_WORKLOAD_NAME", "best-client")::get,
() -> clientBootstrap);
"CSM_WORKLOAD_NAME", "best-client",
"CSM_MESH_ID", "mymesh")::get);
CsmObservability.Builder clientCsmBuilder = new CsmObservability.Builder(clientExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());
String serverBootstrap = "{\"node\": {"
+ "\"id\": \"projects/34/networks/mesh:meshhh/nodes/4969ef19-24b6-44c0-baf3-86d188ff5967\""
+ "}}";

MetadataExchanger serverExchanger = new MetadataExchanger(
Attributes.builder()
.put(stringKey("cloud.platform"), "gcp_compute_engine")
Expand All @@ -483,8 +454,8 @@ public void trailersOnly() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "server-has-a-single-name",
"CSM_WORKLOAD_NAME", "fast-server")::get,
() -> serverBootstrap);
"CSM_WORKLOAD_NAME", "fast-server",
"CSM_MESH_ID", "meshhh")::get);
CsmObservability.Builder serverCsmBuilder = new CsmObservability.Builder(serverExchanger)
.sdk(openTelemetryTesting.getOpenTelemetry());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,56 +33,11 @@
/** Tests for {@link MetadataExchanger}. */
@RunWith(JUnit4.class)
public final class MetadataExchangerTest {
@Test
public void getMeshId_findsMeshId() {
assertThat(MetadataExchanger.getMeshId(() ->
"{\"node\":{\"id\":\"projects/12/networks/mesh:mine/nodes/uu-id\"}}"))
.isEqualTo("mine");
assertThat(MetadataExchanger.getMeshId(() ->
"{\"node\":{\"id\":\"projects/1234567890/networks/mesh:mine/nodes/uu-id\", "
+ "\"unknown\": \"\"}, \"unknown\": \"\"}"))
.isEqualTo("mine");
}

@Test
public void getMeshId_returnsNullOnBadMeshId() {
assertThat(MetadataExchanger.getMeshId(
() -> "[\"node\"]"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":[\"id\"]}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":[\"projects/12/networks/mesh:mine/nodes/uu-id\"]}}"))
.isNull();

assertThat(MetadataExchanger.getMeshId(
() -> "{\"NODE\":{\"id\":\"projects/12/networks/mesh:mine/nodes/uu-id\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"ID\":\"projects/12/networks/mesh:mine/nodes/uu-id\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":\"projects/12/networks/mesh:mine\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":\"PROJECTS/12/networks/mesh:mine/nodes/uu-id\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":\"projects/12/NETWORKS/mesh:mine/nodes/uu-id\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":\"projects/12/networks/MESH:mine/nodes/uu-id\"}}"))
.isNull();
assertThat(MetadataExchanger.getMeshId(
() -> "{\"node\":{\"id\":\"projects/12/networks/mesh:mine/NODES/uu-id\"}}"))
.isNull();
}

@Test
public void enablePluginForChannel_matches() {
MetadataExchanger exchanger =
new MetadataExchanger(Attributes.builder().build(), (name) -> null, () -> "");
new MetadataExchanger(Attributes.builder().build(), (name) -> null);
assertThat(exchanger.enablePluginForChannel("xds:///testing")).isTrue();
assertThat(exchanger.enablePluginForChannel("xds:/testing")).isTrue();
assertThat(exchanger.enablePluginForChannel(
Expand All @@ -92,7 +47,7 @@ public void enablePluginForChannel_matches() {
@Test
public void enablePluginForChannel_doesNotMatch() {
MetadataExchanger exchanger =
new MetadataExchanger(Attributes.builder().build(), (name) -> null, () -> "");
new MetadataExchanger(Attributes.builder().build(), (name) -> null);
assertThat(exchanger.enablePluginForChannel("dns:///localhost")).isFalse();
assertThat(exchanger.enablePluginForChannel("xds:///[]")).isFalse();
assertThat(exchanger.enablePluginForChannel("xds://my-xds-server/testing")).isFalse();
Expand All @@ -101,7 +56,7 @@ public void enablePluginForChannel_doesNotMatch() {
@Test
public void addLabels_receivedWrongType() {
MetadataExchanger exchanger =
new MetadataExchanger(Attributes.builder().build(), (name) -> null, () -> "");
new MetadataExchanger(Attributes.builder().build(), (name) -> null);
Metadata metadata = new Metadata();
metadata.put(Metadata.Key.of("x-envoy-peer-metadata", Metadata.ASCII_STRING_MARSHALLER),
BaseEncoding.base64().encode(Struct.newBuilder()
Expand All @@ -122,7 +77,7 @@ public void addLabels_receivedWrongType() {
@Test
public void addLabelsFromExchange_unknownGcpType() {
MetadataExchanger exchanger =
new MetadataExchanger(Attributes.builder().build(), (name) -> null, () -> "");
new MetadataExchanger(Attributes.builder().build(), (name) -> null);
Metadata metadata = new Metadata();
metadata.put(Metadata.Key.of("x-envoy-peer-metadata", Metadata.ASCII_STRING_MARSHALLER),
BaseEncoding.base64().encode(Struct.newBuilder()
Expand Down Expand Up @@ -153,8 +108,7 @@ public void addMetadata_k8s() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "myservice1",
"CSM_WORKLOAD_NAME", "myworkload1")::get,
() -> "");
"CSM_WORKLOAD_NAME", "myworkload1")::get);
Metadata metadata = new Metadata();
exchanger.newClientCallPlugin().addMetadata(metadata);

Expand Down Expand Up @@ -182,8 +136,7 @@ public void addMetadata_gce() throws Exception {
.build(),
ImmutableMap.of(
"CSM_CANONICAL_SERVICE_NAME", "myservice1",
"CSM_WORKLOAD_NAME", "myworkload1")::get,
() -> "");
"CSM_WORKLOAD_NAME", "myworkload1")::get);
Metadata metadata = new Metadata();
exchanger.newClientCallPlugin().addMetadata(metadata);

Expand Down

0 comments on commit 84d30af

Please sign in to comment.