Skip to content

Commit

Permalink
GCP Auth extension - allow users to specify quota project ID (#1647)
Browse files Browse the repository at this point in the history
  • Loading branch information
psx95 authored Jan 16, 2025
1 parent c00f094 commit 72dc156
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 40 deletions.
5 changes: 4 additions & 1 deletion gcp-auth-extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ Here is a list of configurable options for the extension:

- `GOOGLE_CLOUD_PROJECT`: Environment variable that represents the Google Cloud Project ID to which the telemetry needs to be exported.
- Can also be configured using `google.cloud.project` system property.
- If this option is not configured, the extension would infer GCP Project ID from the application default credentials. For more information on application default credentials, see [here](https://cloud.google.com/docs/authentication/application-default-credentials).
- This is a required option, the agent configuration will fail if this option is not set.
- `GOOGLE_CLOUD_QUOTA_PROJECT`: Environment variable that represents the Google Cloud Quota Project ID which will be charged for the GCP API usage. To learn more about a *quota project*, see [here](https://cloud.google.com/docs/quotas/quota-project).
- Can also be configured using `google.cloud.quota.project` system property.
- If this option is not configured, the extension will use the Quota Project ID found in the Application Default Credentials (ADC), if available. For more information on application default credentials, see [here](https://cloud.google.com/docs/authentication/application-default-credentials).

## Usage

Expand Down
4 changes: 4 additions & 0 deletions gcp-auth-extension/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
testCompileOnly("com.google.auto.service:auto-service-annotations")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testCompileOnly("org.junit.jupiter:junit-jupiter-params")

testImplementation("io.opentelemetry:opentelemetry-api")
testImplementation("io.opentelemetry:opentelemetry-exporter-otlp")
Expand All @@ -45,6 +46,9 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter:2.7.18")
testImplementation("org.springframework.boot:spring-boot-starter-test:2.7.18")

testAnnotationProcessor("com.google.auto.value:auto-value")
testCompileOnly("com.google.auto.value:auto-value-annotations")

agent("io.opentelemetry.javaagent:opentelemetry-javaagent")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,18 @@ public enum ConfigurableOption {
* Represents the Google Cloud Project ID option. Can be configured using the environment variable
* `GOOGLE_CLOUD_PROJECT` or the system property `google.cloud.project`.
*/
GOOGLE_CLOUD_PROJECT("Google Cloud Project ID");
GOOGLE_CLOUD_PROJECT("Google Cloud Project ID"),

/**
* Represents the Google Cloud Quota Project ID option. Can be configured using the environment
* variable `GOOGLE_CLOUD_QUOTA_PROJECT` or the system property `google.cloud.quota.project`. The
* quota project is the project that is used for quota management and billing for the API usage.
*
* <p>The environment variable name is selected to be consistent with the <a
* href="https://cloud.google.com/docs/quotas/set-quota-project">official GCP client
* libraries</a>.
*/
GOOGLE_CLOUD_QUOTA_PROJECT("Google Cloud Quota Project ID");

private final String userReadableName;
private final String environmentVariableName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ public class GcpAuthAutoConfigurationCustomizerProvider
*/
@Override
public void customize(AutoConfigurationCustomizer autoConfiguration) {
GoogleCredentials credentials;
try {
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
autoConfiguration
.addSpanExporterCustomizer(
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
.addResourceCustomizer(GcpAuthAutoConfigurationCustomizerProvider::customizeResource);
credentials = GoogleCredentials.getApplicationDefault();
} catch (IOException e) {
throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
}
autoConfiguration
.addSpanExporterCustomizer(
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
.addResourceCustomizer(GcpAuthAutoConfigurationCustomizerProvider::customizeResource);
}

@Override
Expand Down Expand Up @@ -100,24 +101,19 @@ private static Map<String, String> getRequiredHeaderMap(GoogleCredentials creden
} catch (IOException e) {
throw new GoogleAuthException(Reason.FAILED_ADC_REFRESH, e);
}
gcpHeaders.put(QUOTA_USER_PROJECT_HEADER, credentials.getQuotaProjectId());
gcpHeaders.put("Authorization", "Bearer " + credentials.getAccessToken().getTokenValue());
String configuredQuotaProjectId =
ConfigurableOption.GOOGLE_CLOUD_QUOTA_PROJECT.getConfiguredValueWithFallback(
credentials::getQuotaProjectId);
if (configuredQuotaProjectId != null && !configuredQuotaProjectId.isEmpty()) {
gcpHeaders.put(QUOTA_USER_PROJECT_HEADER, configuredQuotaProjectId);
}
return gcpHeaders;
}

// Updates the current resource with the attributes required for ingesting OTLP data on GCP.
private static Resource customizeResource(Resource resource, ConfigProperties configProperties) {
String gcpProjectId =
ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValueWithFallback(
() -> {
try {
GoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();
return googleCredentials.getQuotaProjectId();
} catch (IOException e) {
throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
}
});

String gcpProjectId = ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValue();
Resource res =
Resource.create(
Attributes.of(AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY), gcpProjectId));
Expand Down
Loading

0 comments on commit 72dc156

Please sign in to comment.