Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for AWS::IoT::MitigationAction #15

Merged

Conversation

saurabh14rajput
Copy link
Contributor

@saurabh14rajput saurabh14rajput commented Nov 5, 2020

Notes
Mitigation actions allow you to take actions for mitigating issues that were found during an audit. AWS IoT Device Defender provides predefined actions for the different audit checks. You configure those actions for your AWS account and then apply them to a set of findings.
Documentation for Mitigation actions can be found at https://docs.aws.amazon.com/iot/latest/developerguide/device-defender-mitigation-actions.html
Most of the complications for this resources are around tagging (in handlers, we have to call separate tag management APIs).

This change includes: model, handlers, unit tests, inputs for contract tests.

Testing
Unit tests - 80%+ coverage.
All contract tests passed - except for the ones that failed due to known issues in the contract tests library.
Ran pre-commit run --all-files, mvn verify successfully.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Copy link
Contributor

@anton-aws anton-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a description to this PR, can be something similar to what we have in the one for Dimensions.

]
},
"EnableIoTLoggingParams": {
"description": "Allows logging",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use the descriptions from https://docs.aws.amazon.com/iot/latest/apireference/API_MitigationActionParams.html#iot-Type-MitigationActionParams and make sure to have one for every property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
},
"AddThingsToThingGroupParams": {
"description": "Allows adding things that triggered the mitigation action to thing groups",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: let's stay consistent and add periods at the end of all descriptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* - object translation to/from aws sdk
* - resource model construction for read/list handlers
*/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: There seem to be some extra new lines and inconsistent indentation depths. Let's reformat all the files that need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

"ActionName": "CfnContractTest",
"RoleArn": "arn:aws:iam::072938559174:role/Admin",
"ActionParams":
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's run pre-commit run --all-files, that should reformat all the json files to be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import java.sql.Date;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an accidental import. Let's run "organize imports" for all files that need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 3 to 4
// TODO: replace all usage of SdkClient with your service client type, e.g; YourServiceAsyncClient
// import software.amazon.awssdk.services.yourservice.YourServiceAsyncClient;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental leftover

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

software.amazon.awssdk.services.iot.model.PublishFindingToSnsParams.builder()
.topicArn("arn:aws:sns:us-east-1:072938559174:myTopic.fifo")
.build();
protected static final software.amazon.awssdk.services.iot.model.MitigationActionParams SDK_ACTION_PARAMS2 =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: IntelliJ pointed out to me that this one is unused. If there's no need for it, let's remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

}

@Test
void translateActionParamsToSdkTest() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Let's verify conversion for all the mitigation actions, not just ReplaceDefaultPolicyVersion. Same below.
  2. Minor: it would be nice to keep the test naming convention as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

.collect(Collectors.toSet());
}

static MitigationActionParams translateActionParamsToSdk(ActionParams actionParams) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider a case where customer fills out all the actions (which is incorrect). Looks like this method will just fill out AddThingsToThingGroup and return. How about we pass the customer's template the way it is and let the service throw the right exception? If so, maybe drop the else in else ifs. And let's have a unit test to cover that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Done

