-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#2019 configure pekko-persistence with AWS IAM based auth
* provide own "driver" for the pekko-persistence plugin * configure AWS IAM based authentication based on the Ditto configuration * moved common AWS MongoCredential obtaining logic to new AwsAuthenticationHelper class
- Loading branch information
Showing
10 changed files
with
261 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
...java/org/eclipse/ditto/internal/utils/persistence/mongo/auth/AwsAuthenticationHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright (c) 2024 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.internal.utils.persistence.mongo.auth; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.mongodb.AwsCredential; | ||
import com.mongodb.MongoCredential; | ||
|
||
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.sts.StsClient; | ||
import software.amazon.awssdk.services.sts.StsClientBuilder; | ||
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; | ||
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse; | ||
import software.amazon.awssdk.services.sts.model.Credentials; | ||
|
||
/** | ||
* Helper class to obtain {@link MongoCredential}s when running Ditto in AWS. | ||
*/ | ||
public final class AwsAuthenticationHelper { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(AwsAuthenticationHelper.class); | ||
|
||
private AwsAuthenticationHelper() { | ||
throw new AssertionError(); | ||
} | ||
|
||
/** | ||
* Obtains a {@link MongoCredential} based on AWS IAM "obtaining role" based authentication. | ||
* | ||
* @param awsRegion the optional to-be-configured AWS region | ||
* @param awsRoleArn the role ARN to obtain | ||
* @param awsSessionName the session name to use | ||
* @return the MongoCredential prepared to authenticate via AWS IAM | ||
*/ | ||
public static MongoCredential provideAwsIamBasedMongoCredential( | ||
@Nullable final String awsRegion, | ||
final String awsRoleArn, | ||
final String awsSessionName | ||
) { | ||
final StsClientBuilder stsClientBuilder = StsClient.builder() | ||
.credentialsProvider(DefaultCredentialsProvider.create()); | ||
if (awsRegion != null && !awsRegion.isEmpty()) { | ||
stsClientBuilder.region(Region.of(awsRegion)); | ||
} | ||
|
||
final Supplier<AwsCredential> awsFreshCredentialSupplier; | ||
try (final StsClient stsClient = stsClientBuilder.build()) { | ||
awsFreshCredentialSupplier = () -> { | ||
LOGGER.info("Supplying AWS IAM credentials, assuming role <{}> in session name <{}>", | ||
awsRoleArn, awsSessionName); | ||
|
||
// assume role using the AWS SDK | ||
final AssumeRoleRequest roleRequest = AssumeRoleRequest.builder() | ||
.roleArn(awsRoleArn) | ||
.roleSessionName(awsSessionName) | ||
.build(); | ||
final AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest); | ||
final Credentials awsCredentials = roleResponse.credentials(); | ||
|
||
return new AwsCredential(awsCredentials.accessKeyId(), awsCredentials.secretAccessKey(), | ||
awsCredentials.sessionToken()); | ||
}; | ||
|
||
return MongoCredential.createAwsCredential(null, null) | ||
.withMechanismProperty(MongoCredential.AWS_CREDENTIAL_PROVIDER_KEY, awsFreshCredentialSupplier); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
.../ditto/internal/utils/persistence/pekko/CustomizableScalaDriverPersistenceExtension.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2024 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.internal.utils.persistence.pekko | ||
|
||
import com.mongodb.MongoCredential | ||
import com.typesafe.config.Config | ||
import org.apache.pekko.actor.ActorSystem | ||
import org.eclipse.ditto.internal.utils.config.DefaultScopedConfig | ||
import org.eclipse.ditto.internal.utils.persistence.mongo.auth.AwsAuthenticationHelper | ||
import org.eclipse.ditto.internal.utils.persistence.mongo.config.DefaultMongoDbConfig | ||
import pekko.contrib.persistence.mongodb.driver.{ScalaDriverPersistenceJournaller, ScalaDriverPersistenceReadJournaller, ScalaDriverPersistenceSnapshotter, ScalaMongoDriver} | ||
import pekko.contrib.persistence.mongodb.{ConfiguredExtension, MongoPersistenceExtension, MongoPersistenceJournalMetrics, MongoPersistenceJournallingApi} | ||
|
||
/** | ||
* An adjustment of the original pekko-persistence | ||
* [[pekko.contrib.persistence.mongodb.driver.ScalaDriverPersistenceExtension]] which can be customized in a way to | ||
* overwrite configuration of the used [[ScalaMongoDriver]]. | ||
* Creates an instance of [[CustomizableScalaMongoDriver]] when a custom [[MongoCredential]] should be provided | ||
* to the driver in order to authenticate. | ||
* | ||
* @param actorSystem the ActorSystem in which the extension was loaded | ||
*/ | ||
class CustomizableScalaDriverPersistenceExtension(val actorSystem: ActorSystem) | ||
extends MongoPersistenceExtension(actorSystem) { | ||
|
||
override def configured(config: Config): Configured = Configured(config) | ||
|
||
case class Configured(config: Config) extends ConfiguredExtension { | ||
|
||
val driver: ScalaMongoDriver = { | ||
val mongoDbConfig = DefaultMongoDbConfig.of(DefaultScopedConfig.dittoScoped(actorSystem.settings.config)) | ||
val optionsConfig = mongoDbConfig.getOptionsConfig | ||
|
||
if (optionsConfig.isUseAwsIamRole) { | ||
val mongoCredential = AwsAuthenticationHelper.provideAwsIamBasedMongoCredential( | ||
optionsConfig.awsRegion(), | ||
optionsConfig.awsRoleArn(), | ||
optionsConfig.awsSessionName() | ||
) | ||
new CustomizableScalaMongoDriver(actorSystem, config, builder => builder.credential(mongoCredential)) | ||
} else { | ||
new ScalaMongoDriver(actorSystem, config) | ||
} | ||
} | ||
|
||
override lazy val journaler: MongoPersistenceJournallingApi = new ScalaDriverPersistenceJournaller(driver) | ||
with MongoPersistenceJournalMetrics { | ||
override def driverName = "scala-official" | ||
} | ||
override lazy val snapshotter = new ScalaDriverPersistenceSnapshotter(driver) | ||
|
||
override lazy val readJournal = new ScalaDriverPersistenceReadJournaller(driver) | ||
} | ||
|
||
} |
Oops, something went wrong.