diff --git a/azureDatabaseUtils/src/main/resources/application.yml b/azureDatabaseUtils/src/main/resources/application.yml index 9783c283bb..38b90b3905 100644 --- a/azureDatabaseUtils/src/main/resources/application.yml +++ b/azureDatabaseUtils/src/main/resources/application.yml @@ -1,8 +1,13 @@ +azureEnvironmentConfig: + dbHostNames: + AzureUSGovernmentCloud: ${DB_SERVER_NAME}.postgres.database.usgovcloudapi.net + AzureCloud: ${DB_SERVER_NAME}.postgres.database.azure.com + env: db: - host: ${DB_SERVER_NAME}.postgres.database.azure.com:5432 - url: ${DB_SERVER_NAME}.postgres.database.azure.com port: 5432 + host: ${azureEnvironmentConfig.dbHostNames.${AZURE_ENVIRONMENT:AzureCloud}}:5432 + url: ${azureEnvironmentConfig.dbHostNames.${AZURE_ENVIRONMENT:AzureCloud}} user: ${ADMIN_DB_USER_NAME} connectToDatabase: ${CONNECT_TO_DATABASE:postgres} params: @@ -16,6 +21,7 @@ env: blobContainerName: ${BLOB_CONTAINER_NAME} blobContainerUrlAuthenticated: ${BLOB_CONTAINER_URL_AUTHENTICATED} encryptionKey: ${ENCRYPTION_KEY} + azureEnvironment: ${AZURE_ENVIRONMENT} spring: diff --git a/service/dependencies.gradle b/service/dependencies.gradle index f502dac829..a89184c653 100644 --- a/service/dependencies.gradle +++ b/service/dependencies.gradle @@ -44,8 +44,8 @@ dependencies { implementation group: 'bio.terra', name: 'terra-cloud-resource-lib', version: "1.2.31-SNAPSHOT" // Terra Landing Zone Service - implementation ('bio.terra:terra-landing-zone-service:0.0.362-SNAPSHOT') - implementation ('bio.terra:landing-zone-service-client:0.0.362-SNAPSHOT') + implementation ('bio.terra:terra-landing-zone-service:0.0.367-SNAPSHOT') + implementation ('bio.terra:landing-zone-service-client:0.0.367-SNAPSHOT') // Storage transfer service implementation group: 'com.google.apis', name: 'google-api-services-storagetransfer', version: 'v1-rev20230831-2.0.0' diff --git a/service/src/main/java/bio/terra/workspace/app/configuration/external/AzureConfiguration.java b/service/src/main/java/bio/terra/workspace/app/configuration/external/AzureConfiguration.java index ca19040c1f..12c9163ebc 100644 --- a/service/src/main/java/bio/terra/workspace/app/configuration/external/AzureConfiguration.java +++ b/service/src/main/java/bio/terra/workspace/app/configuration/external/AzureConfiguration.java @@ -1,5 +1,6 @@ package bio.terra.workspace.app.configuration.external; +import com.azure.core.management.AzureEnvironment; import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -25,8 +26,24 @@ public class AzureConfiguration { private String wsmServiceManagedIdentity; private String azureEnvironment; - public String getAzureEnvironment() { - return azureEnvironment; + public AzureEnvironment getAzureEnvironment() { + return getAzureEnvironmentFromString(azureEnvironment); + } + + public AzureEnvironment getAzureEnvironmentFromString(String azureEnvironment) { + try { + return switch (azureEnvironment) { + case "AzureUSGovernmentCloud" -> AzureEnvironment.AZURE_US_GOVERNMENT; + case "AzureCloud" -> AzureEnvironment.AZURE; + default -> AzureEnvironment.AZURE; + }; + } catch (IllegalArgumentException e) { + return AzureEnvironment.AZURE; + } + } + + public String getAzureEnvironmentConfigString() { + return this.azureEnvironment; } public void setAzureEnvironment(String azureEnvironment) { diff --git a/service/src/main/java/bio/terra/workspace/app/configuration/external/PolicyServiceConfiguration.java b/service/src/main/java/bio/terra/workspace/app/configuration/external/PolicyServiceConfiguration.java index 1b8bb48f0f..d01a12b90e 100644 --- a/service/src/main/java/bio/terra/workspace/app/configuration/external/PolicyServiceConfiguration.java +++ b/service/src/main/java/bio/terra/workspace/app/configuration/external/PolicyServiceConfiguration.java @@ -54,6 +54,7 @@ public String getAccessToken() { features.isAzureControlPlaneEnabled(), POLICY_SERVICE_ACCOUNT_SCOPES, Arrays.asList(azureConfiguration.getAuthTokenScope()), + azureConfiguration.getAzureEnvironment(), clientCredentialFilePath); } catch (IOException e) { throw new InternalServerErrorException("Internal server error retrieving WSM credentials", e); diff --git a/service/src/main/java/bio/terra/workspace/common/utils/AuthUtils.java b/service/src/main/java/bio/terra/workspace/common/utils/AuthUtils.java index ef0bf0f5cb..ea34ad5c3f 100644 --- a/service/src/main/java/bio/terra/workspace/common/utils/AuthUtils.java +++ b/service/src/main/java/bio/terra/workspace/common/utils/AuthUtils.java @@ -2,6 +2,7 @@ import com.azure.core.credential.TokenCredential; import com.azure.core.credential.TokenRequestContext; +import com.azure.core.management.AzureEnvironment; import com.azure.identity.DefaultAzureCredentialBuilder; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; @@ -16,10 +17,14 @@ public static String getAccessToken( boolean isAzureControlPlaneEnabled, Collection gcpScopes, Collection azureScopes, + AzureEnvironment azureEnvironment, String credentialsPath) throws IOException { if (isAzureControlPlaneEnabled) { - TokenCredential credential = new DefaultAzureCredentialBuilder().build(); + TokenCredential credential = + new DefaultAzureCredentialBuilder() + .authorityHost(azureEnvironment.getActiveDirectoryEndpoint()) + .build(); // The Microsoft Authentication Library (MSAL) currently specifies offline_access, openid, // profile, and email by default in authorization and token requests. com.azure.core.credential.AccessToken token = diff --git a/service/src/main/java/bio/terra/workspace/service/crl/CrlService.java b/service/src/main/java/bio/terra/workspace/service/crl/CrlService.java index 06692d5555..9272e49f75 100644 --- a/service/src/main/java/bio/terra/workspace/service/crl/CrlService.java +++ b/service/src/main/java/bio/terra/workspace/service/crl/CrlService.java @@ -583,19 +583,11 @@ private AzureProfile getAzureProfile(AzureCloudContext azureCloudContext) { return new AzureProfile( azureCloudContext.getAzureTenantId(), azureCloudContext.getAzureSubscriptionId(), - getAzureEnvironmentFromName(azureConfiguration.getAzureEnvironment())); + azureConfiguration.getAzureEnvironment()); } - public AzureEnvironment getAzureEnvironmentFromName(String envName) { - try { - return switch (envName.toUpperCase()) { - case "AZURE_US_GOVERNMENT" -> AzureEnvironment.AZURE_US_GOVERNMENT; - case "AZURE_CHINA" -> AzureEnvironment.AZURE_CHINA; - default -> AzureEnvironment.AZURE; - }; - } catch (IllegalArgumentException e) { - return AzureEnvironment.AZURE; - } + public AzureEnvironment getAzureEnvironmentFromName(String azureEnvironment) { + return azureConfiguration.getAzureEnvironmentFromString(azureEnvironment); } @VisibleForTesting diff --git a/service/src/main/java/bio/terra/workspace/service/iam/SamService.java b/service/src/main/java/bio/terra/workspace/service/iam/SamService.java index d7551f1518..e7cf3648e6 100644 --- a/service/src/main/java/bio/terra/workspace/service/iam/SamService.java +++ b/service/src/main/java/bio/terra/workspace/service/iam/SamService.java @@ -162,6 +162,7 @@ public String getWsmServiceAccountToken() { features.isAzureControlPlaneEnabled(), SAM_OAUTH_SCOPES, Arrays.asList(azureConfiguration.getAuthTokenScope()), + azureConfiguration.getAzureEnvironment(), null); } catch (IOException e) { throw new InternalServerErrorException("Internal server error retrieving WSM credentials", e); diff --git a/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/AzureStorageAccessService.java b/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/AzureStorageAccessService.java index 3cbdce770b..50d36add0a 100644 --- a/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/AzureStorageAccessService.java +++ b/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/AzureStorageAccessService.java @@ -266,7 +266,7 @@ public AzureSasBundle createAzureStorageContainerSasToken( URLDecoder.decode(sig, StandardCharsets.UTF_8)) .toUpperCase(); - var azureEnv = crlService.getAzureEnvironmentFromName(azureConfiguration.getAzureEnvironment()); + var azureEnv = azureConfiguration.getAzureEnvironment(); logger.info( "SAS token with expiry time of {} generated for user {} [SubjectId={}] on container {} in workspace {} [sha256 = {}] [AzureEnvironment portal = {}]", diff --git a/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/database/AzureDatabaseUtilsRunner.java b/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/database/AzureDatabaseUtilsRunner.java index a105f6d04c..bd68d89d58 100644 --- a/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/database/AzureDatabaseUtilsRunner.java +++ b/service/src/main/java/bio/terra/workspace/service/resource/controlled/cloud/azure/database/AzureDatabaseUtilsRunner.java @@ -79,6 +79,7 @@ public class AzureDatabaseUtilsRunner { public static final String PARAM_CONNECT_TO_DATABASE = "CONNECT_TO_DATABASE"; public static final String PARAM_NEW_DB_USER_NAME = "NEW_DB_USER_NAME"; public static final String PARAM_NEW_DB_USER_OID = "NEW_DB_USER_OID"; + public static final String PARAM_AZURE_ENVIRONMENT = "AZURE_ENVIRONMENT"; // Workflow cloning - TODO: which params can be reused? public static final String PARAM_BLOB_FILE_NAME = "BLOB_FILE_NAME"; @@ -597,6 +598,10 @@ private V1Pod createPodDefinition(UUID workspaceId, String podName, List new IllegalStateException("No shared database admin identity found"))); List envVarsWithCommonArgs = new ArrayList<>(); + envVarsWithCommonArgs.add( + new V1EnvVar() + .name(PARAM_AZURE_ENVIRONMENT) + .value(azureConfig.getAzureEnvironmentConfigString())); envVarsWithCommonArgs.add(new V1EnvVar().name(PARAM_DB_SERVER_NAME).value(dbServerName)); envVarsWithCommonArgs.add(new V1EnvVar().name(PARAM_ADMIN_DB_USER_NAME).value(adminDbUserName)); envVarsWithCommonArgs.addAll(envVars);