Skip to content

Commit 91db27b

Browse files
authored
Add AWS::DataSync::LocationHDFS resource and merge in other resource changes (#28)
1 parent 396a054 commit 91db27b

File tree

119 files changed

+4105
-269
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+4105
-269
lines changed

aws-datasync-agent/aws-datasync-agent.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"SecurityGroupArns": {
4747
"description": "The ARNs of the security group used to protect your data transfer task subnets.",
4848
"type": "array",
49+
"insertionOrder": false,
4950
"items": {
5051
"type": "string",
5152
"pattern": "^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):ec2:[a-z\\-0-9]*:[0-9]{12}:security-group/.*$",
@@ -55,6 +56,7 @@
5556
"SubnetArns": {
5657
"description": "The ARNs of the subnets in which DataSync will create elastic network interfaces for each data transfer task.",
5758
"type": "array",
59+
"insertionOrder": false,
5860
"items": {
5961
"type": "string",
6062
"pattern": "^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):ec2:[a-z\\-0-9]*:[0-9]{12}:subnet/.*$",
@@ -92,6 +94,7 @@
9294
"maxLength": 128
9395
}
9496
},
97+
"taggable": true,
9598
"additionalProperties": false,
9699
"required": [
97100
"ActivationKey"
@@ -109,6 +112,9 @@
109112
"/properties/SubnetArns",
110113
"/properties/VpcEndpointId"
111114
],
115+
"writeOnlyProperties": [
116+
"/properties/ActivationKey"
117+
],
112118
"handlers": {
113119
"create": {
114120
"permissions": [

aws-datasync-agent/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<dependency>
2424
<groupId>software.amazon.awssdk</groupId>
2525
<artifactId>bom</artifactId>
26-
<version>2.13.36</version>
26+
<version>2.16.68</version>
2727
<type>pom</type>
2828
<scope>import</scope>
2929
</dependency>
@@ -35,7 +35,7 @@
3535
<dependency>
3636
<groupId>software.amazon.cloudformation</groupId>
3737
<artifactId>aws-cloudformation-rpdk-java-plugin</artifactId>
38-
<version>2.0.2</version>
38+
<version>[2.0.0, 3.0.0]</version>
3939
</dependency>
4040
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
4141
<dependency>
@@ -48,7 +48,7 @@
4848
<dependency>
4949
<groupId>software.amazon.awssdk</groupId>
5050
<artifactId>datasync</artifactId>
51-
<version>2.13.36</version>
51+
<version>2.16.68</version>
5252
</dependency>
5353
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/ec2 -->
5454
<dependency>

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/CreateHandler.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import software.amazon.awssdk.services.datasync.model.InternalException;
77
import software.amazon.awssdk.services.datasync.model.InvalidRequestException;
88
import software.amazon.awssdk.services.datasync.model.DataSyncException;
9-
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
109
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
1110
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
1211
import software.amazon.cloudformation.proxy.*;
@@ -15,6 +14,7 @@
1514
import java.util.Map;
1615

1716
public class CreateHandler extends BaseHandlerStd {
17+
private static final String AWS_TAG_PREFIX = "aws:";
1818

1919
public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
2020
final AmazonWebServicesClientProxy proxy,
@@ -30,12 +30,24 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
3030
throw new CfnInvalidRequestException("AgentArn cannot be specified to create an Agent.");
3131
}
3232

33-
// Get combined resource- and stack-level tags, since CFN stack stags are not in the model.
3433
Map<String, String> tagList = request.getDesiredResourceTags();
3534
if (tagList == null) {
3635
tagList = new HashMap<String, String>();
3736
}
3837

38+
// Check for invalid requested system tags.
39+
for (String key : tagList.keySet()) {
40+
if (key.trim().toLowerCase().startsWith(AWS_TAG_PREFIX)) {
41+
throw new CfnInvalidRequestException(key + " is an invalid key. aws: prefixed tag key names cannot be requested.");
42+
}
43+
}
44+
45+
// Retrieve default stack-level tags with aws:cloudformation prefix.
46+
Map<String, String> systemTagList = request.getSystemTags();
47+
if (systemTagList != null) {
48+
tagList.putAll(systemTagList);
49+
}
50+
3951
CreateAgentRequest createAgentRequest = Translator.translateToCreateRequest(model, tagList);
4052
CreateAgentResponse response;
4153
try {
@@ -46,7 +58,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
4658
} catch (InternalException e) {
4759
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
4860
} catch (DataSyncException e) {
49-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
61+
throw Translator.translateDataSyncExceptionToCfnException(e);
5062
}
5163

5264
ResourceModel returnModel = ResourceModel.builder()

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/DeleteHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
2929
} catch (InternalException e) {
3030
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
3131
} catch (DataSyncException e) {
32-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
32+
throw Translator.translateDataSyncExceptionToCfnException(e);
3333
}
3434

3535
return ProgressEvent.defaultSuccessHandler(null);

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/ListHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import software.amazon.awssdk.services.datasync.model.InvalidRequestException;
88
import software.amazon.awssdk.services.datasync.model.ListAgentsRequest;
99
import software.amazon.awssdk.services.datasync.model.ListAgentsResponse;
10-
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
1110
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
1211
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
1312
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
@@ -41,7 +40,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
4140
} catch (InternalException e) {
4241
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
4342
} catch (DataSyncException e) {
44-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
43+
throw Translator.translateDataSyncExceptionToCfnException(e);
4544
}
4645

4746
List<ResourceModel> models = new ArrayList<>();

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/ReadHandler.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88
import software.amazon.awssdk.services.datasync.model.InvalidRequestException;
99
import software.amazon.awssdk.services.datasync.model.ListTagsForResourceRequest;
1010
import software.amazon.awssdk.services.datasync.model.ListTagsForResourceResponse;
11-
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
1211
import software.amazon.cloudformation.exceptions.CfnNotFoundException;
1312
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
1413
import software.amazon.cloudformation.proxy.*;
1514

1615
import java.util.HashSet;
1716
import java.util.Set;
17+
import java.util.stream.Collectors;
1818

1919

2020
public class ReadHandler extends BaseHandlerStd {
21+
private static final String AWS_CFN_TAG_PREFIX = "aws:cloudformation:";
2122

2223
@Override
2324
public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
@@ -40,7 +41,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
4041
} catch (InternalException e) {
4142
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
4243
} catch (DataSyncException e) {
43-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
44+
throw Translator.translateDataSyncExceptionToCfnException(e);
4445
}
4546

4647
// Since tags are not returned by the DescribeAgent call but can be modified,
@@ -55,23 +56,25 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
5556
} catch (InternalException e) {
5657
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
5758
} catch (DataSyncException e) {
58-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
59+
throw Translator.translateDataSyncExceptionToCfnException(e);
5960
}
6061

61-
Set<Tag> tags = new HashSet<Tag>();
62+
Set<Tag> allTags = new HashSet<Tag>();
6263
if (tagsResponse.tags() != null) {
63-
tags = Translator.translateTagListEntries(tagsResponse.tags());
64+
allTags = Translator.translateTagListEntries(tagsResponse.tags());
6465
}
66+
final Set<Tag> userTags = allTags.stream()
67+
.filter(tag -> !tag.getKey().startsWith(AWS_CFN_TAG_PREFIX))
68+
.collect(Collectors.toSet());
6569

6670
ResourceModel returnModel = ResourceModel.builder()
6771
.agentArn(response.agentArn())
6872
.agentName(response.name())
69-
.activationKey(model.getActivationKey())
70-
.securityGroupArns(model.getSecurityGroupArns())
71-
.subnetArns(model.getSubnetArns())
72-
.vpcEndpointId(model.getVpcEndpointId())
73+
.securityGroupArns(response.privateLinkConfig() == null ? null : response.privateLinkConfig().securityGroupArns())
74+
.subnetArns(response.privateLinkConfig() == null ? null : response.privateLinkConfig().subnetArns())
75+
.vpcEndpointId(response.privateLinkConfig() == null ? null : response.privateLinkConfig().vpcEndpointId())
7376
.endpointType(response.endpointType() == null ? null : response.endpointType().toString())
74-
.tags(tags)
77+
.tags(userTags)
7578
.build();
7679

7780
return ProgressEvent.defaultSuccessHandler(returnModel);

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/Translator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.util.stream.Collectors;
88

99
import software.amazon.awssdk.services.datasync.model.*;
10+
import software.amazon.cloudformation.exceptions.BaseHandlerException;
11+
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
12+
import software.amazon.cloudformation.exceptions.CfnThrottlingException;
1013

1114
public class Translator {
1215

@@ -108,4 +111,11 @@ static Set<Tag> translateMapToTags(final Map<String, String> tags) {
108111
}).collect(Collectors.toSet());
109112
}
110113

114+
public static BaseHandlerException translateDataSyncExceptionToCfnException(DataSyncException e) {
115+
if (e.isThrottlingException()) {
116+
return new CfnThrottlingException(e);
117+
} else {
118+
return new CfnGeneralServiceException(e.getMessage(), e.getCause());
119+
}
120+
}
111121
}

aws-datasync-agent/src/main/java/software/amazon/datasync/agent/UpdateHandler.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import software.amazon.awssdk.services.datasync.model.TagResourceRequest;
1111
import software.amazon.awssdk.services.datasync.model.UntagResourceRequest;
1212
import software.amazon.awssdk.services.datasync.model.UpdateAgentRequest;
13-
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
13+
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
1414
import software.amazon.cloudformation.exceptions.CfnNotFoundException;
1515
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
1616
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
@@ -24,6 +24,7 @@
2424
import java.util.stream.Collectors;
2525

2626
public class UpdateHandler extends BaseHandler<CallbackContext> {
27+
private static final String AWS_TAG_PREFIX = "aws:";
2728

2829
@Override
2930
public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
@@ -47,7 +48,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
4748
} catch (InternalException e) {
4849
throw new CfnServiceInternalErrorException(e.getMessage(), e.getCause());
4950
} catch (DataSyncException e) {
50-
throw new CfnGeneralServiceException(e.getMessage(), e.getCause());
51+
throw Translator.translateDataSyncExceptionToCfnException(e);
5152
}
5253

5354
// Since tags are not maintained by the update request, we must manually calculate
@@ -67,6 +68,7 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
6768
prevTagList.keySet(),
6869
tagList.keySet()
6970
);
71+
7072
if (!keysToRemove.isEmpty()) {
7173
UntagResourceRequest untagResourceRequest = Translator.translateToUntagResourceRequest(
7274
keysToRemove, currentModel.getAgentArn());
@@ -87,6 +89,16 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
8789
}).collect(Collectors.toSet());
8890
tagsToAdd.addAll(Translator.translateMapToTags(mapDifference.entriesOnlyOnLeft()));
8991

