Azure resource providers (#1228)

Co-authored-by: heyams <heya@microsoft.com>
This commit is contained in:
Gregor Zeitlinger 2025-01-17 17:46:21 +01:00 committed by GitHub
parent 1b006501c0
commit c19a97334a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 1371 additions and 0 deletions

View File

@ -19,6 +19,9 @@ components:
aws-xray-propagator:
- wangzlei
- srprash
azure-resources:
- trask
- zeitlinger
baggage-processor:
- mikegoldsmith
- zeitlinger

35
azure-resources/README.md Normal file
View File

@ -0,0 +1,35 @@
# Azure Resource Detectors for OpenTelemetry
This module provides Azure resource detectors for OpenTelemetry.
The following OpenTelemetry semantic conventions will be detected:
| Resource attribute | VM | Functions | App Service | Containers |
|-------------------------|----------|-----------------|-------------------|----------------------|
| cloud.platform | azure_vm | azure_functions | azure_app_service | azure_container_apps |
| cloud.provider | azure | azure | azure | azure |
| cloud.resource.id | auto | | auto | |
| cloud.region | auto | auto | auto | |
| deployment.environment | | | auto | |
| host.id | auto | | auto | |
| host.name | auto | | | |
| host.type | auto | | | |
| os.type | auto | | | |
| os.version | auto | | | |
| azure.vm.scaleset.name | auto | | | |
| azure.vm.sku | auto | | | |
| service.name | | | auto | auto |
| service.version | | | | auto |
| service.instance.id | | | auto | auto |
| azure.app.service.stamp | | | auto | |
| faas.name | | auto | | |
| faas.version | | auto | | |
| faas.instance | | auto | | |
| faas.faas.max_memory | | auto | | |
## Component Owners
- [Trask Stalnaker](https://github.com/trask), Microsoft
- [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana
Learn more about component owners in [component_owners.yml](../.github/component_owners.yml).

View File

@ -0,0 +1,37 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
id("maven-publish")
}
description = "OpenTelemetry GCP Resources Support"
otelJava.moduleName.set("io.opentelemetry.contrib.gcp.resource")
// enable publishing to maven local
java {
withSourcesJar()
}
dependencies {
api("io.opentelemetry:opentelemetry-api")
api("io.opentelemetry:opentelemetry-sdk")
implementation("io.opentelemetry.semconv:opentelemetry-semconv")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.squareup.okhttp3:okhttp")
testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating")
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
// testImplementation("org.mockito:mockito-core")
testImplementation("com.google.guava:guava")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.assertj:assertj-core")
testImplementation("com.linecorp.armeria:armeria-junit5")
}

View File

@ -0,0 +1,73 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CloudPlatformIncubatingValues.AZURE_AKS;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.K8S_CLUSTER_NAME;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
public class AzureAksResourceProvider extends CloudResourceProvider {
private static final Map<String, AzureVmResourceProvider.Entry> COMPUTE_MAPPING = new HashMap<>();
static {
COMPUTE_MAPPING.put(
"resourceGroupName",
new AzureVmResourceProvider.Entry(
K8S_CLUSTER_NAME, AzureAksResourceProvider::parseClusterName));
}
// visible for testing
static String parseClusterName(String resourceGroup) {
// Code inspired by
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/datadogexporter/internal/hostmetadata/internal/azure/provider.go#L36
String[] splitAll = resourceGroup.split("_");
if (splitAll.length == 4 && splitAll[0].equalsIgnoreCase("mc")) {
return splitAll[splitAll.length - 2];
}
return resourceGroup;
}
// Environment variable that is set when running on Kubernetes
static final String KUBERNETES_SERVICE_HOST = "KUBERNETES_SERVICE_HOST";
private final Supplier<Optional<String>> client;
private final Map<String, String> environment;
// SPI
public AzureAksResourceProvider() {
this(AzureMetadataService.defaultClient(), System.getenv());
}
// visible for testing
AzureAksResourceProvider(Supplier<Optional<String>> client, Map<String, String> environment) {
this.client = client;
this.environment = environment;
}
@Override
public int order() {
// run after the fast cloud resource providers that only check environment variables
// and before the AKS provider
return 100;
}
@Override
public Resource createResource(ConfigProperties configProperties) {
if (environment.get(KUBERNETES_SERVICE_HOST) == null) {
return Resource.empty();
}
return client
.get()
.map(body -> AzureVmResourceProvider.parseMetadata(body, COMPUTE_MAPPING, AZURE_AKS))
.orElse(Resource.empty());
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_REGION;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_RESOURCE_ID;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CloudPlatformIncubatingValues.AZURE_APP_SERVICE;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.DEPLOYMENT_ENVIRONMENT_NAME;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.HOST_ID;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.SERVICE_INSTANCE_ID;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.internal.StringUtils;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
public class AzureAppServiceResourceProvider extends CloudResourceProvider {
static final AttributeKey<String> AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE =
AttributeKey.stringKey("azure.app.service.stamp");
static final String REGION_NAME = "REGION_NAME";
private static final String WEBSITE_HOME_STAMPNAME = "WEBSITE_HOME_STAMPNAME";
private static final String WEBSITE_HOSTNAME = "WEBSITE_HOSTNAME";
static final String WEBSITE_INSTANCE_ID = "WEBSITE_INSTANCE_ID";
private static final String WEBSITE_OWNER_NAME = "WEBSITE_OWNER_NAME";
private static final String WEBSITE_RESOURCE_GROUP = "WEBSITE_RESOURCE_GROUP";
static final String WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME";
private static final String WEBSITE_SLOT_NAME = "WEBSITE_SLOT_NAME";
private static final Map<AttributeKey<String>, String> ENV_VAR_MAPPING = new HashMap<>();
static {
ENV_VAR_MAPPING.put(CLOUD_REGION, REGION_NAME);
ENV_VAR_MAPPING.put(DEPLOYMENT_ENVIRONMENT_NAME, WEBSITE_SLOT_NAME);
ENV_VAR_MAPPING.put(HOST_ID, WEBSITE_HOSTNAME);
ENV_VAR_MAPPING.put(SERVICE_INSTANCE_ID, WEBSITE_INSTANCE_ID);
ENV_VAR_MAPPING.put(AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE, WEBSITE_HOME_STAMPNAME);
}
private final Map<String, String> env;
// SPI
public AzureAppServiceResourceProvider() {
this(System.getenv());
}
// Visible for testing
AzureAppServiceResourceProvider(Map<String, String> env) {
this.env = env;
}
@Override
public Resource createResource(ConfigProperties config) {
return Resource.create(getAttributes());
}
public Attributes getAttributes() {
AzureEnvVarPlatform detect = AzureEnvVarPlatform.detect(env);
if (detect != AzureEnvVarPlatform.APP_SERVICE) {
return Attributes.empty();
}
String name = Objects.requireNonNull(env.get(WEBSITE_SITE_NAME));
AttributesBuilder builder = AzureVmResourceProvider.azureAttributeBuilder(AZURE_APP_SERVICE);
builder.put(SERVICE_NAME, name);
String resourceUri = resourceUri(name);
if (resourceUri != null) {
builder.put(CLOUD_RESOURCE_ID, resourceUri);
}
AzureEnvVarPlatform.addAttributesFromEnv(ENV_VAR_MAPPING, env, builder);
return builder.build();
}
@Nullable
private String resourceUri(String websiteName) {
String websiteResourceGroup = env.get(WEBSITE_RESOURCE_GROUP);
String websiteOwnerName = env.get(WEBSITE_OWNER_NAME);
String subscriptionId;
if (websiteOwnerName != null && websiteOwnerName.contains("+")) {
subscriptionId = websiteOwnerName.substring(0, websiteOwnerName.indexOf("+"));
} else {
subscriptionId = websiteOwnerName;
}
if (StringUtils.isNullOrEmpty(websiteResourceGroup)
|| StringUtils.isNullOrEmpty(subscriptionId)) {
return null;
}
return String.format(
"/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s",
subscriptionId, websiteResourceGroup, websiteName);
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.SERVICE_INSTANCE_ID;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_VERSION;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import java.util.HashMap;
import java.util.Map;
public class AzureContainersResourceProvider extends CloudResourceProvider {
static final String CONTAINER_APP_NAME = "CONTAINER_APP_NAME";
private static final String CONTAINER_APP_REPLICA_NAME = "CONTAINER_APP_REPLICA_NAME";
private static final String CONTAINER_APP_REVISION = "CONTAINER_APP_REVISION";
private static final Map<AttributeKey<String>, String> ENV_VAR_MAPPING = new HashMap<>();
static {
ENV_VAR_MAPPING.put(SERVICE_NAME, CONTAINER_APP_NAME);
ENV_VAR_MAPPING.put(SERVICE_INSTANCE_ID, CONTAINER_APP_REPLICA_NAME);
ENV_VAR_MAPPING.put(SERVICE_VERSION, CONTAINER_APP_REVISION);
}
private final Map<String, String> env;
// SPI
public AzureContainersResourceProvider() {
this(System.getenv());
}
// Visible for testing
AzureContainersResourceProvider(Map<String, String> env) {
this.env = env;
}
@Override
public Resource createResource(ConfigProperties config) {
return Resource.create(getAttributes());
}
public Attributes getAttributes() {
AzureEnvVarPlatform detect = AzureEnvVarPlatform.detect(env);
if (detect != AzureEnvVarPlatform.CONTAINER_APP) {
return Attributes.empty();
}
AttributesBuilder builder =
AzureVmResourceProvider.azureAttributeBuilder("azure_container_apps");
AzureEnvVarPlatform.addAttributesFromEnv(ENV_VAR_MAPPING, env, builder);
return builder.build();
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.Map;
public enum AzureEnvVarPlatform {
APP_SERVICE,
FUNCTIONS,
CONTAINER_APP,
NONE;
public static AzureEnvVarPlatform detect(Map<String, String> env) {
String appName = env.get(AzureContainersResourceProvider.CONTAINER_APP_NAME);
if (appName != null) {
return CONTAINER_APP;
}
String name = env.get(AzureAppServiceResourceProvider.WEBSITE_SITE_NAME);
if (name == null) {
return NONE;
}
if (env.get(AzureFunctionsResourceProvider.FUNCTIONS_VERSION) != null) {
return FUNCTIONS;
}
return APP_SERVICE;
}
static void addAttributesFromEnv(
Map<AttributeKey<String>, String> mapping,
Map<String, String> env,
AttributesBuilder builder) {
mapping.forEach(
(key, value) -> {
String envValue = env.get(value);
if (envValue != null) {
builder.put(key, envValue);
}
});
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_REGION;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CloudPlatformIncubatingValues.AZURE_FUNCTIONS;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.FAAS_INSTANCE;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.FAAS_MAX_MEMORY;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.FAAS_NAME;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.FAAS_VERSION;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import java.util.HashMap;
import java.util.Map;
public class AzureFunctionsResourceProvider extends CloudResourceProvider {
static final String FUNCTIONS_VERSION = "FUNCTIONS_EXTENSION_VERSION";
private static final String FUNCTIONS_MEM_LIMIT = "WEBSITE_MEMORY_LIMIT_MB";
private static final Map<AttributeKey<String>, String> ENV_VAR_MAPPING = new HashMap<>();
static {
ENV_VAR_MAPPING.put(CLOUD_REGION, AzureAppServiceResourceProvider.REGION_NAME);
ENV_VAR_MAPPING.put(FAAS_NAME, AzureAppServiceResourceProvider.WEBSITE_SITE_NAME);
ENV_VAR_MAPPING.put(FAAS_VERSION, FUNCTIONS_VERSION);
ENV_VAR_MAPPING.put(FAAS_INSTANCE, AzureAppServiceResourceProvider.WEBSITE_INSTANCE_ID);
}
private final Map<String, String> env;
// SPI
public AzureFunctionsResourceProvider() {
this(System.getenv());
}
// Visible for testing
AzureFunctionsResourceProvider(Map<String, String> env) {
this.env = env;
}
@Override
public Resource createResource(ConfigProperties config) {
return Resource.create(getAttributes());
}
public Attributes getAttributes() {
AzureEnvVarPlatform detect = AzureEnvVarPlatform.detect(env);
if (detect != AzureEnvVarPlatform.FUNCTIONS) {
return Attributes.empty();
}
AttributesBuilder builder = AzureVmResourceProvider.azureAttributeBuilder(AZURE_FUNCTIONS);
String limit = env.get(FUNCTIONS_MEM_LIMIT);
if (limit != null) {
builder.put(FAAS_MAX_MEMORY, Long.parseLong(limit));
}
AzureEnvVarPlatform.addAttributesFromEnv(ENV_VAR_MAPPING, env, builder);
return builder.build();
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import com.fasterxml.jackson.core.JsonFactory;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class AzureMetadataService {
static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final URL METADATA_URL;
static {
try {
METADATA_URL = new URL("http://169.254.169.254/metadata/instance?api-version=2021-02-01");
} catch (MalformedURLException e) {
throw new IllegalStateException(e);
}
}
private AzureMetadataService() {}
private static final Duration TIMEOUT = Duration.ofSeconds(1);
private static final Logger logger = Logger.getLogger(AzureMetadataService.class.getName());
static Supplier<Optional<String>> defaultClient() {
return () -> fetchMetadata(METADATA_URL);
}
// visible for testing
static Optional<String> fetchMetadata(URL url) {
OkHttpClient client =
new OkHttpClient.Builder()
.callTimeout(TIMEOUT)
.connectTimeout(TIMEOUT)
.readTimeout(TIMEOUT)
.build();
Request request = new Request.Builder().url(url).get().addHeader("Metadata", "true").build();
try (Response response = client.newCall(request).execute()) {
int responseCode = response.code();
if (responseCode != 200) {
logger.log(
Level.FINE,
"Error response from "
+ url
+ " code ("
+ responseCode
+ ") text "
+ response.message());
return Optional.empty();
}
return Optional.of(Objects.requireNonNull(response.body()).string());
} catch (IOException e) {
logger.log(Level.FINE, "Failed to fetch Azure VM metadata", e);
return Optional.empty();
}
}
}

View File

@ -0,0 +1,165 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_PROVIDER;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_REGION;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_RESOURCE_ID;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CloudPlatformIncubatingValues.AZURE_VM;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CloudProviderIncubatingValues.AZURE;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.HOST_ID;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.HOST_NAME;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.HOST_TYPE;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.OS_TYPE;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.OS_VERSION;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jetbrains.annotations.NotNull;
public class AzureVmResourceProvider extends CloudResourceProvider {
static class Entry {
final AttributeKey<String> key;
final Function<String, String> transform;
Entry(AttributeKey<String> key) {
this(key, Function.identity());
}
Entry(AttributeKey<String> key, Function<String, String> transform) {
this.key = key;
this.transform = transform;
}
}
private static final Map<String, Entry> COMPUTE_MAPPING = new HashMap<>();
static {
COMPUTE_MAPPING.put("location", new Entry(CLOUD_REGION));
COMPUTE_MAPPING.put("resourceId", new Entry(CLOUD_RESOURCE_ID));
COMPUTE_MAPPING.put("vmId", new Entry(HOST_ID));
COMPUTE_MAPPING.put("name", new Entry(HOST_NAME));
COMPUTE_MAPPING.put("vmSize", new Entry(HOST_TYPE));
COMPUTE_MAPPING.put("osType", new Entry(OS_TYPE));
COMPUTE_MAPPING.put("version", new Entry(OS_VERSION));
COMPUTE_MAPPING.put(
"vmScaleSetName", new Entry(AttributeKey.stringKey("azure.vm.scaleset.name")));
COMPUTE_MAPPING.put("sku", new Entry(AttributeKey.stringKey("azure.vm.sku")));
}
private static final Logger logger = Logger.getLogger(AzureVmResourceProvider.class.getName());
private final Supplier<Optional<String>> client;
// SPI
public AzureVmResourceProvider() {
this(AzureMetadataService.defaultClient());
}
// visible for testing
AzureVmResourceProvider(Supplier<Optional<String>> client) {
this.client = client;
}
@Override
public int order() {
// run after the fast cloud resource providers that only check environment variables
// and after the AKS provider
return 100;
}
@Override
public Resource createResource(ConfigProperties config) {
return client
.get()
.map(body -> parseMetadata(body, COMPUTE_MAPPING, AZURE_VM))
.orElse(Resource.empty());
}
static Resource parseMetadata(String body, Map<String, Entry> computeMapping, String platform) {
AttributesBuilder builder = azureAttributeBuilder(platform);
try (JsonParser parser = AzureMetadataService.JSON_FACTORY.createParser(body)) {
parser.nextToken();
parseResponse(parser, builder, computeMapping);
} catch (IOException e) {
logger.log(Level.FINE, "Can't get Azure VM metadata", e);
}
return Resource.create(builder.build());
}
@NotNull
static AttributesBuilder azureAttributeBuilder(String platform) {
AttributesBuilder builder = Attributes.builder();
builder.put(CLOUD_PROVIDER, AZURE);
builder.put(CLOUD_PLATFORM, platform);
return builder;
}
static void parseResponse(
JsonParser parser, AttributesBuilder builder, Map<String, Entry> computeMapping)
throws IOException {
if (!parser.isExpectedStartObjectToken()) {
logger.log(Level.FINE, "Couldn't parse ECS metadata, invalid JSON");
return;
}
consumeJson(
parser,
(name, value) -> {
try {
if (name.equals("compute")) {
consumeCompute(parser, builder, computeMapping);
} else {
parser.skipChildren();
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
}
private static void consumeCompute(
JsonParser parser, AttributesBuilder builder, Map<String, Entry> computeMapping)
throws IOException {
consumeJson(
parser,
(computeName, computeValue) -> {
Entry entry = computeMapping.get(computeName);
if (entry != null) {
builder.put(entry.key, entry.transform.apply(computeValue));
} else {
try {
parser.skipChildren();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
});
}
private static void consumeJson(JsonParser parser, BiConsumer<String, String> consumer)
throws IOException {
while (parser.nextToken() != JsonToken.END_OBJECT) {
consumer.accept(parser.currentName(), parser.nextTextValue());
}
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.CLOUD_PROVIDER;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
public abstract class CloudResourceProvider implements ConditionalResourceProvider {
@Override
public final boolean shouldApply(ConfigProperties config, Resource existing) {
return existing.getAttribute(CLOUD_PROVIDER) == null;
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import io.opentelemetry.api.common.AttributeKey;
// copied from opentelemetry-semconv-incubating
final class IncubatingAttributes {
// service attributes
public static final AttributeKey<String> SERVICE_INSTANCE_ID =
AttributeKey.stringKey("service.instance.id");
// cloud attributes
public static final AttributeKey<String> CLOUD_PLATFORM =
AttributeKey.stringKey("cloud.platform");
public static final AttributeKey<String> CLOUD_PROVIDER =
AttributeKey.stringKey("cloud.provider");
public static final AttributeKey<String> CLOUD_REGION = AttributeKey.stringKey("cloud.region");
public static final AttributeKey<String> CLOUD_RESOURCE_ID =
AttributeKey.stringKey("cloud.resource_id");
public static final class CloudPlatformIncubatingValues {
public static final String AZURE_VM = "azure_vm";
public static final String AZURE_AKS = "azure_aks";
public static final String AZURE_FUNCTIONS = "azure_functions";
public static final String AZURE_APP_SERVICE = "azure_app_service";
private CloudPlatformIncubatingValues() {}
}
public static final class CloudProviderIncubatingValues {
public static final String AZURE = "azure";
private CloudProviderIncubatingValues() {}
}
// deployment attributes
public static final AttributeKey<String> DEPLOYMENT_ENVIRONMENT_NAME =
AttributeKey.stringKey("deployment.environment.name");
// host attributes
public static final AttributeKey<String> HOST_ID = AttributeKey.stringKey("host.id");
public static final AttributeKey<String> HOST_NAME = AttributeKey.stringKey("host.name");
public static final AttributeKey<String> HOST_TYPE = AttributeKey.stringKey("host.type");
// faas attributes
public static final AttributeKey<String> FAAS_INSTANCE = AttributeKey.stringKey("faas.instance");
public static final AttributeKey<Long> FAAS_MAX_MEMORY = AttributeKey.longKey("faas.max_memory");
public static final AttributeKey<String> FAAS_NAME = AttributeKey.stringKey("faas.name");
public static final AttributeKey<String> FAAS_VERSION = AttributeKey.stringKey("faas.version");
// host attributes
static final AttributeKey<String> K8S_CLUSTER_NAME = AttributeKey.stringKey("k8s.cluster.name");
// OS attributes
public static final AttributeKey<String> OS_TYPE = AttributeKey.stringKey("os.type");
public static final AttributeKey<String> OS_VERSION = AttributeKey.stringKey("os.version");
private IncubatingAttributes() {}
}

View File

@ -0,0 +1,3 @@
io.opentelemetry.contrib.azure.resource.AzureAppServiceResourceProvider
io.opentelemetry.contrib.azure.resource.AzureFunctionsResourceProvider
io.opentelemetry.contrib.azure.resource.AzureVmResourceProvider

View File

@ -0,0 +1,63 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
import io.opentelemetry.semconv.incubating.K8sIncubatingAttributes;
import java.util.Collections;
import java.util.Optional;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
class AzureAksResourceProviderTest extends MetadataBasedResourceProviderTest {
@NotNull
@Override
protected ResourceProvider getResourceProvider(Supplier<Optional<String>> client) {
return new AzureAksResourceProvider(
client,
Collections.singletonMap(AzureAksResourceProvider.KUBERNETES_SERVICE_HOST, "localhost"));
}
@Override
protected String getPlatform() {
return CloudIncubatingAttributes.CloudPlatformIncubatingValues.AZURE_AKS;
}
@Override
protected void assertDefaultAttributes(AttributesAssert attributesAssert) {
attributesAssert
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(
CLOUD_PLATFORM, CloudIncubatingAttributes.CloudPlatformIncubatingValues.AZURE_AKS)
.containsEntry(K8sIncubatingAttributes.K8S_CLUSTER_NAME, "macikgo-test-may-23");
}
@Test
void notOnK8s() {
AzureAksResourceProvider provider =
new AzureAksResourceProvider(() -> Optional.of(okResponse()), Collections.emptyMap());
Attributes attributes = provider.createResource(null).getAttributes();
OpenTelemetryAssertions.assertThat(attributes).isEmpty();
}
@Test
void parseClusterName() {
String clusterName =
AzureAksResourceProvider.parseClusterName(
"mc_macikgo-test-may-23_macikgo-test-may-23_eastus");
assertThat(clusterName).isEqualTo("macikgo-test-may-23");
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_REGION;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_RESOURCE_ID;
import static io.opentelemetry.semconv.incubating.DeploymentIncubatingAttributes.DEPLOYMENT_ENVIRONMENT_NAME;
import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_ID;
import static io.opentelemetry.semconv.incubating.ServiceIncubatingAttributes.SERVICE_INSTANCE_ID;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
class AzureAppServiceResourceProviderTest {
private static final String TEST_WEBSITE_SITE_NAME = "TEST_WEBSITE_SITE_NAME";
private static final String TEST_REGION_NAME = "TEST_REGION_NAME";
private static final String TEST_WEBSITE_SLOT_NAME = "TEST_WEBSITE_SLOT_NAME";
private static final String TEST_WEBSITE_HOSTNAME = "TEST_WEBSITE_HOSTNAME";
private static final String TEST_WEBSITE_INSTANCE_ID = "TEST_WEBSITE_INSTANCE_ID";
private static final String TEST_WEBSITE_HOME_STAMPNAME = "TEST_WEBSITE_HOME_STAMPNAME";
private static final String TEST_WEBSITE_RESOURCE_GROUP = "TEST_WEBSITE_RESOURCE_GROUP";
private static final String TEST_WEBSITE_OWNER_NAME = "TEST_WEBSITE_OWNER_NAME";
private static final ImmutableMap<String, String> DEFAULT_ENV_VARS =
ImmutableMap.of(
"WEBSITE_SITE_NAME", TEST_WEBSITE_SITE_NAME,
"REGION_NAME", TEST_REGION_NAME,
"WEBSITE_SLOT_NAME", TEST_WEBSITE_SLOT_NAME,
"WEBSITE_HOSTNAME", TEST_WEBSITE_HOSTNAME,
"WEBSITE_INSTANCE_ID", TEST_WEBSITE_INSTANCE_ID,
"WEBSITE_HOME_STAMPNAME", TEST_WEBSITE_HOME_STAMPNAME,
"WEBSITE_RESOURCE_GROUP", TEST_WEBSITE_RESOURCE_GROUP,
"WEBSITE_OWNER_NAME", TEST_WEBSITE_OWNER_NAME);
@Test
void defaultValues() {
createResource(DEFAULT_ENV_VARS)
.containsEntry(SERVICE_NAME, TEST_WEBSITE_SITE_NAME)
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(CLOUD_PLATFORM, "azure_app_service")
.containsEntry(
CLOUD_RESOURCE_ID,
"/subscriptions/TEST_WEBSITE_OWNER_NAME/resourceGroups/TEST_WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/TEST_WEBSITE_SITE_NAME")
.containsEntry(CLOUD_REGION, TEST_REGION_NAME)
.containsEntry(DEPLOYMENT_ENVIRONMENT_NAME, TEST_WEBSITE_SLOT_NAME)
.containsEntry(HOST_ID, TEST_WEBSITE_HOSTNAME)
.containsEntry(SERVICE_INSTANCE_ID, TEST_WEBSITE_INSTANCE_ID)
.containsEntry(
AzureAppServiceResourceProvider.AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE,
TEST_WEBSITE_HOME_STAMPNAME);
}
@Test
void subscriptionFromOwner() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.put("WEBSITE_OWNER_NAME", "foo+bar");
createResource(map)
.containsEntry(
CLOUD_RESOURCE_ID,
"/subscriptions/foo/resourceGroups/TEST_WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/TEST_WEBSITE_SITE_NAME");
}
@Test
void noResourceId() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.remove("WEBSITE_RESOURCE_GROUP");
createResource(map).doesNotContainKey(CLOUD_RESOURCE_ID);
}
@Test
void noWebsite() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.remove("WEBSITE_SITE_NAME");
createResource(map).isEmpty();
}
@Test
void isFunction() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.put("FUNCTIONS_EXTENSION_VERSION", "3.0");
createResource(map).isEmpty();
}
@NotNull
private static AttributesAssert createResource(Map<String, String> map) {
return OpenTelemetryAssertions.assertThat(
new AzureAppServiceResourceProvider(map).createResource(null).getAttributes());
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_VERSION;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import static io.opentelemetry.semconv.incubating.ServiceIncubatingAttributes.SERVICE_INSTANCE_ID;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
class AzureContainersResourceProviderTest {
private static final String TEST_APP_NAME = "TEST_APP_NAME";
private static final String TEST_REPLICA_NAME = "TEST_REPLICA_NAME";
private static final String TEST_REVISION = "TEST_REVISION";
private static final ImmutableMap<String, String> DEFAULT_ENV_VARS =
ImmutableMap.of(
"CONTAINER_APP_NAME", TEST_APP_NAME,
"CONTAINER_APP_REPLICA_NAME", TEST_REPLICA_NAME,
"CONTAINER_APP_REVISION", TEST_REVISION);
@Test
void defaultValues() {
createResource(DEFAULT_ENV_VARS)
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(CLOUD_PLATFORM, "azure_container_apps")
.containsEntry(SERVICE_NAME, TEST_APP_NAME)
.containsEntry(SERVICE_INSTANCE_ID, TEST_REPLICA_NAME)
.containsEntry(SERVICE_VERSION, TEST_REVISION);
}
@Test
void isNotContainer() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.remove("CONTAINER_APP_NAME");
createResource(map).isEmpty();
}
@NotNull
private static AttributesAssert createResource(Map<String, String> map) {
return OpenTelemetryAssertions.assertThat(
new AzureContainersResourceProvider(map).createResource(null).getAttributes());
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import static io.opentelemetry.semconv.incubating.FaasIncubatingAttributes.FAAS_INSTANCE;
import static io.opentelemetry.semconv.incubating.FaasIncubatingAttributes.FAAS_MAX_MEMORY;
import static io.opentelemetry.semconv.incubating.FaasIncubatingAttributes.FAAS_NAME;
import static io.opentelemetry.semconv.incubating.FaasIncubatingAttributes.FAAS_VERSION;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
class AzureFunctionsResourceProviderTest {
private static final String TEST_WEBSITE_SITE_NAME = "TEST_WEBSITE_SITE_NAME";
private static final String TEST_REGION_NAME = "TEST_REGION_NAME";
private static final String TEST_FUNCTION_VERSION = "TEST_VERSION";
private static final String TEST_WEBSITE_INSTANCE_ID = "TEST_WEBSITE_INSTANCE_ID";
private static final String TEST_MEM_LIMIT = "1024";
private static final ImmutableMap<String, String> DEFAULT_ENV_VARS =
ImmutableMap.of(
"WEBSITE_SITE_NAME", TEST_WEBSITE_SITE_NAME,
"REGION_NAME", TEST_REGION_NAME,
"WEBSITE_MEMORY_LIMIT_MB", TEST_MEM_LIMIT,
"FUNCTIONS_EXTENSION_VERSION", TEST_FUNCTION_VERSION,
"WEBSITE_INSTANCE_ID", TEST_WEBSITE_INSTANCE_ID);
@Test
void defaultValues() {
createResource(DEFAULT_ENV_VARS)
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(CLOUD_PLATFORM, "azure_functions")
.containsEntry(FAAS_NAME, TEST_WEBSITE_SITE_NAME)
.containsEntry(FAAS_VERSION, TEST_FUNCTION_VERSION)
.containsEntry(FAAS_INSTANCE, TEST_WEBSITE_INSTANCE_ID)
.containsEntry(FAAS_MAX_MEMORY, Long.parseLong(TEST_MEM_LIMIT));
}
@Test
void isNotFunction() {
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
map.remove("FUNCTIONS_EXTENSION_VERSION");
createResource(map).isEmpty();
}
@NotNull
private static AttributesAssert createResource(Map<String, String> map) {
return OpenTelemetryAssertions.assertThat(
new AzureFunctionsResourceProvider(map).createResource(null).getAttributes());
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_REGION;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_RESOURCE_ID;
import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_ID;
import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_NAME;
import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_TYPE;
import static io.opentelemetry.semconv.incubating.OsIncubatingAttributes.OS_TYPE;
import static io.opentelemetry.semconv.incubating.OsIncubatingAttributes.OS_VERSION;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
import java.util.Optional;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
class AzureVmResourceProviderTest extends MetadataBasedResourceProviderTest {
@NotNull
@Override
protected ResourceProvider getResourceProvider(Supplier<Optional<String>> client) {
return new AzureVmResourceProvider(client);
}
@Override
protected String getPlatform() {
return CloudIncubatingAttributes.CloudPlatformIncubatingValues.AZURE_VM;
}
@Override
protected void assertDefaultAttributes(AttributesAssert attributesAssert) {
attributesAssert
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(
CLOUD_PLATFORM, CloudIncubatingAttributes.CloudPlatformIncubatingValues.AZURE_VM)
.containsEntry(CLOUD_REGION, "westus")
.containsEntry(
CLOUD_RESOURCE_ID,
"/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test-may-23/providers/Microsoft.Compute/virtualMachines/examplevmname")
.containsEntry(HOST_ID, "02aab8a4-74ef-476e-8182-f6d2ba4166a6")
.containsEntry(HOST_NAME, "examplevmname")
.containsEntry(HOST_TYPE, "Standard_A3")
.containsEntry(OS_TYPE, "Linux")
.containsEntry(OS_VERSION, "15.05.22")
.containsEntry("azure.vm.scaleset.name", "crpteste9vflji9")
.containsEntry("azure.vm.sku", "18.04-LTS");
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.azure.resource;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PLATFORM;
import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_PROVIDER;
import com.google.common.io.CharStreams;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.common.MediaType;
import com.linecorp.armeria.testing.junit5.server.mock.MockWebServerExtension;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
public abstract class MetadataBasedResourceProviderTest {
@RegisterExtension
public static final MockWebServerExtension server = new MockWebServerExtension();
@NotNull
private AttributesAssert mockServerResponse() {
return createResource(
() -> {
try {
return AzureMetadataService.fetchMetadata(server.httpUri().toURL());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
});
}
@NotNull
private AttributesAssert createResource(Supplier<Optional<String>> client) {
Resource resource = getResourceProvider(client).createResource(null);
return OpenTelemetryAssertions.assertThat(resource.getAttributes());
}
@NotNull
protected abstract ResourceProvider getResourceProvider(Supplier<Optional<String>> client);
private void assertOnlyProvider(AttributesAssert attributesAssert) {
attributesAssert
.hasSize(2)
.containsEntry(CLOUD_PROVIDER, "azure")
.containsEntry(CLOUD_PLATFORM, getPlatform());
}
protected abstract String getPlatform();
protected abstract void assertDefaultAttributes(AttributesAssert attributesAssert);
protected static String okResponse() {
try {
return CharStreams.toString(
new InputStreamReader(
Objects.requireNonNull(
AzureVmResourceProviderTest.class
.getClassLoader()
.getResourceAsStream("response.json")),
StandardCharsets.UTF_8));
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Test
public void successFromFile() {
assertDefaultAttributes(createResource(() -> Optional.of(okResponse())));
}
@Test
public void successFromMockServer() {
server.enqueue(HttpResponse.of(MediaType.JSON, okResponse()));
assertDefaultAttributes(mockServerResponse());
}
@Test
public void responseNotFound() {
server.enqueue(HttpResponse.of(HttpStatus.NOT_FOUND));
mockServerResponse().isEmpty();
}
@Test
public void responseEmpty() {
server.enqueue(HttpResponse.of(""));
assertOnlyProvider(mockServerResponse());
}
@Test
public void responseEmptyJson() {
server.enqueue(HttpResponse.of("{}"));
assertOnlyProvider(mockServerResponse());
}
}

View File

@ -0,0 +1,159 @@
{
"compute": {
"azEnvironment": "AZUREPUBLICCLOUD",
"additionalCapabilities": {
"hibernationEnabled": "true"
},
"hostGroup": {
"id": "testHostGroupId"
},
"extendedLocation": {
"type": "edgeZone",
"name": "microsoftlosangeles"
},
"evictionPolicy": "",
"isHostCompatibilityLayerVm": "true",
"licenseType": "",
"location": "westus",
"name": "examplevmname",
"offer": "UbuntuServer",
"osProfile": {
"adminUsername": "admin",
"computerName": "examplevmname",
"disablePasswordAuthentication": "true"
},
"osType": "Linux",
"placementGroupId": "f67c14ab-e92c-408c-ae2d-da15866ec79a",
"plan": {
"name": "planName",
"product": "planProduct",
"publisher": "planPublisher"
},
"platformFaultDomain": "36",
"platformSubFaultDomain": "",
"platformUpdateDomain": "42",
"priority": "Regular",
"publicKeys": [{
"keyData": "ssh-rsa 0",
"path": "/home/user/.ssh/authorized_keys0"
},
{
"keyData": "ssh-rsa 1",
"path": "/home/user/.ssh/authorized_keys1"
}
],
"publisher": "Canonical",
"resourceGroupName": "macikgo-test-may-23",
"resourceId": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test-may-23/providers/Microsoft.Compute/virtualMachines/examplevmname",
"securityProfile": {
"secureBootEnabled": "true",
"virtualTpmEnabled": "false",
"encryptionAtHost": "true",
"securityType": "TrustedLaunch"
},
"sku": "18.04-LTS",
"storageProfile": {
"dataDisks": [{
"bytesPerSecondThrottle": "979202048",
"caching": "None",
"createOption": "Empty",
"diskCapacityBytes": "274877906944",
"diskSizeGB": "1024",
"image": {
"uri": ""
},
"isSharedDisk": "false",
"isUltraDisk": "true",
"lun": "0",
"managedDisk": {
"id": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test-may-23/providers/Microsoft.Compute/disks/exampledatadiskname",
"storageAccountType": "StandardSSD_LRS"
},
"name": "exampledatadiskname",
"opsPerSecondThrottle": "65280",
"vhd": {
"uri": ""
},
"writeAcceleratorEnabled": "false"
}],
"imageReference": {
"id": "",
"offer": "UbuntuServer",
"publisher": "Canonical",
"sku": "16.04.0-LTS",
"version": "latest",
"communityGalleryImageId": "/CommunityGalleries/testgallery/Images/1804Gen2/Versions/latest",
"sharedGalleryImageId": "/SharedGalleries/1P/Images/gen2/Versions/latest",
"exactVersion": "1.1686127202.30113"
},
"osDisk": {
"caching": "ReadWrite",
"createOption": "FromImage",
"diskSizeGB": "30",
"diffDiskSettings": {
"option": "Local"
},
"encryptionSettings": {
"enabled": "false",
"diskEncryptionKey": {
"sourceVault": {
"id": "/subscriptions/test-source-guid/resourceGroups/testrg/providers/Microsoft.KeyVault/vaults/test-kv"
},
"secretUrl": "https://test-disk.vault.azure.net/secrets/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
},
"keyEncryptionKey": {
"sourceVault": {
"id": "/subscriptions/test-key-guid/resourceGroups/testrg/providers/Microsoft.KeyVault/vaults/test-kv"
},
"keyUrl": "https://test-key.vault.azure.net/secrets/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
}
},
"image": {
"uri": ""
},
"managedDisk": {
"id": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test-may-23/providers/Microsoft.Compute/disks/exampleosdiskname",
"storageAccountType": "StandardSSD_LRS"
},
"name": "exampleosdiskname",
"osType": "Linux",
"vhd": {
"uri": ""
},
"writeAcceleratorEnabled": "false"
},
"resourceDisk": {
"size": "4096"
}
},
"subscriptionId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"tags": "baz:bash;foo:bar",
"version": "15.05.22",
"virtualMachineScaleSet": {
"id": "/subscriptions/xxxxxxxx-xxxxx-xxx-xxx-xxxx/resourceGroups/resource-group-name/providers/Microsoft.Compute/virtualMachineScaleSets/virtual-machine-scale-set-name"
},
"vmId": "02aab8a4-74ef-476e-8182-f6d2ba4166a6",
"vmScaleSetName": "crpteste9vflji9",
"vmSize": "Standard_A3",
"zone": ""
},
"network": {
"interface": [{
"ipv4": {
"ipAddress": [{
"privateIpAddress": "10.144.133.132",
"publicIpAddress": ""
}],
"subnet": [{
"address": "10.144.133.128",
"prefix": "26"
}]
},
"ipv6": {
"ipAddress": [
]
},
"macAddress": "0011AAFFBB22"
}]
}
}

View File

@ -31,6 +31,7 @@ include(":all")
include(":aws-resources")
include(":aws-xray")
include(":aws-xray-propagator")
include(":azure-resources")
include(":baggage-processor")
include(":compressors:compressor-zstd")
include(":consistent-sampling")