From 1bf54b3acc106544590c4754cc94ff8dca0d574c Mon Sep 17 00:00:00 2001 From: bennettn4 <117685842+bennettn4@users.noreply.github.com> Date: Tue, 13 Aug 2024 11:09:19 -0400 Subject: [PATCH] Enable v1 APIs for Disk, App, and Runtime for Azure hosted Leonardo instances (#4737) --- .../http/AzureDependenciesBuilder.scala | 30 ++++++++++++++++++- .../http/GcpDependenciesBuilder.scala | 8 ++--- .../leonardo/http/api/HttpRoutes.scala | 10 ++++++- .../http/service/DiskServiceInterp.scala | 10 +++---- .../http/service/RuntimeService.scala | 4 +-- .../http/service/RuntimeServiceInterp.scala | 8 ++--- .../leonardo/http/api/TestLeoRoutes.scala | 4 +-- .../http/service/DiskServiceInterpSpec.scala | 14 ++++----- .../service/RuntimeServiceInterpSpec.scala | 4 +-- 9 files changed, 64 insertions(+), 28 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AzureDependenciesBuilder.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AzureDependenciesBuilder.scala index 21ef44eb027..a1275ee01b4 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AzureDependenciesBuilder.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AzureDependenciesBuilder.scala @@ -3,7 +3,12 @@ import akka.actor.ActorSystem import cats.effect.{IO, Resource} import org.broadinstitute.dsde.workbench.leonardo.config.Config.{appServiceConfig, gkeCustomAppConfig} import org.broadinstitute.dsde.workbench.leonardo.db.DbReference -import org.broadinstitute.dsde.workbench.leonardo.http.service.LeoAppServiceInterp +import org.broadinstitute.dsde.workbench.leonardo.http.service.{ + DiskService, + DiskServiceInterp, + LeoAppServiceInterp, + RuntimeService +} import org.broadinstitute.dsde.workbench.leonardo.monitor.MonitorAtBoot import org.broadinstitute.dsde.workbench.leonardo.util.ServicesRegistry import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics @@ -85,9 +90,32 @@ class AzureDependenciesBuilder extends CloudDependenciesBuilder { baselineDependencies.wsmClientProvider ) + // Needed for v1 APIs + val diskService = new DiskServiceInterp[IO]( + ConfigReader.appConfig.persistentDisk, + baselineDependencies.authProvider, + baselineDependencies.serviceAccountProvider, + baselineDependencies.publisherQueue, + None, + None + ) + + val runtimeService = RuntimeService( + baselineDependencies.runtimeServicesConfig, + ConfigReader.appConfig.persistentDisk, + baselineDependencies.authProvider, + baselineDependencies.serviceAccountProvider, + baselineDependencies.dockerDAO, + None, + None, + baselineDependencies.publisherQueue + ) + var servicesRegistry = ServicesRegistry() servicesRegistry.register[LeoAppServiceInterp[IO]](leoKubernetesService) + servicesRegistry.register[DiskService[IO]](diskService) + servicesRegistry.register[RuntimeService[IO]](runtimeService) Resource.make(IO(servicesRegistry))(_ => IO.unit) } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/GcpDependenciesBuilder.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/GcpDependenciesBuilder.scala index 842bc9dc2fc..36e6bc07c24 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/GcpDependenciesBuilder.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/GcpDependenciesBuilder.scala @@ -284,8 +284,8 @@ class GcpDependencyBuilder extends CloudDependenciesBuilder { baselineDependencies.authProvider, baselineDependencies.serviceAccountProvider, baselineDependencies.publisherQueue, - gcpDependencies.googleDiskService, - gcpDependencies.googleProjectDAO + Some(gcpDependencies.googleDiskService), + Some(gcpDependencies.googleProjectDAO) ) val runtimeService = RuntimeService( @@ -294,8 +294,8 @@ class GcpDependencyBuilder extends CloudDependenciesBuilder { baselineDependencies.authProvider, baselineDependencies.serviceAccountProvider, baselineDependencies.dockerDAO, - gcpDependencies.googleStorageService, - gcpDependencies.googleComputeService, + Some(gcpDependencies.googleStorageService), + Some(gcpDependencies.googleComputeService), baselineDependencies.publisherQueue ) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/HttpRoutes.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/HttpRoutes.scala index 6d11ebcf2cd..36ae7e705ca 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/HttpRoutes.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/HttpRoutes.scala @@ -44,6 +44,7 @@ class HttpRoutes( private val statusRoutes = new StatusRoutes(statusService) private val corsSupport = new CorsSupport(contentSecurityPolicy, refererConfig) private val kubernetesRoutes = new AppRoutes(kubernetesService, userInfoDirectives) + private val appRoutes = createAppRoutesUsingServicesRegistry private val appV2Routes = new AppV2Routes(kubernetesService, userInfoDirectives) private val runtimeV2Routes = new RuntimeV2Routes(refererConfig, azureService, userInfoDirectives) private val diskV2Routes = new DiskV2Routes(diskV2Service, userInfoDirectives) @@ -133,7 +134,9 @@ class HttpRoutes( oidcConfig .swaggerRoutes("swagger/api-docs.yaml") ~ oidcConfig.oauth2Routes ~ statusRoutes.route ~ pathPrefix("api") { - runtimeV2Routes.routes ~ appV2Routes.routes ~ diskV2Routes.routes ~ adminRoutes.routes + runtimeRoutes.get.routes ~ runtimeV2Routes.routes ~ + diskRoutes.get.routes ~ diskV2Routes.routes ~ + appRoutes.get.routes ~ appV2Routes.routes ~ adminRoutes.routes } ) } @@ -153,6 +156,11 @@ class HttpRoutes( .lookup[RuntimeService[IO]] .map(runtimeService => new RuntimeRoutes(refererConfig, runtimeService, userInfoDirectives)) + private def createAppRoutesUsingServicesRegistry = + gcpOnlyServicesRegistry + .lookup[LeoAppServiceInterp[IO]] + .map(appService => new AppRoutes(appService, userInfoDirectives)) + private def createProxyRoutesUsingServicesRegistry = gcpOnlyServicesRegistry .lookup[ProxyService] diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterp.scala index 6fffdb6a274..91de307f4f8 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterp.scala @@ -38,8 +38,8 @@ class DiskServiceInterp[F[_]: Parallel](config: PersistentDiskConfig, authProvider: LeoAuthProvider[F], serviceAccountProvider: ServiceAccountProvider[F], publisherQueue: Queue[F, LeoPubsubMessage], - googleDiskService: GoogleDiskService[F], - googleProjectDAO: GoogleProjectDAO + googleDiskService: Option[GoogleDiskService[F]], + googleProjectDAO: Option[GoogleProjectDAO] )(implicit F: Async[F], log: StructuredLogger[F], @@ -122,10 +122,10 @@ class DiskServiceInterp[F[_]: Parallel](config: PersistentDiskConfig, ): F[Unit] = for { ctx <- as.ask - sourceAncestry <- F.fromFuture(F.delay(googleProjectDAO.getAncestry(sourceGoogleProject.value))) + sourceAncestry <- F.fromFuture(F.delay(googleProjectDAO.get.getAncestry(sourceGoogleProject.value))) sourceAncestor <- immediateAncestor(sourceAncestry) - targetAncestry <- F.fromFuture(F.delay(googleProjectDAO.getAncestry(targetGoogleProject.value))) + targetAncestry <- F.fromFuture(F.delay(googleProjectDAO.get.getAncestry(targetGoogleProject.value))) targetAncestor <- immediateAncestor(targetAncestry) _ <- F.raiseWhen( @@ -160,7 +160,7 @@ class DiskServiceInterp[F[_]: Parallel](config: PersistentDiskConfig, case _: DiskNotFoundException => F.raiseError(BadRequestException("source disk does not exist", Option(ctx.traceId))) } - maybeGoogleDisk <- googleDiskService.getDisk(sourceDiskReq.googleProject, sourceDisk.zone, sourceDisk.name) + maybeGoogleDisk <- googleDiskService.get.getDisk(sourceDiskReq.googleProject, sourceDisk.zone, sourceDisk.name) googleDisk <- maybeGoogleDisk.toOptionT.getOrElseF( F.raiseError( LeoInternalServerError(s"Source disk $sourceDiskReq does not exist in google", Option(ctx.traceId)) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeService.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeService.scala index 1f303c5f46c..0e2fd101b39 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeService.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeService.scala @@ -71,8 +71,8 @@ object RuntimeService { authProvider: LeoAuthProvider[F], serviceAccountProvider: ServiceAccountProvider[F], dockerDAO: DockerDAO[F], - googleStorageService: GoogleStorageService[F], - googleComputeService: GoogleComputeService[F], + googleStorageService: Option[GoogleStorageService[F]], + googleComputeService: Option[GoogleComputeService[F]], publisherQueue: Queue[F, LeoPubsubMessage] )(implicit F: Async[F], diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala index 998011f5fce..d0d78e03c24 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala @@ -68,8 +68,8 @@ class RuntimeServiceInterp[F[_]: Parallel]( authProvider: LeoAuthProvider[F], serviceAccountProvider: ServiceAccountProvider[F], dockerDAO: DockerDAO[F], - googleStorageService: GoogleStorageService[F], - googleComputeService: GoogleComputeService[F], + googleStorageService: Option[GoogleStorageService[F]], + googleComputeService: Option[GoogleComputeService[F]], publisherQueue: Queue[F, LeoPubsubMessage] )(implicit F: Async[F], @@ -369,7 +369,7 @@ class RuntimeServiceInterp[F[_]: Parallel]( disk <- F.fromEither( diskOpt.toRight(new RuntimeException(s"Can't find ${diskId} in PERSISTENT_DISK table")) ) - detachOp <- googleComputeService.detachDisk( + detachOp <- googleComputeService.get.detachDisk( req.googleProject, disk.zone, InstanceName(runtime.runtimeName.asString), @@ -765,7 +765,7 @@ class RuntimeServiceInterp[F[_]: Parallel]( ) val res = for { - blob <- googleStorageService + blob <- googleStorageService.get .getBlob( gcsPath.bucketName, GcsBlobName(gcsPath.objectName.value), diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/TestLeoRoutes.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/TestLeoRoutes.scala index 9f906487328..97169908930 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/TestLeoRoutes.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/api/TestLeoRoutes.scala @@ -191,8 +191,8 @@ trait TestLeoRoutes { allowListAuthProvider, serviceAccountProvider, new MockDockerDAO, - FakeGoogleStorageInterpreter, - FakeGoogleComputeService, + Some(FakeGoogleStorageInterpreter), + Some(FakeGoogleComputeService), QueueFactory.makePublisherQueue() ) diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterpSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterpSpec.scala index 5c355dfffdd..8cace4a4d61 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterpSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/DiskServiceInterpSpec.scala @@ -67,8 +67,8 @@ trait DiskServiceInterpSpec extends AnyFlatSpec with LeonardoTestSuite with Test allowListAuthProvider, serviceAccountProvider, publisherQueue, - MockGoogleDiskService, - googleProjectDAO + Some(MockGoogleDiskService), + Some(googleProjectDAO) ) (diskService, publisherQueue) } @@ -166,13 +166,13 @@ class DiskServiceInterpTest allowListAuthProvider, serviceAccountProvider, publisherQueue, - new MockGoogleDiskService { + Some(new MockGoogleDiskService { override def getDisk(project: GoogleProject, zone: ZoneName, diskName: DiskName)(implicit ev: Ask[IO, TraceId] ): IO[Option[Disk]] = IO.pure(Some(Disk.newBuilder().setSelfLink(dummyDiskLink).build())) - }, - new MockGoogleProjectDAOWithCustomAncestors(projectToFolder) + }), + Some(new MockGoogleProjectDAOWithCustomAncestors(projectToFolder)) ) val userInfo = UserInfo(OAuth2BearerToken(""), @@ -291,8 +291,8 @@ class DiskServiceInterpTest authProviderMock, serviceAccountProvider, publisherQueue, - googleDiskServiceMock, - new MockGoogleProjectDAO + Some(googleDiskServiceMock), + Some(new MockGoogleProjectDAO) ) val userInfoCreator = UserInfo(OAuth2BearerToken(""), WorkbenchUserId("creator"), WorkbenchEmail("creator@example.com"), 0) diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterpSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterpSpec.scala index df95aff7212..e69b069fa4e 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterpSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterpSpec.scala @@ -95,8 +95,8 @@ trait RuntimeServiceInterpSpec extends AnyFlatSpec with LeonardoTestSuite with T authProvider, serviceAccountProvider, new MockDockerDAO, - FakeGoogleStorageInterpreter, - computeService, + Some(FakeGoogleStorageInterpreter), + Some(computeService), publisherQueue )