Skip to content

Commit

Permalink
Merge effdf32 into 37bc074
Browse files Browse the repository at this point in the history
  • Loading branch information
marctalbott committed Mar 5, 2019
2 parents 37bc074 + effdf32 commit 4c0d221
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 53 deletions.
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Dependencies {

val workbenchUtilV = "0.5-6942040"
val workbenchModelV = "0.13-7e86fba"
val workbenchGoogleV = "0.18-8328aae"
val workbenchGoogleV = "0.18-f074409"
val workbenchGoogle2V = "0.1-8328aae"
val workbenchNotificationsV = "0.1-f2a0020"
val monocleVersion = "1.5.1-cats"
Expand Down
26 changes: 10 additions & 16 deletions src/main/scala/org/broadinstitute/dsde/workbench/sam/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,8 @@ import javax.net.ssl.SSLContext
import org.broadinstitute.dsde.workbench.dataaccess.PubSubNotificationDAO
import org.broadinstitute.dsde.workbench.google.GoogleCredentialModes.{Json, Pem}
import org.broadinstitute.dsde.workbench.google2.util.DistributedLock
import org.broadinstitute.dsde.workbench.google.{
GoogleDirectoryDAO,
HttpGoogleDirectoryDAO,
HttpGoogleIamDAO,
HttpGoogleProjectDAO,
HttpGooglePubSubDAO,
HttpGoogleStorageDAO
}
import org.broadinstitute.dsde.workbench.google2.{
GoogleStorageService,
GoogleFirestoreInterpreter,
GoogleStorageInterpreter
}
import org.broadinstitute.dsde.workbench.google.{GoogleDirectoryDAO, GoogleKmsInterpreter, GoogleKmsService, HttpGoogleDirectoryDAO, HttpGoogleIamDAO, HttpGoogleProjectDAO, HttpGooglePubSubDAO, HttpGoogleStorageDAO}
import org.broadinstitute.dsde.workbench.google2.{GoogleFirestoreInterpreter, GoogleStorageInterpreter, GoogleStorageService}
import org.broadinstitute.dsde.workbench.model.{WorkbenchEmail, WorkbenchException, WorkbenchSubject}
import org.broadinstitute.dsde.workbench.sam.api.{SamRoutes, StandardUserInfoDirectives}
import org.broadinstitute.dsde.workbench.sam.config.{AppConfig, GoogleConfig}
Expand Down Expand Up @@ -64,7 +53,7 @@ object Boot extends IOApp with LazyLogging {

val appDependencies = createAppDependencies(appConfig)

appDependencies.use { dependencies =>
appDependencies.use { dependencies => // this is where the resource is used
for {
_ <- IO.fromFuture(IO(schemaDAO.init())).onError {
case e: WorkbenchException =>
Expand Down Expand Up @@ -183,15 +172,18 @@ object Boot extends IOApp with LazyLogging {
config.googleServicesConfig.serviceAccountCredentialJson.firestoreServiceAccountJsonPath.asString)
googleStorage <- GoogleStorageInterpreter.storage[IO](
config.googleServicesConfig.serviceAccountCredentialJson.defaultServiceAccountJsonPath.asString)
googleKmsClient <- GoogleKmsInterpreter.client[IO](
config.googleServicesConfig.serviceAccountCredentialJson.defaultServiceAccountJsonPath.asString)
} yield {
val ioFireStore = GoogleFirestoreInterpreter[IO](googleFire)
// googleServicesConfig.resourceNamePrefix is an environment specific variable passed in https://github.com/broadinstitute/firecloud-develop/blob/fade9286ff0aec8449121ed201ebc44c8a4d57dd/run-context/fiab/configs/sam/docker-compose.yaml.ctmpl#L24
// Use resourceNamePrefix to avoid collision between different fiab environments (we share same firestore for fiabs)
val lock =
DistributedLock[IO](s"sam-${config.googleServicesConfig.resourceNamePrefix.getOrElse("local")}", appConfig.distributedLockConfig, ioFireStore)
val newGoogleStorage = GoogleStorageInterpreter[IO](googleStorage, blockingEc)
val googleKmsInterpreter = GoogleKmsInterpreter[IO](googleKmsClient, blockingEc)
val resourceTypeMap = appConfig.resourceTypes.map(rt => rt.name -> rt).toMap
val cloudExtension = createGoogleCloudExt(accessPolicyDao, directoryDAO, config, resourceTypeMap, lock, newGoogleStorage)
val cloudExtension = createGoogleCloudExt(accessPolicyDao, directoryDAO, config, resourceTypeMap, lock, newGoogleStorage, googleKmsInterpreter)
val googleGroupSynchronizer = new GoogleGroupSynchronizer(backgroundDirectoryDAO, backgroundAccessPolicyDao, cloudExtension.googleDirectoryDAO, cloudExtension, resourceTypeMap)(backgroundLdapExecutionContext)
val cloudExtensionsInitializer = new GoogleExtensionsInitializer(cloudExtension, googleGroupSynchronizer)
createAppDepenciesWithSamRoutes(appConfig, cloudExtensionsInitializer, accessPolicyDao, directoryDAO)
Expand All @@ -206,7 +198,8 @@ object Boot extends IOApp with LazyLogging {
config: GoogleConfig,
resourceTypeMap: Map[ResourceTypeName, ResourceType],
distributedLock: DistributedLock[IO],
googleStorageNew: GoogleStorageService[IO])(implicit actorSystem: ActorSystem): GoogleExtensions = {
googleStorageNew: GoogleStorageService[IO],
googleKms: GoogleKmsService[IO])(implicit actorSystem: ActorSystem): GoogleExtensions = {
val googleDirDaos = (config.googleServicesConfig.adminSdkServiceAccounts match {
case None =>
NonEmptyList.one(
Expand Down Expand Up @@ -267,6 +260,7 @@ object Boot extends IOApp with LazyLogging {
googleProjectDAO,
googleKeyCache,
notificationDAO,
googleKms,
config.googleServicesConfig,
config.petServiceAccountConfig,
resourceTypeMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.broadinstitute.dsde.workbench.model.google.{GcsBucketName, GoogleProj
import net.ceedubs.ficus.Ficus._
import AppConfig.nonEmptyListReader
import com.typesafe.config.ConfigRenderOptions
import org.broadinstitute.dsde.workbench.google.{KeyId, KeyRingId, Location}

import scala.concurrent.duration.FiniteDuration

Expand Down Expand Up @@ -36,7 +37,8 @@ final case class GoogleServicesConfig(
notificationTopic: String,
googleKeyCacheConfig: GoogleKeyCacheConfig,
resourceNamePrefix: Option[String],
adminSdkServiceAccounts: Option[NonEmptyList[ServiceAccountConfig]]
adminSdkServiceAccounts: Option[NonEmptyList[ServiceAccountConfig]],
googleKms: GoogleKmsConfig
)

object GoogleServicesConfig {
Expand All @@ -54,6 +56,16 @@ object GoogleServicesConfig {
)
}

implicit val googleKmsConfigReader: ValueReader[GoogleKmsConfig] = ValueReader.relative { config =>
GoogleKmsConfig(
GoogleProject(config.getString("project")),
Location(config.getString("location")),
KeyRingId(config.getString("keyRingId")),
KeyId(config.getString("keyId")),
config.as[FiniteDuration]("rotationPeriod")
)
}

implicit val serviceAccountConfigReader: ValueReader[ServiceAccountConfig] = ValueReader.relative { config =>
ServiceAccountConfig(config.root().render(ConfigRenderOptions.concise))
}
Expand Down Expand Up @@ -87,7 +99,8 @@ object GoogleServicesConfig {
config.getString("notifications.topicName"),
config.as[GoogleKeyCacheConfig]("googleKeyCache"),
config.as[Option[String]]("resourceNamePrefix"),
config.as[Option[NonEmptyList[ServiceAccountConfig]]]("adminSdkServiceAccounts")
config.as[Option[NonEmptyList[ServiceAccountConfig]]]("adminSdkServiceAccounts"),
config.as[GoogleKmsConfig]("kms")
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.broadinstitute.dsde.workbench.sam.config

import org.broadinstitute.dsde.workbench.google.{KeyId, KeyRingId, Location}
import org.broadinstitute.dsde.workbench.model.google.GoogleProject

import scala.concurrent.duration.FiniteDuration

/**
* created by mtalbott 1/25/18
*
* @param project google project for the key
* @param location location for the key
* @param keyRingId name of the key ring that contains the key
* @param keyId name of the key
*/

final case class GoogleKmsConfig(
project: GoogleProject,
location: Location,
keyRingId: KeyRingId,
keyId: KeyId,
rotationPeriod: FiniteDuration
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,15 @@ import akka.http.scaladsl.model.headers.OAuth2BearerToken
import cats.effect.{ContextShift, IO}
import cats.implicits._
import com.google.api.client.googleapis.json.GoogleJsonResponseException
import com.google.api.gax.rpc.AlreadyExistsException
import com.google.auth.oauth2.ServiceAccountCredentials
import com.google.protobuf.{Timestamp, Duration}
import com.google.rpc.Code
import com.typesafe.scalalogging.LazyLogging
import org.broadinstitute.dsde.workbench.dataaccess.NotificationDAO
import org.broadinstitute.dsde.workbench.google2.util.{DistributedLock, LockPath}
import org.broadinstitute.dsde.workbench.google.{
GoogleDirectoryDAO,
GoogleIamDAO,
GoogleProjectDAO,
GooglePubSubDAO,
GoogleStorageDAO
}
import org.broadinstitute.dsde.workbench.google2.{
CollectionName,
Document
}
import org.broadinstitute.dsde.workbench.google.{GoogleDirectoryDAO, GoogleIamDAO, GoogleKmsService, GoogleProjectDAO, GooglePubSubDAO, GoogleStorageDAO}
import org.broadinstitute.dsde.workbench.google2.{CollectionName, Document}
import org.broadinstitute.dsde.workbench.model.Notifications.Notification
import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport.WorkbenchGroupNameFormat
import org.broadinstitute.dsde.workbench.model._
Expand Down Expand Up @@ -62,6 +55,7 @@ class GoogleExtensions(
val googleProjectDAO: GoogleProjectDAO,
val googleKeyCache: GoogleKeyCache,
val notificationDAO: NotificationDAO,
val googleKms: GoogleKmsService[IO],
val googleServicesConfig: GoogleServicesConfig,
val petServiceAccountConfig: PetServiceAccountConfig,
val resourceTypes: Map[ResourceTypeName, ResourceType])(implicit val system: ActorSystem, executionContext: ExecutionContext, cs: ContextShift[IO])
Expand Down Expand Up @@ -134,6 +128,25 @@ class GoogleExtensions(
case e: WorkbenchExceptionWithErrorReport if e.errorReport.statusCode == Option(StatusCodes.Conflict) =>
}))

_ <- googleKms.createKeyRing(googleServicesConfig.googleKms.project,
googleServicesConfig.googleKms.location,
googleServicesConfig.googleKms.keyRingId) handleErrorWith { case _: AlreadyExistsException => IO.unit }

_ <- googleKms.createKey(googleServicesConfig.googleKms.project,
googleServicesConfig.googleKms.location,
googleServicesConfig.googleKms.keyRingId,
googleServicesConfig.googleKms.keyId,
Option(Timestamp.newBuilder().setSeconds(System.currentTimeMillis() / 1000 + googleServicesConfig.googleKms.rotationPeriod.toSeconds).build()),
Option(Duration.newBuilder().setSeconds(googleServicesConfig.googleKms.rotationPeriod.toSeconds).build())
) handleErrorWith { case _: AlreadyExistsException => IO.unit }

_ <- googleKms.addMemberToKeyPolicy(googleServicesConfig.googleKms.project,
googleServicesConfig.googleKms.location,
googleServicesConfig.googleKms.keyRingId,
googleServicesConfig.googleKms.keyId,
s"group:$allUsersGroupEmail",
"roles/cloudkms.cryptoKeyEncrypterDecrypter")

_ <- samApplication.resourceService.createResourceType(extensionResourceType)

_ <- IO.fromFuture(IO(samApplication.resourceService.createResource(extensionResourceType, GoogleExtensions.resourceId, serviceAccountUserInfo))) handleErrorWith {
Expand Down
8 changes: 8 additions & 0 deletions src/test/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ googleServices {
workerCount = 1
}
}

kms {
project = "broad-dsde-dev"
location = "global"
keyRingId = "not-actually-used"
keyId = "dockerhub-key"
rotationPeriod = "180 days"
}
}

schemaLock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ object TestSupport extends TestSupport {
null,
cloudKeyCache,
notificationDAO,
FakeGoogleKmsInterpreter,
googleServicesConfig,
petServiceAccountConfig,
resourceTypes))
Expand Down
Loading

0 comments on commit 4c0d221

Please sign in to comment.