diff --git a/core/src/main/scala/org/broadinstitute/dsde/rawls/Boot.scala b/core/src/main/scala/org/broadinstitute/dsde/rawls/Boot.scala index d6ff9cd143..d8d627c0ed 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/rawls/Boot.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/rawls/Boot.scala @@ -419,7 +419,8 @@ object Boot extends IOApp with LazyLogging { appConfigManager.gcsConfig.map(_.getString("terraBucketWriterRole")).getOrElse("unsupported"), new RawlsWorkspaceAclManager(samDAO), new MultiCloudWorkspaceAclManager(workspaceManagerDAO, samDAO, billingProfileManagerDAO, slickDataSource), - fastPassServiceConstructor + fastPassServiceConstructor, + dataRepoDAO ) val workspaceAdminServiceConstructor: RawlsRequestContext => WorkspaceAdminService = diff --git a/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/DataRepoDAO.scala b/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/DataRepoDAO.scala index 6ae7e90155..9c469b567e 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/DataRepoDAO.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/DataRepoDAO.scala @@ -1,7 +1,7 @@ package org.broadinstitute.dsde.rawls.dataaccess.datarepo import akka.http.scaladsl.model.headers.OAuth2BearerToken -import bio.terra.datarepo.model.SnapshotModel +import bio.terra.datarepo.model.{PolicyResponse, SnapshotModel} import java.util.UUID @@ -10,4 +10,8 @@ trait DataRepoDAO { def getInstanceName: String def getSnapshot(snapshotId: UUID, accessToken: OAuth2BearerToken): SnapshotModel + + def retrieveSnapshotPolicies(snapshotId: UUID, accessToken: OAuth2BearerToken): PolicyResponse + + def removeSnapshotPolicy(snapshotId: UUID, member: String, accessToken: OAuth2BearerToken) } diff --git a/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/HttpDataRepoDAO.scala b/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/HttpDataRepoDAO.scala index 126a216491..104ef497c5 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/HttpDataRepoDAO.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/datarepo/HttpDataRepoDAO.scala @@ -3,7 +3,7 @@ package org.broadinstitute.dsde.rawls.dataaccess.datarepo import akka.http.scaladsl.model.headers.OAuth2BearerToken import bio.terra.datarepo.api.RepositoryApi import bio.terra.datarepo.client.ApiClient -import bio.terra.datarepo.model.{ColumnModel, SnapshotModel, TableDataType} +import bio.terra.datarepo.model.{ColumnModel, PolicyResponse, SnapshotModel, TableDataType} import org.broadinstitute.dsde.rawls.entities.datarepo.DataRepoBigQuerySupport import java.util.stream.Collectors @@ -38,4 +38,10 @@ class HttpDataRepoDAO(dataRepoInstanceName: String, dataRepoInstanceBasePath: St } snapshot } + + override def retrieveSnapshotPolicies(snapshotId: UUID, accessToken: OAuth2BearerToken): PolicyResponse = + getRepositoryApi(accessToken).retrieveSnapshotPolicies(snapshotId) + + override def removeSnapshotPolicy(snapshotId: UUID, member: String, accessToken: OAuth2BearerToken) = + getRepositoryApi(accessToken).deleteSnapshotPolicyMember(snapshotId, "reader", member) } diff --git a/core/src/main/scala/org/broadinstitute/dsde/rawls/workspace/WorkspaceService.scala b/core/src/main/scala/org/broadinstitute/dsde/rawls/workspace/WorkspaceService.scala index 1e049a49da..0f85d260e2 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/rawls/workspace/WorkspaceService.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/rawls/workspace/WorkspaceService.scala @@ -2,6 +2,7 @@ package org.broadinstitute.dsde.rawls.workspace import akka.http.scaladsl.model.{StatusCode, StatusCodes} import akka.stream.Materializer +import bio.terra.datarepo.model.{PolicyResponse, WorkspacePolicyModel} import bio.terra.workspace.client.ApiException import bio.terra.workspace.model.WorkspaceDescription import cats.implicits._ @@ -47,6 +48,7 @@ import spray.json._ import org.broadinstitute.dsde.rawls.metrics.MetricsHelper import cats.effect.unsafe.implicits.global import org.broadinstitute.dsde.rawls.billing.BillingRepository +import org.broadinstitute.dsde.rawls.dataaccess.datarepo.DataRepoDAO import java.io.IOException import java.util.UUID @@ -81,7 +83,8 @@ object WorkspaceService { terraBucketWriterRole: String, rawlsWorkspaceAclManager: RawlsWorkspaceAclManager, multiCloudWorkspaceAclManager: MultiCloudWorkspaceAclManager, - fastPassServiceConstructor: (RawlsRequestContext, SlickDataSource) => FastPassService + fastPassServiceConstructor: (RawlsRequestContext, SlickDataSource) => FastPassService, + dataRepoDao: DataRepoDAO )( ctx: RawlsRequestContext )(implicit materializer: Materializer, executionContext: ExecutionContext): WorkspaceService = @@ -109,6 +112,7 @@ object WorkspaceService { rawlsWorkspaceAclManager, multiCloudWorkspaceAclManager, (context: RawlsRequestContext) => fastPassServiceConstructor(context, dataSource), + dataRepoDao, new WorkspaceRepository(dataSource), new BillingRepository(dataSource) ) @@ -156,6 +160,7 @@ class WorkspaceService( rawlsWorkspaceAclManager: RawlsWorkspaceAclManager, multiCloudWorkspaceAclManager: MultiCloudWorkspaceAclManager, val fastPassServiceConstructor: RawlsRequestContext => FastPassService, + val dataRepoDao: DataRepoDAO, val workspaceRepository: WorkspaceRepository, val billingRepository: BillingRepository )(implicit protected val executionContext: ExecutionContext) @@ -485,6 +490,11 @@ class WorkspaceService( new RawlsExceptionWithErrorReport(ErrorReport(StatusCodes.InternalServerError, "MC workspaces not supported")) ) } + val resourceList = + workspaceManagerDAO.enumerateDataRepoSnapshotReferences(workspaceContext.workspaceIdAsUUID, 0, 100, ctx) + val snapshotIds = resourceList.getResources.asScala.flatMap { resource => + Option(resource.getResourceAttributes.getGcpDataRepoSnapshot).map(_.getSnapshot) + }.toList for { // just a simple db operation now - the extra logging is excessive @@ -501,6 +511,32 @@ class WorkspaceService( Future.traverse(workflowsToAbort)(wf => executionServiceCluster.abort(wf, ctx.userInfo)) ) + _ <- traceFutureWithParent("getSnapshotPolicies", parentContext)(_ => + Future + .traverse(snapshotIds) { snapshotId => + val filteredWorkspaces = + dataRepoDao + .retrieveSnapshotPolicies(UUID.fromString(snapshotId), ctx.userInfo.accessToken) + .getWorkspaces + .asScala + .filter(wsPM => wsPM.getWorkspaceId == workspaceContext.workspaceIdAsUUID) + .toList + logger.info(s"FilteredWorkspaces: $filteredWorkspaces") + + Future.successful { + filteredWorkspaces.map { workspace => + workspace.getWorkspacePolicies.asScala.foreach { wsPolicy => + wsPolicy.getMembers.asScala.foreach { member => + logger.info(s"removing policyMember: $member") + dataRepoDao.removeSnapshotPolicy(UUID.fromString(snapshotId), member, ctx.userInfo.accessToken) + + } + } + } + } + } + ) + _ <- traceFutureWithParent("deleteFastPassGrantsTransaction", parentContext)(childContext => fastPassServiceConstructor(childContext).removeFastPassGrantsForWorkspace(workspaceContext) ) @@ -533,7 +569,9 @@ class WorkspaceService( // Delete workflowCollection resource in sam outside of DB transaction _ <- traceFutureWithParent("deleteWorkflowCollectionSamResource", parentContext)(_ => workspaceContext.workflowCollectionName - .map(cn => samDAO.deleteResource(SamResourceTypeNames.workflowCollection, cn, ctx)) + .map { cn => + samDAO.deleteResource(SamResourceTypeNames.workflowCollection, cn, ctx) + } .getOrElse(Future.successful(())) recoverWith { case t: RawlsExceptionWithErrorReport if t.errorReport.statusCode.contains(StatusCodes.NotFound) => logger.warn(