92+
for (Tag tag: tagsToAdd) {
93+
if (tag.getKey().trim().toLowerCase().startsWith(AWS_TAG_PREFIX)) {
94+
throw new CfnInvalidRequestException(tag.getKey() + " is an invalid key. aws: prefixed tag key names cannot be requested.");
95+
}
96+
}
97+
98+
if (request.getPreviousSystemTags() == null && request.getSystemTags() != null) {
99+
tagsToAdd.addAll(Translator.translateMapToTags(request.getSystemTags()));
100+
}
101+
90102
if (!tagsToAdd.isEmpty()) {
91103
TagResourceRequest tagResourceRequest = Translator.translateToTagResourceRequest(
92104
tagsToAdd, currentModel.getAgentArn());

aws-datasync-agent/src/test/java/software/amazon/datasync/agent/CreateHandlerTest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
import org.mockito.junit.jupiter.MockitoExtension;
1717
import software.amazon.cloudformation.proxy.*;
1818

19+
import java.util.Arrays;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
1923
import static org.junit.jupiter.api.Assertions.assertThrows;
2024
import static org.mockito.ArgumentMatchers.any;
2125

@@ -76,11 +80,31 @@ public void handleRequest_SimpleSuccess() {
7680
assertThat(response.getCallbackContext()).isNull();
7781
assertThat(response.getCallbackDelaySeconds()).isEqualTo(0);
7882
assertThat(response.getResourceModels()).isNull();
79-
assertThat(response.getResourceModel()).hasFieldOrPropertyWithValue("agentName", "MyAgent");
8083
assertThat(response.getMessage()).isNull();
8184
assertThat(response.getErrorCode()).isNull();
8285
}
8386

87+
@Test
88+
public void handleRequest_InvalidSystemTagRequest() {
89+
final CreateHandler handler = new CreateHandler();
90+
91+
final ResourceModel model = buildDefaultModel();
92+
93+
Set<Tag> TagsWithSystemTag = new HashSet<Tag>(Arrays.asList(
94+
Tag.builder().key("aws:cloudformation:stackid").value("100").build()
95+
));
96+
97+
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
98+
.desiredResourceState(model)
99+
.desiredResourceTags(Translator.translateTagsToMap(TagsWithSystemTag))
100+
.build();
101+
102+
assertThrows(CfnInvalidRequestException.class, () -> {
103+
handler.handleRequest(proxy, request, null, proxyClient, logger);
104+
} );
105+
}
106+
107+
84108
@Test
85109
public void handleRequest_FailureInvalidRequest() {
86110
final CreateHandler handler = new CreateHandler();

0 commit comments

Comments
 (0)