Skip to content

Commit

Permalink
Merge branch 'master' into extracting-predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
npxcomplete authored Nov 5, 2024
2 parents 9c2a59b + c316d58 commit ebfe3f0
Show file tree
Hide file tree
Showing 68 changed files with 1,027 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/maven-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
merge_group:

jobs:
build:
Expand Down
5 changes: 5 additions & 0 deletions aws-rds-cfn-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<artifactId>rds</artifactId>
<version>2.25.56</version>
</dependency>
<dependency>
<groupId>software.amazon.cloudformation</groupId>
<artifactId>aws-cloudformation-resource-schema</artifactId>
<version>[2.0.10,3.0.0)</version>
</dependency>
<dependency>
<groupId>software.amazon.cloudformation</groupId>
<artifactId>aws-cloudformation-rpdk-java-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Map;
import java.util.function.Function;

import com.google.common.collect.ImmutableMap;
import lombok.NonNull;
import org.apache.commons.lang3.exception.ExceptionUtils;
import software.amazon.awssdk.core.exception.SdkClientException;
Expand Down Expand Up @@ -126,16 +127,16 @@ public static <M, C> ProgressEvent<M, C> reportResourceDrift(
final M inputModel,
final ProgressEvent<M, C> progress,
final ResourceTypeSchema schema,
final RequestLogger logger
) {
final RequestLogger requestLogger,
final String handlerAction) {
try {
final DriftDetector driftDetector = new DriftDetector(schema);
final Map<String, Mutation> mutations = driftDetector.detectDrift(inputModel, progress.getResourceModel());
if (!mutations.isEmpty()) {
logger.log("Resource drift detected", new DriftDetectorReport(mutations));
requestLogger.log("Resource drift detected", ImmutableMap.of("HandlerAction", handlerAction, "Report", new DriftDetectorReport(mutations)));
}
} catch (Exception e) {
logger.log("Drift detector internal error", e);
requestLogger.log("Drift detector internal error", e);
}
return progress;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package software.amazon.rds.common.status;

/**
* Represents a status that could be considered "terminal" for a resource.
* Terminal states cause resource stabilization to fail immediately. If a
* resource enters a terminal state following a mutation, the operation fails
* with a {@link software.amazon.cloudformation.exceptions.CfnNotStabilizedException}.
*/
public interface TerminableStatus extends Status {
/**
* Returns true if the status is terminal.
*/
boolean isTerminal();
}
Original file line number Diff line number Diff line change
Expand Up @@ -331,10 +331,12 @@ void test_detectDrift_shouldLogDriftedModel() {
final TestResourceModel output = new TestResourceModel();
output.testProperty = "test-property-output";

final String handlerOperation = "test-property";

Logger logger = Mockito.mock(Logger.class);
Mockito.doNothing().when(logger).log(any(String.class));

Commons.reportResourceDrift(input, ProgressEvent.<TestResourceModel, Void>progress(output, null), TEST_RESOURCE_TYPE_SCHEMA, new RequestLogger(logger, new ResourceHandlerRequest<>(), new FilteredJsonPrinter()));
Commons.reportResourceDrift(input, ProgressEvent.<TestResourceModel, Void>progress(output, null), TEST_RESOURCE_TYPE_SCHEMA, new RequestLogger(logger, new ResourceHandlerRequest<>(), new FilteredJsonPrinter()), handlerOperation);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(logger).log(captor.capture());

Expand All @@ -350,12 +352,32 @@ void test_detectDrift_shouldNotLogIfModelIsNotDrifted() {
final TestResourceModel output = new TestResourceModel();
output.testProperty = "test-property";

final String handlerOperation = "test-property";

Logger logger = Mockito.mock(Logger.class);

Commons.reportResourceDrift(input, ProgressEvent.<TestResourceModel, Void>progress(output, null), TEST_RESOURCE_TYPE_SCHEMA, new RequestLogger(logger, new ResourceHandlerRequest<>(), new FilteredJsonPrinter()));
Commons.reportResourceDrift(input, ProgressEvent.<TestResourceModel, Void>progress(output, null), TEST_RESOURCE_TYPE_SCHEMA, new RequestLogger(logger, new ResourceHandlerRequest<>(), new FilteredJsonPrinter()), handlerOperation);
verifyNoInteractions(logger);
}

@Test
void test_detectDrift_shouldFailIfSchemaIsNull(){

final TestResourceModel input = new TestResourceModel();
input.testProperty = "test-property";

final TestResourceModel output = new TestResourceModel();
output.testProperty = "test-property-1";

final String handlerOperation = null;

Commons.reportResourceDrift(input, ProgressEvent.<TestResourceModel, Void>progress(output, null), null, requestLogger, handlerOperation);

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Exception> exCaptor = ArgumentCaptor.forClass(Exception.class);
verify(requestLogger).log(captor.capture(), exCaptor.capture());
}

private AwsServiceException newAwsServiceException(final ErrorCode errorCode) {
return AwsServiceException.builder()
.awsErrorDetails(AwsErrorDetails.builder()
Expand Down
12 changes: 10 additions & 2 deletions aws-rds-customdbengineversion/aws-rds-customdbengineversion.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
"description": "The AWS::RDS::CustomDBEngineVersion resource creates an Amazon RDS custom DB engine version.",
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-rpdk.git",
"tagging": {
"taggable": true
"taggable": true,
"tagOnCreate": true,
"tagUpdatable": true,
"cloudFormationSystemTags": true,
"tagProperty": "/properties/Tags",
"permissions": [
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource"
]
},
"definitions": {
"Tag": {
Expand Down Expand Up @@ -112,7 +120,7 @@
"propertyTransform": {
"/properties/Engine": "$lowercase(Engine)",
"/properties/EngineVersion": "$lowercase(EngineVersion)",
"/properties/KMSKeyId": "$join([\"arn:(aws)[-]{0,1}[a-z]{0,2}[-]{0,1}[a-z]{0,3}:kms:[a-z]{2}[-]{1}[a-z]{3,10}[-]{0,1}[a-z]{0,10}[-]{1}[1-3]{1}:[0-9]{12}[:]{1}key\\/\", KMSKeyId])"
"/properties/KMSKeyId": "$join([\"arn:.+?:kms:.+?:.+?:key\\/\", KMSKeyId])"
},
"required": [
"Engine",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ private void assertNoCustomDbEngineVersionTerminalStatus(final String source) th
private void resourceStabilizationTime(final CallbackContext callbackContext) {
callbackContext.timestampOnce(CUSTOM_DB_ENGINE_VERSION_REQUEST_STARTED_AT, Instant.now());
callbackContext.timestamp(CUSTOM_DB_ENGINE_VERSION_REQUEST_IN_PROGRESS_AT, Instant.now());
callbackContext.calculateTimeDeltaInMinutes(CUSTOM_DB_ENGINE_VERSION_RESOURCE_STABILIZATION_TIME, callbackContext.getTimestamp(CUSTOM_DB_ENGINE_VERSION_REQUEST_IN_PROGRESS_AT), callbackContext.getTimestamp(CUSTOM_DB_ENGINE_VERSION_REQUEST_STARTED_AT));
callbackContext.calculateTimeDeltaInMinutes(CUSTOM_DB_ENGINE_VERSION_RESOURCE_STABILIZATION_TIME,
callbackContext.getTimestamp(CUSTOM_DB_ENGINE_VERSION_REQUEST_IN_PROGRESS_AT),
callbackContext.getTimestamp(CUSTOM_DB_ENGINE_VERSION_REQUEST_STARTED_AT));
}

protected DBEngineVersion fetchDBEngineVersion(final ResourceModel model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public Instant getTimestamp(final String label) {

@Override
public void calculateTimeDeltaInMinutes(final String label, final Instant currentTime, final Instant startTime){
double delta = Duration.between(currentTime, startTime).toMinutes();
double delta = Duration.between(startTime, currentTime).toMinutes();
timeDelta.put(label, delta);
}
}
37 changes: 24 additions & 13 deletions aws-rds-dbcluster/aws-rds-dbcluster.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
},
"BacktrackWindow": {
"description": "The target backtrack window, in seconds. To disable backtracking, set this value to 0.",
"default": 0,
"minimum": 0,
"type": "integer"
},
Expand Down Expand Up @@ -89,8 +88,7 @@
},
"DBClusterParameterGroupName": {
"description": "The name of the DB cluster parameter group to associate with this DB cluster.",
"type": "string",
"default": "default.aurora5.6"
"type": "string"
},
"DBSubnetGroupName": {
"description": "A DB subnet group that you want to associate with this DB cluster.",
Expand Down Expand Up @@ -128,6 +126,10 @@
"description": "A value that indicates whether to enable mapping of AWS Identity and Access Management (IAM) accounts to database accounts. By default, mapping is disabled.",
"type": "boolean"
},
"EnableLocalWriteForwarding": {
"description": "Specifies whether read replicas can forward write operations to the writer DB instance in the DB cluster. By default, write operations aren't allowed on reader DB instances.",
"type": "boolean"
},
"Engine": {
"description": "The name of the database engine to be used for this DB cluster. Valid Values: aurora (for MySQL 5.6-compatible Aurora), aurora-mysql (for MySQL 5.7-compatible Aurora), and aurora-postgresql",
"type": "string"
Expand Down Expand Up @@ -171,9 +173,8 @@
"description": "Contains the secret managed by RDS in AWS Secrets Manager for the master user password."
},
"MonitoringInterval": {
"description": "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB cluster. To turn off collecting Enhanced Monitoring metrics, specify 0. The default is 0.",
"type": "integer",
"default": 0
"description": "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB cluster. To turn off collecting Enhanced Monitoring metrics, specify 0. The default is not to enable Enhanced Monitoring.",
"type": "integer"
},
"MonitoringRoleArn": {
"description": "The Amazon Resource Name (ARN) for the IAM role that permits RDS to send Enhanced Monitoring metrics to Amazon CloudWatch Logs.",
Expand Down Expand Up @@ -221,8 +222,7 @@
},
"RestoreType": {
"description": "The type of restore to be performed. You can specify one of the following values:\nfull-copy - The new DB cluster is restored as a full copy of the source DB cluster.\ncopy-on-write - The new DB cluster is restored as a clone of the source DB cluster.",
"type": "string",
"default": "full-copy"
"type": "string"
},
"ServerlessV2ScalingConfiguration": {
"description": "Contains the scaling configuration of an Aurora Serverless v2 DB cluster.",
Expand Down Expand Up @@ -410,13 +410,13 @@
"/properties/DBClusterIdentifier": "$lowercase(DBClusterIdentifier)",
"/properties/DBClusterParameterGroupName": "$lowercase(DBClusterParameterGroupName)",
"/properties/DBSubnetGroupName": "$lowercase(DBSubnetGroupName)",
"/properties/EnableHttpEndpoint": "$lowercase($string(EngineMode)) = 'serverless' ? EnableHttpEndpoint : ($lowercase($string(Engine)) = 'aurora-postgresql' ? EnableHttpEndpoint : false )",
"/properties/EnableHttpEndpoint": "$lowercase($string(EngineMode)) = 'serverless' ? EnableHttpEndpoint : ($lowercase($string(Engine)) in ['aurora-postgresql', 'aurora-mysql'] ? EnableHttpEndpoint : false )",
"/properties/Engine": "$lowercase(Engine)",
"/properties/EngineVersion": "$join([$string(EngineVersion), \".*\"])",
"/properties/KmsKeyId": "$join([\"arn:(aws)[-]{0,1}[a-z]{0,2}[-]{0,1}[a-z]{0,3}:kms:[a-z]{2}[-]{1}[a-z]{3,10}[-]{0,1}[a-z]{0,10}[-]{1}[1-3]{1}:[0-9]{12}[:]{1}key\\/\", KmsKeyId])",
"/properties/MasterUserSecret/KmsKeyId": "$join([\"arn:(aws)[-]{0,1}[a-z]{0,2}[-]{0,1}[a-z]{0,3}:kms:[a-z]{2}[-]{1}[a-z]{3,10}[-]{0,1}[a-z]{0,10}[-]{1}[1-3]{1}:[0-9]{12}[:]{1}key\\/\", MasterUserSecret.KmsKeyId])",
"/properties/KmsKeyId": "$join([\"arn:.+?:kms:.+?:.+?:key\\/\", KmsKeyId])",
"/properties/MasterUserSecret/KmsKeyId": "$join([\"arn:.+?:kms:.+?:.+?:key\\/\", MasterUserSecret.KmsKeyId])",
"/properties/NetworkType": "$lowercase(NetworkType)",
"/properties/PerformanceInsightsKmsKeyId": "$join([\"arn:(aws)[-]{0,1}[a-z]{0,2}[-]{0,1}[a-z]{0,3}:kms:[a-z]{2}[-]{1}[a-z]{3,10}[-]{0,1}[a-z]{0,10}[-]{1}[1-3]{1}:[0-9]{12}[:]{1}key\\/\", PerformanceInsightsKmsKeyId])",
"/properties/PerformanceInsightsKmsKeyId": "$join([\"arn:.+?:kms:.+?:.+?:key\\/\", PerformanceInsightsKmsKeyId])",
"/properties/PreferredMaintenanceWindow": "$lowercase(PreferredMaintenanceWindow)",
"/properties/SnapshotIdentifier": "$lowercase(SnapshotIdentifier)",
"/properties/SourceDBClusterIdentifier": "$lowercase(SourceDBClusterIdentifier)",
Expand All @@ -428,7 +428,6 @@
"/properties/Endpoint",
"/properties/Endpoint/Address",
"/properties/Endpoint/Port",
"/properties/ReadEndpoint/Port",
"/properties/ReadEndpoint/Address",
"/properties/MasterUserSecret/SecretArn",
"/properties/StorageThroughput"
Expand Down Expand Up @@ -517,6 +516,7 @@
},
"delete": {
"permissions": [
"rds:AddTagsToResource",
"rds:CreateDBClusterSnapshot",
"rds:DeleteDBCluster",
"rds:DeleteDBInstance",
Expand All @@ -530,5 +530,16 @@
"rds:DescribeDBClusters"
]
}
},
"tagging": {
"taggable": true,
"tagOnCreate": true,
"tagUpdatable": true,
"cloudFormationSystemTags": true,
"tagProperty": "/properties/Tags",
"permissions": [
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource"
]
}
}
12 changes: 12 additions & 0 deletions aws-rds-dbcluster/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
"<a href="#enableglobalwriteforwarding" title="EnableGlobalWriteForwarding">EnableGlobalWriteForwarding</a>" : <i>Boolean</i>,
"<a href="#enablehttpendpoint" title="EnableHttpEndpoint">EnableHttpEndpoint</a>" : <i>Boolean</i>,
"<a href="#enableiamdatabaseauthentication" title="EnableIAMDatabaseAuthentication">EnableIAMDatabaseAuthentication</a>" : <i>Boolean</i>,
"<a href="#enablelocalwriteforwarding" title="EnableLocalWriteForwarding">EnableLocalWriteForwarding</a>" : <i>Boolean</i>,
"<a href="#engine" title="Engine">Engine</a>" : <i>String</i>,
"<a href="#enginelifecyclesupport" title="EngineLifecycleSupport">EngineLifecycleSupport</a>" : <i>String</i>,
"<a href="#enginemode" title="EngineMode">EngineMode</a>" : <i>String</i>,
Expand Down Expand Up @@ -103,6 +104,7 @@ Properties:
<a href="#enableglobalwriteforwarding" title="EnableGlobalWriteForwarding">EnableGlobalWriteForwarding</a>: <i>Boolean</i>
<a href="#enablehttpendpoint" title="EnableHttpEndpoint">EnableHttpEndpoint</a>: <i>Boolean</i>
<a href="#enableiamdatabaseauthentication" title="EnableIAMDatabaseAuthentication">EnableIAMDatabaseAuthentication</a>: <i>Boolean</i>
<a href="#enablelocalwriteforwarding" title="EnableLocalWriteForwarding">EnableLocalWriteForwarding</a>: <i>Boolean</i>
<a href="#engine" title="Engine">Engine</a>: <i>String</i>
<a href="#enginelifecyclesupport" title="EngineLifecycleSupport">EngineLifecycleSupport</a>: <i>String</i>
<a href="#enginemode" title="EngineMode">EngineMode</a>: <i>String</i>
Expand Down Expand Up @@ -382,6 +384,16 @@ _Type_: Boolean

_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)

#### EnableLocalWriteForwarding

Specifies whether read replicas can forward write operations to the writer DB instance in the DB cluster. By default, write operations aren't allowed on reader DB instances.

_Required_: No

_Type_: Boolean

_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)

#### Engine

The name of the database engine to be used for this DB cluster. Valid Values: aurora (for MySQL 5.6-compatible Aurora), aurora-mysql (for MySQL 5.7-compatible Aurora), and aurora-postgresql
Expand Down
Loading

0 comments on commit ebfe3f0

Please sign in to comment.