diff --git a/centaur/src/main/resources/standardTestCases/gcpbatch_papi_v2beta_gcsa.test b/centaur/src/main/resources/standardTestCases/gcpbatch_papi_v2beta_gcsa.test new file mode 100644 index 00000000000..8afb0dc96fc --- /dev/null +++ b/centaur/src/main/resources/standardTestCases/gcpbatch_papi_v2beta_gcsa.test @@ -0,0 +1,17 @@ +name: gcpbatch_papi_v2beta_gcsa +testFormat: WorkflowSuccess +backends: [GCPBATCH-gcsa] + +files { + workflow: papi_v2_gcsa/gcpbatch_papi_v2_gcsa.wdl + options-dir: "Error: BA-6546 The environment variable CROMWELL_BUILD_RESOURCES_DIRECTORY must be set/export pointing to a valid path such as '${YOUR_CROMWELL_DIR}/target/ci/resources'" + options-dir: ${?CROMWELL_BUILD_RESOURCES_DIRECTORY} + options: ${files.options-dir}/papi_v2_gcsa.options.json +} + +metadata { + workflowName: papi_v2_gcsa + status: Succeeded + "outputs.papi_v2_gcsa.email": "cromwell@broad-dsde-cromwell-dev.iam.gserviceaccount.com" + "outputs.papi_v2_gcsa.scopes": "https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/cloudkms https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/monitoring.write https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile" +} diff --git a/centaur/src/main/resources/standardTestCases/papi_v2_gcsa/gcpbatch_papi_v2_gcsa.wdl b/centaur/src/main/resources/standardTestCases/papi_v2_gcsa/gcpbatch_papi_v2_gcsa.wdl new file mode 100644 index 00000000000..03a9d3f4860 --- /dev/null +++ b/centaur/src/main/resources/standardTestCases/papi_v2_gcsa/gcpbatch_papi_v2_gcsa.wdl @@ -0,0 +1,37 @@ +version 1.0 + +workflow papi_v2_gcsa { + call get_token_info + output { + String email = get_token_info.json.email + String scopes = get_token_info.json.scopes + File service_account = get_token_info.service_account + } +} + +# Confirm that even though the service account (SA) specified by the backend configuration creates the pipeline job, +# instead the google compute service account (GCSA) workflow option is the actual account used to run the container. +# https://cloud.google.com/genomics/reference/rest/Shared.Types/Metadata#VirtualMachine.FIELDS.service_account +# https://cromwell.readthedocs.io/en/stable/wf_options/Google/#google-pipelines-api-workflow-options +task get_token_info { + command <<< + apt-get install --assume-yes jq > /dev/null + + curl --fail --silent \ + 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/?recursive=true' \ + -H 'Metadata-Flavor: Google' > service_accounts.json + + cat service_accounts.json | jq --monochrome-output \ + '.default | {email, scopes: .scopes | sort | join(" ")}' + >>> + + runtime { + docker: "gcr.io/google.com/cloudsdktool/cloud-sdk:slim" + backend: "GCPBATCH-gcsa" + } + + output { + Object json = read_json(stdout()) + File service_account = "service_accounts.json" + } +} diff --git a/centaur/src/main/resources/standardTestCases/papi_v2beta_gcsa.test b/centaur/src/main/resources/standardTestCases/papi_v2beta_gcsa.test index c6e01fcf195..27dd29621d7 100644 --- a/centaur/src/main/resources/standardTestCases/papi_v2beta_gcsa.test +++ b/centaur/src/main/resources/standardTestCases/papi_v2beta_gcsa.test @@ -1,6 +1,6 @@ name: papi_v2beta_gcsa testFormat: WorkflowSuccess -backends: [papi-v2-gcsa, GCPBATCH_NEEDS_ALT] +backends: [papi-v2-gcsa, GCPBATCH_ALT] files { workflow: papi_v2_gcsa/papi_v2_gcsa.wdl diff --git a/src/ci/resources/gcp_batch_application.conf b/src/ci/resources/gcp_batch_application.conf index aa80d2aa9a8..003b4eaa077 100644 --- a/src/ci/resources/gcp_batch_application.conf +++ b/src/ci/resources/gcp_batch_application.conf @@ -23,6 +23,12 @@ backend { filesystems.gcs.auth = "requester_pays_service_account" } } + GCPBATCH-gcsa { + actor-factory = "cromwell.backend.google.batch.GcpBatchBackendLifecycleActorFactory" + config { + include "gcp_batch_provider_config.inc.conf" + } + } GCPBATCH-Virtual-Private-Cloud-Labels { actor-factory = "cromwell.backend.google.batch.GcpBatchBackendLifecycleActorFactory" config { diff --git a/src/ci/resources/gcp_batch_shared_application.inc.conf b/src/ci/resources/gcp_batch_shared_application.inc.conf index aab22bce38a..7f063ea034e 100644 --- a/src/ci/resources/gcp_batch_shared_application.inc.conf +++ b/src/ci/resources/gcp_batch_shared_application.inc.conf @@ -109,6 +109,24 @@ backend { # enable running jobs in regions that are different from the region of the GCP Batch to which we send jobs. } + # Have the engine authenticate to docker.io. See BT-141 for more info. + include "dockerhub_provider_config_v2.inc.conf" + } + } + GCPBATCH-gcsa { + actor-factory = "REPLACEME!" + config { + # When importing: Remember to also include an appropriate provider_config.inc.conf here. + + project = "user_error: google_project must be set in workflow options http://cromwell.readthedocs.io/en/develop/wf_options/Google/" + root = "user_error: jes_gcs_root must be set in workflow options http://cromwell.readthedocs.io/en/develop/wf_options/Google/" + genomics.compute-service-account = "user_error: google_compute_service_account must be set in workflow options http://cromwell.readthedocs.io/en/develop/wf_options/Google/" + genomics.auth = "google_compute_service_account" + filesystems.http {} + filesystems.drs.auth = "user_service_account" + filesystems.gcs.auth = "user_service_account" + filesystems.gcs.project = "user_error: user_service_account must be set in workflow options http://cromwell.readthedocs.io/en/develop/wf_options/Google/" + # Have the engine authenticate to docker.io. See BT-141 for more info. include "dockerhub_provider_config_v2.inc.conf" } diff --git a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/actors/GcpBatchAsyncBackendJobExecutionActor.scala b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/actors/GcpBatchAsyncBackendJobExecutionActor.scala index def59339847..034772d53ea 100644 --- a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/actors/GcpBatchAsyncBackendJobExecutionActor.scala +++ b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/actors/GcpBatchAsyncBackendJobExecutionActor.scala @@ -890,8 +890,7 @@ class GcpBatchAsyncBackendJobExecutionActor(override val standardParams: Standar rcFileOutputParameter = rcFileOutput, memoryRetryRCFileOutputParameter = memoryRetryRCFileOutput, logFileOutputParameter = logFileOutput - ), - List.empty + ) ) }) diff --git a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactory.scala b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactory.scala index d2f8242b213..74447376cfc 100644 --- a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactory.scala +++ b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactory.scala @@ -59,8 +59,7 @@ object GcpBatchRequestFactory { detritusInputParameters: DetritusInputParameters, jobInputParameters: List[GcpBatchInput], jobOutputParameters: List[GcpBatchOutput], - detritusOutputParameters: DetritusOutputParameters, - literalInputParameters: List[GcpBatchLiteralInput] + detritusOutputParameters: DetritusOutputParameters ) { lazy val fileInputParameters: List[GcpBatchInput] = jobInputParameters ++ detritusInputParameters.all lazy val fileOutputParameters: List[GcpBatchOutput] = detritusOutputParameters.all ++ jobOutputParameters @@ -94,13 +93,7 @@ object GcpBatchRequestFactory { vpcNetworkAndSubnetworkProjectLabels: Option[VpcAndSubnetworkProjectLabelValues], dockerhubCredentials: (String, String) ) { - def literalInputs = inputOutputParameters.literalInputParameters - - def inputParameters = inputOutputParameters.fileInputParameters - def outputParameters = inputOutputParameters.fileOutputParameters - - def allParameters = inputParameters ++ outputParameters } } diff --git a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactoryImpl.scala b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactoryImpl.scala index 8071acbf9e8..8e9d183558e 100644 --- a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactoryImpl.scala +++ b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GcpBatchRequestFactoryImpl.scala @@ -1,5 +1,9 @@ package cromwell.backend.google.batch.api +import com.google.api.services.bigquery.BigqueryScopes +import com.google.api.services.compute.ComputeScopes +import com.google.api.services.oauth2.Oauth2Scopes +import com.google.api.services.storage.StorageScopes import com.google.cloud.batch.v1.AllocationPolicy._ import com.google.cloud.batch.v1.LogsPolicy.Destination import com.google.cloud.batch.v1.{ @@ -169,7 +173,20 @@ class GcpBatchRequestFactoryImpl()(implicit gcsTransferConfiguration: GcsTransfe // set parent for metadata storage of job information lazy val parent = s"projects/${createParameters.projectId}/locations/${data.gcpBatchParameters.region}" - val gcpSa = ServiceAccount.newBuilder.setEmail(createParameters.computeServiceAccount).build + val scopes = List( + ComputeScopes.COMPUTE, + StorageScopes.DEVSTORAGE_FULL_CONTROL, + GoogleCloudScopes.KmsScope, + // Profile and Email scopes are requirements for interacting with DRS Resolvers + Oauth2Scopes.USERINFO_EMAIL, + Oauth2Scopes.USERINFO_PROFILE, + // Monitoring scope as POC + GoogleCloudScopes.MonitoringWrite, + // Allow read/write with BigQuery + BigqueryScopes.BIGQUERY + ).asJava + + val gcpSa = ServiceAccount.newBuilder.setEmail(createParameters.computeServiceAccount).addAllScopes(scopes).build // make zones path val zones = toZonesPath(runtimeAttributes.zones) diff --git a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GoogleCloudScopes.scala b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GoogleCloudScopes.scala new file mode 100644 index 00000000000..6803db37999 --- /dev/null +++ b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/api/GoogleCloudScopes.scala @@ -0,0 +1,25 @@ +package cromwell.backend.google.batch.api + +/** + * Google cloud scopes that don't have constants defined elsewhere in Google Cloud Java API. + */ +object GoogleCloudScopes { + + /** + * More restricted version of com.google.api.services.cloudkms.v1.CloudKMSScopes.CLOUD_PLATFORM + * Could use that scope to keep things simple, but docs say to use a more restricted scope: + * + * https://cloud.google.com/kms/docs/accessing-the-api#google_compute_engine + * + * For some reason this scope isn't listed as a constant under CloudKMSScopes. + */ + val KmsScope = "https://www.googleapis.com/auth/cloudkms" + + /** + * Scope to write metrics to Stackdriver Monitoring API. + * Used by the monitoring action. + * + * For some reason we couldn't find this scope within Google libraries + */ + val MonitoringWrite = "https://www.googleapis.com/auth/monitoring.write" +} diff --git a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/models/GcpBatchParameters.scala b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/models/GcpBatchParameters.scala index be29a38be84..77a52ab1904 100644 --- a/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/models/GcpBatchParameters.scala +++ b/supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/models/GcpBatchParameters.scala @@ -79,6 +79,3 @@ final case class GcpBatchDirectoryOutput(name: String, secondary: Boolean, override val contentType: Option[ContentType] = None ) extends GcpBatchOutput - -// TODO: Remove when support for V1 is stopped, this is only used to pass the extra_param auth file -final case class GcpBatchLiteralInput(name: String, value: String)