Comment on lines 177 to 178
.addThingsToThingGroupParams(addThingsToThingGroupParams)
.addThingsToThingGroupParams(addThingsToThingGroupParams)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an accidental copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

}
else if (actionParams.enableIoTLoggingParams() != null) {
enableIoTLoggingParams = EnableIoTLoggingParams.builder()
.logLevel(actionParams.enableIoTLoggingParams().logLevel().toString())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: the SDK provides a method logLevelAsString, it's nice for this use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Changed.

]
},
"update": {
"permissions": [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add iam:PassRole here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

},
"additionalProperties": false,
"required": [
"ActionName",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the ActionName be optional for this schema? CreateHandler generates an ActionName if it's not provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Changed.

@@ -1,239 +1,248 @@
{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON files are showing big delta because of fixing indentation using pre-commit hook.

Comment on lines 50 to 53
} else if (e instanceof InvalidRequestException) {
return new CfnInvalidRequestException(e);
} else if (e instanceof LimitExceededException) {
return new CfnServiceLimitExceededException(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: somehow the indentations in this file are size 2 instead of 4 like everywhere else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It is weird. Auto indentation did not work either.
Fixed it with this(In case we face again): "Settings | Editor | Code Style" -- try disabling "Detect and use existing file indents for editing" in case if you have it enabled (it is by default). NOTE: re-opening file in editor may be required.

// Like most services, we don't require an explicit resource name in the template,
// and, if it's not provided, generate one based on the stack ID and logical ID.
if (StringUtils.isBlank(model.getActionName())) {
// TODO: include stack-id in the generated name. Will do it once the new release of the java plugin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do this as part of this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did already made that change. Missed taking out the TODO. Removed now.

"MitigationActionId": {
"type": "string"
},
"CreationDate": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, let's remove the CreationDate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Yet we should, otherwise the resource wouldn't equate the template.
Set<Tag> currentTags = listTags(proxy, resourceArn, logger);

// getDesiredResourceTags includes model+stack-level tags, reference: https://tinyurl.com/y2p8medk
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a better link https://tinyurl.com/y55mqrnc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

"typeName": "AWS::IoT::MitigationAction",
"description": "Mitigation actions can be used to take actions to mitigate issues that were found during an audit.",
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-iot.git",
"definitions": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add "additionalProperties": false for all entries with type=object

"RoleArn": "{{RoleForDeviceDefenderAuditArn}}",
"ActionParams": {
"PublishFindingToSnsParams": {
"TopicArn": "{{TopicForDeviceDefenderAuditCreateArn}}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

@@ -0,0 +1,15 @@
{
"ActionName": "CfnContractTest",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be nice to have a test for every single action that we support, else how do you know that the definition of one of the actions isn't broken?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an integ test for them in the integ test package.

Comment on lines +14 to +16
public class HandlerUtils {

public static List<software.amazon.awssdk.services.iot.model.Tag> listTags(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to pull the common code to a common package, it would be painful for now but reduces the effort for future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened an issue about this with the cfn team: aws-cloudformation/cloudformation-cli-java-plugin#335

Comment on lines +38 to +39
@ExtendWith(MockitoExtension.class)
public class CreateHandlerTest {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add tests for every single action that we support in both CREATE and UPDATE paths

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, saw that you added tests for translator

@@ -0,0 +1,253 @@
{
"typeName": "AWS::IoT::MitigationAction",
"description": "Mitigation actions can be used to take actions to mitigate issues that were found during an audit.",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mitigation Action isn't specific to Audit, now even ML Detect uses it. So lets paraphrase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

},
"UpdateCACertificateParams": {
"type": "object",
"description": "Parameters to define a mitigation action that changes the state of the CA certificate to inactive.s",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo s/inactive.s/inactive./g

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -0,0 +1,15 @@
{
"ActionName": "CfnContractTest",
"RoleArn": "{{RoleForDeviceDefenderAuditArn}}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not use "Audit" in names of even the test resource. Reason being MitigationActions isn't specific to Audit anymore (it's a common resource to both Audit/Detect)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment on lines 3 to 7
"RoleArn": "{{RoleForDeviceDefenderAuditArn}}",
"ActionParams": {
"PublishFindingToSnsParams": {
"TopicArn": "{{TopicForDeviceDefenderAuditCreateArn}}"
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, do not use Audit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -0,0 +1,46 @@
AWSTemplateFormatVersion: 2010-09-09
Description: 'Resources for running the AccountAuditConfiguration contract tests'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Description seems wrong. Should say "Mitigation Actions contract tests"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 26 to 45
Outputs:
RoleForDeviceDefenderAuditOutput:
Value:
Fn::GetAtt: [RoleForDeviceDefenderAudit, Arn]
Export:
Name: RoleForDeviceDefenderAuditArn
TopicForDeviceDefenderAuditCreateOutput:
Value:
Ref: TopicForDeviceDefenderAuditCreate
Export:
Name: TopicForDeviceDefenderAuditCreateArn
TopicForDeviceDefenderAuditUpdateOutput:
Value:
Ref: TopicForDeviceDefenderAuditUpdate
Export:
Name: TopicForDeviceDefenderAuditUpdateArn
AccountIdOutput:
Value:
Fn::Sub: "${AWS::AccountId}"
Export:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. It doesn't matter that much, but why not use a generic name that doesn't contain Audit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed


if (!StringUtils.isEmpty(model.getMitigationActionId())) {
logger.log(String.format("MitigationActionId is read-only, but the caller passed %s.",
model.getMitigationActionArn()));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect field name, should be MitigationActionId.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Comment on lines +54 to +55
@Test
public void handleRequest_HappyCase_VerifyRequestResponse() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all tests lets verify that no more interactions were made with the proxy mock.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

assertThat(submittedRequest.actionName().length() > 20).isTrue();
}

// TODO: test system tags when the src code is ready

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line I'd say. When we add support then it's possible we don't even look at this line and just forget about it. Hardly people check for TODOs in code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@anton-aws anton-aws merged commit d5a82f9 into aws-cloudformation:master Dec 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants