From e0b8298316fc550a0795919116099304b3cad2a0 Mon Sep 17 00:00:00 2001 From: Trevor Schiavone Date: Wed, 24 Jan 2024 13:44:01 +0100 Subject: [PATCH 1/3] initial commit of Config Proactive Evaluation --- hooks/Config_ProactiveEvaluation/.gitignore | 33 ++ hooks/Config_ProactiveEvaluation/README.md | 94 ++++ .../cfn-config-rules-sample.json | 301 +++++++++++++ .../cfn-config-sample.json | 174 +++++++ .../cfn-eip-not-attached-fail.json | 12 + .../cfn-lambda-not-in-vpc-fail.json | 60 +++ .../cfn-s3-logging-not-enabled.json | 8 + .../cfn-sns-no-encrypted-kms.json | 8 + .../hooks/.rpdk-config | 29 ++ .../hooks/README.md | 47 ++ .../awssamples-configproactiveeval-hook.json | 64 +++ .../hooks/hook-role.yaml | 42 ++ .../hooks/inputs/inputs_1_invalid.json | 57 +++ .../hooks/inputs/inputs_1_pre_create.json | 98 ++++ .../hooks/inputs/inputs_1_pre_update.json | 99 ++++ .../hooks/lombok.config | 1 + .../Config_ProactiveEvaluation/hooks/pom.xml | 253 +++++++++++ .../hook/BaseHookHandlerStd.java | 105 +++++ .../hook/CallbackContext.java | 13 + .../hook/ClientBuilder.java | 22 + .../hook/Configuration.java | 14 + .../hook/PreCreateHookHandler.java | 28 ++ .../hook/PreUpdateHookHandler.java | 28 ++ .../hook/ProactiveComplianceHandler.java | 158 +++++++ .../hook/RequestBuilders.java | 52 +++ .../hooks/src/resources/log4j2.xml | 17 + .../hook/BaseHookHandlerStdTest.java | 425 ++++++++++++++++++ .../hook/PreCreateHookHandlerTest.java | 66 +++ .../hook/PreUpdateHookHandlerTest.java | 65 +++ .../hooks/template.yml | 23 + 30 files changed, 2396 insertions(+) create mode 100644 hooks/Config_ProactiveEvaluation/.gitignore create mode 100644 hooks/Config_ProactiveEvaluation/README.md create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-rules-sample.json create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-sample.json create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-eip-not-attached-fail.json create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-lambda-not-in-vpc-fail.json create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-s3-logging-not-enabled.json create mode 100644 hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-sns-no-encrypted-kms.json create mode 100644 hooks/Config_ProactiveEvaluation/hooks/.rpdk-config create mode 100644 hooks/Config_ProactiveEvaluation/hooks/README.md create mode 100644 hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json create mode 100644 hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml create mode 100644 hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json create mode 100644 hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json create mode 100644 hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json create mode 100644 hooks/Config_ProactiveEvaluation/hooks/lombok.config create mode 100644 hooks/Config_ProactiveEvaluation/hooks/pom.xml create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java create mode 100644 hooks/Config_ProactiveEvaluation/hooks/template.yml diff --git a/hooks/Config_ProactiveEvaluation/.gitignore b/hooks/Config_ProactiveEvaluation/.gitignore new file mode 100644 index 00000000..111ac0c7 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/.gitignore @@ -0,0 +1,33 @@ +# macOS +.DS_Store +._* + +# Maven outputs +.classpath + +# IntelliJ +*.iml +.idea +out.java +out/ +.settings +.project + +# VS Code +.vscode + +# auto-generated files +/hooks/target/ +/hooks/docs/* +*.zip + +# contract testing +*.hypothesis +*.pytest_cache/ + + +# our logs +rpdk.log* + +# contains credentials +sam-tests/ \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/README.md b/hooks/Config_ProactiveEvaluation/README.md new file mode 100644 index 00000000..5ba3e08e --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/README.md @@ -0,0 +1,94 @@ +# AWSSamples::ConfigProactiveEval::Hook + +- [Overview](#overview) + +- [Deployment](#deployment) + +- [Usage](#usage) + +## Overview +[AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html) is a service that allows you to continually assess, audit, and evaluate the configuration of your resources. + +One of the ways Config helps you to evaluate resources is through the use of **Config rules**. A Config rule evaluates your resource against a desired configuration and lets you know if the resource meets the configuration requirements. + +Config rules can be run in two [evaluation modes](https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config-rules.html#aws-config-rules-evaluation-modes): **Detective mode** which evaluates resources that are already deployed, and [**Proactive mode**](https://aws.amazon.com/blogs/aws/new-aws-config-rules-now-support-proactive-compliance/) which evaluates resource properties before a resource is deployed. + +[AWS CloudFormation hooks](https://aws.amazon.com/blogs/mt/proactively-keep-resources-secure-and-compliant-with-aws-cloudformation-hooks/) allow customers to run code before creating, updating, or deleting resources with CloudFormation and can be used to provide automatic and proactive enforcement of requirements. Business requirement logic can be written directly in the hook, but hooks are also capable of calling external services. + +This CloudFormation hook calls the AWS Config proactive evaluation endpoint to check resources against Config rules that are enabled in the account. This allows customers to manage their resource configuration requirements directly in AWS Config rather than writing the business requirements in the code for the hook. + +## Deployment + +### Prerequisites +1. Building and registering this hook requires: + + a. A version of the Java JDK of 8 or higher, such as [Amazon Corretto](https://aws.amazon.com/corretto). + + b. [Maven](https://maven.apache.org/) + + c. The [CloudFormation CLI](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html) + +2. Evaluating resource with this hook requires: + + a. AWS Config enabled in the AWS Account and Region where you will be registering the hook and deploying resources. A sample CloudFormation template to enable Config can be found at [cloudformation-samples/cfn-config-sample.json](./cloudformation-samples/cfn-config-sample.json) + + b. AWS Config rules enabled in **proactive mode** in the AWS Account and Region where you enabled Config. A sample CloudFormation template to enable a subset of Config rules can be found at [cloudformation-samples/cfn-config-rules-sample.json](./cloudformation-samples/cfn-config-rules-sample.json) + + +### Register the hook +The hook registration process is described in full detail in the [Registering hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/registering-hooks.html) section of the CloudFormation CLI developer guide. + +When you reach the **Configure hooks** section of the registration process, use the following commands to configure the hook (instead of the one listed in the documentation). + +1. Create a typeConfiguration.json file. + +In this case we are configuring the hook to return a success state and have CloudFormation continue with resource creation in the event that AWS Config returns Insufficient Data when evaluation the resource. + +To change this behavior modify the OutcomeForComplianceTypeInsufficientData property to FAIL +``` +cat < typeConfiguration.json +{ + "CloudFormationConfiguration": { + "HookConfiguration": { + "TargetStacks": "ALL", + "FailureMode": "FAIL", + "Properties": { + "OutcomeForComplianceTypeInsufficientData": "PASS" + } + } + } +} +EOF +``` + +**Note:** The hook is currently configured to run when the following resource types are deployed. These resource types correspond with all resource types that currently have [rules to support proactive evaluation](https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-evaluation-mode.html#heading:r1d:) in AWS Config. +``` +"AWS::ApiGateway::Stage", +"AWS::AutoScaling::AutoScalingGroup", +"AWS::EC2::EIP", +"AWS::EC2::Instance", +"AWS::EC2::Subnet", +"AWS::Elasticsearch::Domain", +"AWS::Lambda::Function", +"AWS::RDS::DBInstance", +"AWS::Redshift::Cluster", +"AWS::S3::Bucket", +"AWS::SNS::Topic" +``` + +To configure the hook to only run for a specific subset of this list you can configure a `targetFilter` in the typeConfiguration. See [targetFilter](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-structure.html#hooks-targetfilters) in the Hook configuration schema user guide for details. + +2. Specify the hook configuration +``` +$ aws cloudformation set-type-configuration --configuration file://typeConfiguration.json --type-arn $HOOK_TYPE_ARN +``` + +## Usage + +### Testing +The hook can be tested by provisioning CloudFormation stacks. Sample CloudFormation templates have been provided to test the hook once it is deployed. These can be found in the [cloudformation-samples](./cloudformation-samples/) directory. When using the provided sample Config rules template, these resource will all fail to create. + +Note that there is a [prerequisite](#prerequisites) to enable AWS Config and proactive Config rules to properly test the hook. + +### Clean up +For information on how to update, deactivate, or deregister your hook, see [Managing Hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/managing-hooks-python.html) in the AWS CloudFormation Hooks User Guide. diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-rules-sample.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-rules-sample.json new file mode 100644 index 00000000..dc2fed5b --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-rules-sample.json @@ -0,0 +1,301 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "CloudFormation template that enables all AWS Config rules that support Proactive Evaluations https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-evaluation-mode.html", + "Resources": { + "ConfigRuleApiGwXrayEnabled": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "API_GW_XRAY_ENABLED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleAutoscalingGroupElbHealthcheckRequired": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "AUTOSCALING_GROUP_ELB_HEALTHCHECK_REQUIRED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleEc2InstanceMultipleEniCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "EC2_INSTANCE_MULTIPLE_ENI_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleEipAttached": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "EIP_ATTACHED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleElasticsearchNodeToNodeEncryptionCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleLambdaFunctionSettingsCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "LAMBDA_FUNCTION_SETTINGS_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ], + "InputParameters": { + "runtime": "java8, java11, java17, java21" + } + } + }, + "ConfigRuleRdsAutomaticMinorVersionUpgradeEnabled": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleRdsEnhancedMonitoringEnabled": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "RDS_ENHANCED_MONITORING_ENABLED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleRdsInstancePublicAccessCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "RDS_INSTANCE_PUBLIC_ACCESS_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleRdsMultiAzSupport": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "RDS_MULTI_AZ_SUPPORT" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleRdsStorageEncrypted": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "RDS_STORAGE_ENCRYPTED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleRedshiftClusterMaintenancesettingsCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ], + "InputParameters": { + "allowVersionUpgrade": "TRUE" + } + } + }, + "ConfigRuleRedshiftClusterPublicAccessCheck": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleS3BucketLoggingEnabled": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "S3_BUCKET_LOGGING_ENABLED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleSnsEncryptedKms": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "SNS_ENCRYPTED_KMS" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleSubnetAutoAssignPublicIpDisabled": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + }, + "ConfigRuleLambdaInsideVpc": { + "Type": "AWS::Config::ConfigRule", + "Properties": { + "Source": { + "Owner": "AWS", + "SourceIdentifier": "LAMBDA_INSIDE_VPC" + }, + "EvaluationModes": [ + { + "Mode": "DETECTIVE" + }, + { + "Mode": "PROACTIVE" + } + ] + } + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-sample.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-sample.json new file mode 100644 index 00000000..16756cf2 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-config-sample.json @@ -0,0 +1,174 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "AWS CloudFormation template to enable AWS Config in an account. An Amazon S3 bucket is used as the delivery channel. Recording is only enabled for resources that currently support proactive evaluations.", + "Parameters": { + "ConfigBucketName": { + "Description": "The name of the Amazon S3 that will be used to store Configuration snapshots", + "Type": "String" + }, + "DeliveryFrequency": { + "Description": "The frequency to deliver AWS Config snapshots to S3", + "Type": "String", + "AllowedValues": [ + "One_Hour", + "Three_Hours", + "Six_Hours", + "Twelve_Hours", + "TwentyFour_Hours" + ], + "Default": "Six_Hours" + } + }, + "Resources": { + "ConfigS3Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Ref": "ConfigBucketName" + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + }, + "LifecycleConfiguration": { + "Rules": [ + { + "Id": "TransitionAndExpire", + "Status": "Enabled", + "Transitions": [ + { + "TransitionInDays": 30, + "StorageClass": "STANDARD_IA" + }, + { + "TransitionInDays": 90, + "StorageClass": "GLACIER" + } + ], + "ExpirationInDays": 365 + } + ] + } + } + }, + "ConfigRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "RoleName": { + "Fn::Sub": "config-role-${AWS::AccountId}-${AWS::Region}" + }, + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "config.amazonaws.com" + ] + } + } + ] + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWS_ConfigRole" + ] + } + }, + "ConfigRolePolicy": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyName": "config-policy", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Resource": [ + { + "Fn::Sub": "${ConfigS3Bucket.Arn}/AWSLogs/${AWS::AccountId}/*" + } + ], + "Condition": { + "StringLike": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetBucketAcl" + ], + "Resource": [ + { + "Fn::GetAtt": [ + "ConfigS3Bucket", + "Arn" + ] + } + ] + } + ] + }, + "Roles": [ + { + "Ref": "ConfigRole" + } + ] + } + }, + "ConfigRecorder": { + "Type": "AWS::Config::ConfigurationRecorder", + "Properties": { + "Name": "ConfigRecorder", + "RecordingGroup": { + "RecordingStrategy": { + "UseOnly": "INCLUSION_BY_RESOURCE_TYPES" + }, + "ResourceTypes": [ + "AWS::ApiGateway::Stage", + "AWS::AutoScaling::AutoScalingGroup", + "AWS::EC2::EIP", + "AWS::EC2::Instance", + "AWS::EC2::Subnet", + "AWS::Elasticsearch::Domain", + "AWS::Lambda::Function", + "AWS::RDS::DBInstance", + "AWS::Redshift::Cluster", + "AWS::S3::Bucket", + "AWS::SNS::Topic" + ] + }, + "RoleARN": { + "Fn::GetAtt": [ + "ConfigRole", + "Arn" + ] + } + } + }, + "ConfigDeliveryChannel": { + "Type": "AWS::Config::DeliveryChannel", + "Properties": { + "S3BucketName": { + "Ref": "ConfigBucketName" + }, + "ConfigSnapshotDeliveryProperties": { + "DeliveryFrequency": { + "Ref": "DeliveryFrequency" + } + } + } + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-eip-not-attached-fail.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-eip-not-attached-fail.json new file mode 100644 index 00000000..ec341065 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-eip-not-attached-fail.json @@ -0,0 +1,12 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "EIP that is not attached to an instance", + "Resources": { + "ElasticIP": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc" + } + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-lambda-not-in-vpc-fail.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-lambda-not-in-vpc-fail.json new file mode 100644 index 00000000..bfba6fcf --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-lambda-not-in-vpc-fail.json @@ -0,0 +1,60 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + "Description" : "Lambda that is not in a VPC", + "Resources": { + "HelloWorldLambda": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": { + "Fn::Join": [ + "\n", + [ + "export const handler = async (event) => {", + " const response = {", + " statusCode: 200,", + " body: JSON.stringify('Hello from Lambda!'),", + " };", + " return response;", + "};" + ] + ] + } + }, + "FunctionName": "HelloWorldLambda-NotInVPC", + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "LambdaExecutionRole", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + } + }, + "LambdaExecutionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + } + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-s3-logging-not-enabled.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-s3-logging-not-enabled.json new file mode 100644 index 00000000..27ef37bc --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-s3-logging-not-enabled.json @@ -0,0 +1,8 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Resources": { + "MyS3Bucket": { + "Type": "AWS::S3::Bucket" + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-sns-no-encrypted-kms.json b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-sns-no-encrypted-kms.json new file mode 100644 index 00000000..899e0e56 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/cloudformation-samples/cfn-sns-no-encrypted-kms.json @@ -0,0 +1,8 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Resources": { + "MySnsTopic": { + "Type": "AWS::SNS::Topic" + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/hooks/.rpdk-config b/hooks/Config_ProactiveEvaluation/hooks/.rpdk-config new file mode 100644 index 00000000..a6cf3725 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/.rpdk-config @@ -0,0 +1,29 @@ +{ + "artifact_type": "HOOK", + "typeName": "AWSSamples::ConfigProactiveEval::Hook", + "language": "java", + "runtime": "java11", + "entrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapper::handleRequest", + "testEntrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapper::testEntrypoint", + "settings": { + "version": false, + "subparser_name": null, + "verbose": 0, + "force": false, + "type_name": null, + "artifact_type": null, + "endpoint_url": null, + "region": null, + "target_schemas": [], + "profile": null, + "namespace": [ + "com", + "awssamples", + "configproactiveeval", + "hook" + ], + "codegen_template_path": "guided_aws", + "protocolVersion": "2.0.0" + }, + "executableEntrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapperExecutable" +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/README.md b/hooks/Config_ProactiveEvaluation/hooks/README.md new file mode 100644 index 00000000..8fa1faa7 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/README.md @@ -0,0 +1,47 @@ +# Hook development notes + +## Prerequisites + +Building and registering this hook requires: + 1. A version of the Java JDK of 8 or higher, such as [Amazon Corretto](https://aws.amazon.com/corretto). + 2. [Maven](https://maven.apache.org/) + 3. The [CloudFormation CLI](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html) + +## Tests + +### Unit tests +Run unit tests with the following command +``` +mvn clean verify +``` + +### Contract tests +This project also contains contract tests which are a requirement to [publish hooks for public use](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-publishing.html). + +#### Prerequisites +1. Running contract tests requires the AWS SAM. See [Installing the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) for installation instructions. + +2. Set up a retry configuration in your `~/.aws/config` global AWS configuration file. Add the `retry_mode` and `max_attempts` configurations to the profile you'll use for testing (in this case **\[default\]**): +``` +[default] +retry_mode = standard +max_attempts = 15 +``` +For more information see [AWS CLI retries](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html) + +3. Run the following commands to create a `~/.cfn-cli` directory and add the `typeConfiguration.json` file (see **Register the Hook** in the top level [README.md](../README.md) for more details on this file. +``` +mkdir ~/.cfn-cli/ +cp typeConfiguration.json ~/.cfn-cli/typeConfiguration.json +``` + +#### Running the tests +1. Open a terminal, navigate to the project `/hooks` directory, and run the following command +``` +sam local start-lambda +``` + +2. Open a second terminal, navigate to the project `/hooks` directory, and run the following command +``` +cfn generate && mvn clean package && cfn test -v --enforce-timeout 90 +``` \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json b/hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json new file mode 100644 index 00000000..a1361de0 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json @@ -0,0 +1,64 @@ +{ + "typeName": "AWSSamples::ConfigProactiveEval::Hook", + "description": "Sample hook to call AWS Config proactive evaluations", + "sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-samples/", + "documentationUrl": "https://github.com/aws-cloudformation/aws-cloudformation-samples/", + "typeConfiguration": { + "properties": { + "OutcomeForComplianceTypeInsufficientData": { + "description": "Determines whether the hook should pass or fail if Config returns 'Insufficient Data' on resource evaluation.", + "default": "PASS", + "type": "string", + "enum": [ + "PASS", + "FAIL" + ] + } + }, + "additionalProperties": false + }, + "required": [], + "handlers": { + "preCreate": { + "targetNames": [ + "AWS::ApiGateway::Stage", + "AWS::AutoScaling::AutoScalingGroup", + "AWS::EC2::EIP", + "AWS::EC2::Instance", + "AWS::EC2::Subnet", + "AWS::Elasticsearch::Domain", + "AWS::Lambda::Function", + "AWS::RDS::DBInstance", + "AWS::Redshift::Cluster", + "AWS::S3::Bucket", + "AWS::SNS::Topic" + ], + "permissions": [ + "config:GetResourceEvaluationSummary", + "config:StartResourceEvaluation", + "cloudformation:DescribeType" + ] + }, + "preUpdate": { + "targetNames": [ + "AWS::ApiGateway::Stage", + "AWS::AutoScaling::AutoScalingGroup", + "AWS::EC2::EIP", + "AWS::EC2::Instance", + "AWS::EC2::Subnet", + "AWS::Elasticsearch::Domain", + "AWS::Lambda::Function", + "AWS::RDS::DBInstance", + "AWS::Redshift::Cluster", + "AWS::S3::Bucket", + "AWS::SNS::Topic" + ], + "permissions": [ + "config:GetResourceEvaluationSummary", + "config:StartResourceEvaluation", + "cloudformation:DescribeType" + ] + } + }, + "additionalProperties": false +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml b/hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml new file mode 100644 index 00000000..141d1247 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml @@ -0,0 +1,42 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: > + This CloudFormation template creates a role assumed by CloudFormation + during Hook operations on behalf of the customer. + +Resources: + ExecutionRole: + Type: AWS::IAM::Role + Properties: + MaxSessionDuration: 8400 + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - hooks.cloudformation.amazonaws.com + - resources.cloudformation.amazonaws.com + Action: sts:AssumeRole + Condition: + StringEquals: + aws:SourceAccount: + Ref: AWS::AccountId + StringLike: + aws:SourceArn: + Fn::Sub: arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:type/hook/AWSSamples-ConfigProactiveEval-Hook/* + Path: "/" + Policies: + - PolicyName: HookTypePolicy + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - "cloudformation:DescribeType" + - "config:GetResourceEvaluationSummary" + - "config:StartResourceEvaluation" + Resource: "*" +Outputs: + ExecutionRoleArn: + Value: + Fn::GetAtt: ExecutionRole.Arn diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json new file mode 100644 index 00000000..4f0a0e71 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json @@ -0,0 +1,57 @@ +{ + "AWS::ApiGateway::Stage": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::AutoScaling::AutoScalingGroup": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::EC2::EIP": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::EC2::Instance": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::EC2::Subnet": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::Elasticsearch::Domain": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::Lambda::Function": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::RDS::DBInstance": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::Redshift::Cluster": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::S3::Bucket": { + "resourceProperties": { + "badResource": "badResource" + } + }, + "AWS::SNS::Topic": { + "resourceProperties": { + "badResource": "badResource" + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json new file mode 100644 index 00000000..fc68a64e --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json @@ -0,0 +1,98 @@ +{ + "AWS::ApiGateway::Stage": { + "resourceProperties": { + "RestApiId": "1234abcd", + "TracingEnabled": true + } + }, + "AWS::AutoScaling::AutoScalingGroup": { + "resourceProperties": { + "HealthCheckType": "ELB", + "MaxSize": "1", + "MinSize": "1" + } + }, + "AWS::EC2::EIP": { + "resourceProperties": { + "InstanceId": "i-1234abcd" + } + }, + "AWS::EC2::Instance": { + "resourceProperties": { + "ImageId": "ami-1234abcd", + "InstanceType": "t2.micro" + } + }, + "AWS::EC2::Subnet": { + "resourceProperties": { + "MapPublicIpOnLaunch": false, + "VpcId": "vpc-1234abcd" + } + }, + "AWS::Elasticsearch::Domain": { + "resourceProperties": { + "LogPublishingOptions": { + "ES_APPLICATION_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-application-logs", + "Enabled": true + }, + "INDEX_SLOW_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-index-slow-logs", + "Enabled": true + }, + "SEARCH_SLOW_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-slow-logs", + "Enabled": true + } + }, + "NodeToNodeEncryptionOptions": { + "Enabled": true + } + } + }, + "AWS::Lambda::Function": { + "resourceProperties": { + "Code": { + "ZipFile": "This is some code" + }, + "Role": "arn:aws:iam::123456789012:role/lambda-role", + "Runtime": "python3.8" + } + }, + "AWS::RDS::DBInstance": { + "resourceProperties": { + "AutoMinorVersionUpgrade": true, + "DBInstanceClass": "db.m5.large", + "Engine": "mysql", + "MonitoringInterval": 60, + "MonitoringRoleArn": "arn:aws:iam::123456789012:role/rds-monitoring-role", + "MultiAZ": true, + "PubliclyAccessible": false, + "StorageEncrypted": true + } + }, + "AWS::Redshift::Cluster": { + "resourceProperties": { + "AllowVersionUpgrade": true, + "ClusterType": "multi-node", + "DBName": "testonly", + "MasterUserPassword": "testonly", + "MasterUsername": "testonly", + "NodeType": "ds2.xlarge", + "PubliclyAccessible": false + } + }, + "AWS::S3::Bucket": { + "resourceProperties": { + "LoggingConfiguration": { + "DestinationBucketName": "DOC-EXAMPLE-BUCKET", + "LogFilePrefix": "testing-logs" + } + } + }, + "AWS::SNS::Topic": { + "resourceProperties": { + "KmsMasterKeyId": "arn:aws:kms:us-east-1:111122223333:key/00000000-1111-2222-aaaa-bbbbccccdddd" + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json new file mode 100644 index 00000000..7a311922 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json @@ -0,0 +1,99 @@ +{ + "AWS::ApiGateway::Stage": { + "resourceProperties": { + "DeploymentId": "abc123", + "RestApiId": "123456abcd", + "TracingEnabled": true + } + }, + "AWS::AutoScaling::AutoScalingGroup": { + "resourceProperties": { + "HealthCheckType": "ELB", + "MaxSize": "1", + "MinSize": "1" + } + }, + "AWS::EC2::EIP": { + "resourceProperties": { + "InstanceId": "i-1234abcd" + } + }, + "AWS::EC2::Instance": { + "resourceProperties": { + "ImageId": "ami-1234abcd", + "InstanceType": "t2.micro" + } + }, + "AWS::EC2::Subnet": { + "resourceProperties": { + "MapPublicIpOnLaunch": false, + "VpcId": "vpc-1234abcd" + } + }, + "AWS::Elasticsearch::Domain": { + "resourceProperties": { + "LogPublishingOptions": { + "ES_APPLICATION_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-application-logs", + "Enabled": true + }, + "INDEX_SLOW_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-index-slow-logs", + "Enabled": true + }, + "SEARCH_SLOW_LOGS": { + "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/opensearchservice/domains/es-slow-logs", + "Enabled": true + } + }, + "NodeToNodeEncryptionOptions": { + "Enabled": true + } + } + }, + "AWS::Lambda::Function": { + "resourceProperties": { + "Code": { + "ZipFile": "This is some code" + }, + "Role": "arn:aws:iam::123456789012:role/lambda-role", + "Runtime": "python3.8" + } + }, + "AWS::RDS::DBInstance": { + "resourceProperties": { + "AutoMinorVersionUpgrade": true, + "DBInstanceClass": "db.m5.large", + "Engine": "mysql", + "MonitoringInterval": 60, + "MonitoringRoleArn": "arn:aws:iam::123456789012:role/rds-monitoring-role", + "MultiAZ": true, + "PubliclyAccessible": false, + "StorageEncrypted": true + } + }, + "AWS::Redshift::Cluster": { + "resourceProperties": { + "AllowVersionUpgrade": true, + "ClusterType": "multi-node", + "DBName": "testonly", + "MasterUserPassword": "testonly", + "MasterUsername": "testonly", + "NodeType": "ds2.xlarge", + "PubliclyAccessible": false + } + }, + "AWS::S3::Bucket": { + "resourceProperties": { + "LoggingConfiguration": { + "DestinationBucketName": "DOC-EXAMPLE-BUCKET", + "LogFilePrefix": "testing-logs" + } + } + }, + "AWS::SNS::Topic": { + "resourceProperties": { + "KmsMasterKeyId": "arn:aws:kms:us-east-1:111122223333:key/00000000-1111-2222-aaaa-bbbbccccdddd" + } + } +} \ No newline at end of file diff --git a/hooks/Config_ProactiveEvaluation/hooks/lombok.config b/hooks/Config_ProactiveEvaluation/hooks/lombok.config new file mode 100644 index 00000000..7a21e880 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true diff --git a/hooks/Config_ProactiveEvaluation/hooks/pom.xml b/hooks/Config_ProactiveEvaluation/hooks/pom.xml new file mode 100644 index 00000000..f1dd0da3 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/pom.xml @@ -0,0 +1,253 @@ + + + 4.0.0 + + com.awssamples.configproactiveeval.hook + awssamples-configproactiveeval-hook-handler + awssamples-configproactiveeval-hook-handler + 1.0-SNAPSHOT + jar + + + 1.8 + 1.8 + UTF-8 + UTF-8 + + + + + + + software.amazon.awssdk + bom + 2.21.9 + pom + import + + + + + + + software.amazon.awssdk + config + + + + software.amazon.cloudformation + aws-cloudformation-rpdk-java-plugin + [2.0.0,3.0.0) + + + + org.projectlombok + lombok + 1.18.30 + provided + + + + org.apache.logging.log4j + log4j-api + 2.22.1 + + + + org.apache.logging.log4j + log4j-core + 2.22.1 + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.22.1 + + + + + org.assertj + assertj-core + 3.12.2 + test + + + + org.junit.jupiter + junit-jupiter + 5.5.0-M1 + test + + + + org.mockito + mockito-core + 3.6.0 + test + + + + org.mockito + mockito-junit-jupiter + 3.6.0 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + -Xlint:all,-options,-processing + -Werror + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + false + + + *:* + + **/Log4j2Plugins.dat + + + + + + + package + + shade + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + generate + generate-sources + + exec + + + cfn + generate ${cfn.generate.args} + ${project.basedir} + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + add-source + generate-sources + + add-source + + + + ${project.basedir}/target/generated-sources/rpdk + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4 + + + maven-surefire-plugin + 3.0.0-M3 + + + org.jacoco + jacoco-maven-plugin + 0.8.4 + + + **/hook/model/** + **/BaseHookConfiguration* + **/HookHandlerWrapper* + **/Configuration* + + + + + + prepare-agent + + + + report + test + + report + + + + jacoco-check + + check + + + + + PACKAGE + + + BRANCH + COVEREDRATIO + 0.8 + + + INSTRUCTION + COVEREDRATIO + 0.8 + + + + + + + + + + + + ${project.basedir} + + awssamples-configproactiveeval-hook.json + + + + ${project.basedir}/target/loaded-target-schemas + + **/*.json + + + + + diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java new file mode 100644 index 00000000..55a0e76a --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java @@ -0,0 +1,105 @@ +package com.awssamples.configproactiveeval.hook; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import software.amazon.awssdk.services.config.model.InvalidParameterValueException; +import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; +import software.amazon.cloudformation.proxy.HandlerErrorCode; +import software.amazon.cloudformation.proxy.Logger; +import software.amazon.cloudformation.proxy.OperationStatus; +import software.amazon.cloudformation.proxy.ProgressEvent; +import software.amazon.cloudformation.proxy.hook.HookContext; +import software.amazon.cloudformation.proxy.hook.HookHandlerRequest; +import software.amazon.cloudformation.proxy.hook.targetmodel.HookTargetModel; + +/** + * Methods that are common to both pre-create and pre-update handlers for this + * hook. + */ +public abstract class BaseHookHandlerStd + extends BaseHookHandler { + + private static final String insufficientDataOutcomeDefault = "PASS"; + + /** + * Run operations common to pre-create and pre-update phases for this hook. + * + * @param proxy AmazonWebServicesClientProxy + * @param request HookHandlerRequest + * @param callbackContext CallbackContext + * @param logger Logger + * @param typeConfiguration TypeConfigurationModel + * @return ProgressEvent + */ + protected ProgressEvent preCreatePreUpdateOperations( + final AmazonWebServicesClientProxy proxy, + final HookHandlerRequest request, + final CallbackContext callbackContext, + final Logger logger, + final TypeConfigurationModel typeConfiguration) { + + final HookContext hookContext = request.getHookContext(); + final String resourceType = hookContext.getTargetName(); + final String resourceId = hookContext.getTargetLogicalId(); + final String resourceConfiguration = hookContext + .getTargetModel() + .getTargetModelAsJSONObject() + .get("resourceProperties") + .toString(); + + try { + + ProactiveComplianceHandler proactiveComplianceHandler = ProactiveComplianceHandler.builder() + .resourceType(resourceType) + .resourceId(resourceId) + .resourceConfiguration(resourceConfiguration) + .awsClientProxy(proxy) + .outcomeForComplianceTypeInsufficientData(getInsufficientDataOutcome(typeConfiguration)) + .configClient(ClientBuilder.getConfigClient()) + .build(); + + String evaluationId = proactiveComplianceHandler.startResourceEvalution(); + return proactiveComplianceHandler.assessCompliance(evaluationId); + + } catch (final InvalidParameterValueException ipve) { + final String messageForInvalidParameterValueException = ipve.getMessage() + + " Check that you have specified all the required parameters" + + " for the resource type you are describing" + + " in your CloudFormation template, and parameters' key(s)/value(s) are correct."; + logger.log(messageForInvalidParameterValueException); + + return ProgressEvent.builder() + .status(OperationStatus.FAILED) + .message(messageForInvalidParameterValueException) + .errorCode(HandlerErrorCode.InvalidRequest) + .build(); + + } catch (final Throwable throwable) { + logger.log(ExceptionUtils.getStackTrace(throwable)); + + String messageFromThrowable = "A handler internal failure error has occurred."; + if (throwable.getMessage() != null) { + messageFromThrowable += String.format(" %s", throwable.getMessage()); + } + + return ProgressEvent.builder() + .status(OperationStatus.FAILED) + .message(messageFromThrowable) + .errorCode(HandlerErrorCode.HandlerInternalFailure) + .build(); + } + } + + /** + * Return the default value for the InsufficientDataOutcome behavior if not set + * in the type configuration; otherwise, return the value set in the type + * configuration. + * + * @param typeConfiguration TypeConfigurationModel + * @return String + */ + private String getInsufficientDataOutcome(final TypeConfigurationModel typeConfiguration) { + final String outcome = typeConfiguration.getOutcomeForComplianceTypeInsufficientData(); + + return (outcome == null || outcome.isEmpty()) ? insufficientDataOutcomeDefault : outcome; + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java new file mode 100644 index 00000000..1d40688f --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java @@ -0,0 +1,13 @@ +package com.awssamples.configproactiveeval.hook; + +import software.amazon.cloudformation.proxy.StdCallbackContext; + +/** + * Configure the callback context. + */ +@lombok.Getter +@lombok.Setter +@lombok.ToString +@lombok.EqualsAndHashCode(callSuper = true) +public class CallbackContext extends StdCallbackContext { +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java new file mode 100644 index 00000000..58e405c4 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java @@ -0,0 +1,22 @@ +package com.awssamples.configproactiveeval.hook; + +import software.amazon.awssdk.services.config.ConfigClient; +import software.amazon.cloudformation.HookLambdaWrapper; + +/** + * Build AWS Service Clients. + */ +public class ClientBuilder { + + /** + * Create a static HTTP client for AWS Config. + * + * @return ConfigClient + */ + public static ConfigClient getConfigClient() { + return ConfigClient.builder() + .httpClient(HookLambdaWrapper.HTTP_CLIENT) + .build(); + } + +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java new file mode 100644 index 00000000..068d7c3a --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java @@ -0,0 +1,14 @@ +package com.awssamples.configproactiveeval.hook; + +/** + * Handle the configuration. + */ +class Configuration extends BaseHookConfiguration { + + /** + * Initialize with the hook schema configuration file. + */ + public Configuration() { + super("awssamples-configproactiveeval-hook.json"); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java new file mode 100644 index 00000000..978fb995 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java @@ -0,0 +1,28 @@ +package com.awssamples.configproactiveeval.hook; + +import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; +import software.amazon.cloudformation.proxy.Logger; +import software.amazon.cloudformation.proxy.ProgressEvent; +import software.amazon.cloudformation.proxy.hook.HookHandlerRequest; +import software.amazon.cloudformation.proxy.hook.targetmodel.HookTargetModel; + +/** + * Handles the pre-create logic for the hook. + */ +public class PreCreateHookHandler extends BaseHookHandlerStd { + + @Override + public ProgressEvent handleRequest( + final AmazonWebServicesClientProxy proxy, + final HookHandlerRequest request, + final CallbackContext callbackContext, + final Logger logger, + final TypeConfigurationModel typeConfiguration) { + return preCreatePreUpdateOperations( + proxy, + request, + callbackContext, + logger, + typeConfiguration); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java new file mode 100644 index 00000000..3253662a --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java @@ -0,0 +1,28 @@ +package com.awssamples.configproactiveeval.hook; + +import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; +import software.amazon.cloudformation.proxy.Logger; +import software.amazon.cloudformation.proxy.ProgressEvent; +import software.amazon.cloudformation.proxy.hook.HookHandlerRequest; +import software.amazon.cloudformation.proxy.hook.targetmodel.HookTargetModel; + +/** + * Handles the pre-update logic for the hook. + */ +public class PreUpdateHookHandler extends BaseHookHandlerStd { + + @Override + public ProgressEvent handleRequest( + final AmazonWebServicesClientProxy proxy, + final HookHandlerRequest request, + final CallbackContext callbackContext, + final Logger logger, + final TypeConfigurationModel typeConfiguration) { + return preCreatePreUpdateOperations( + proxy, + request, + callbackContext, + logger, + typeConfiguration); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java new file mode 100644 index 00000000..02e90315 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java @@ -0,0 +1,158 @@ +package com.awssamples.configproactiveeval.hook; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import lombok.ToString; +import software.amazon.awssdk.services.config.ConfigClient; +import software.amazon.awssdk.services.config.model.ComplianceType; +import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryRequest; +import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryResponse; +import software.amazon.awssdk.services.config.model.ResourceEvaluationStatus; +import software.amazon.awssdk.services.config.model.StartResourceEvaluationRequest; +import software.amazon.awssdk.services.config.model.StartResourceEvaluationResponse; +import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; +import software.amazon.cloudformation.proxy.HandlerErrorCode; +import software.amazon.cloudformation.proxy.OperationStatus; +import software.amazon.cloudformation.proxy.ProgressEvent; +import software.amazon.cloudformation.proxy.hook.targetmodel.HookTargetModel; + +/** + * Used to start a proactive AWS Config check + * and retrieve the results of the check. + */ +@Builder +@ToString +@EqualsAndHashCode +@AllArgsConstructor +public class ProactiveComplianceHandler { + + @NonNull + public ConfigClient configClient; + + @NonNull + public AmazonWebServicesClientProxy awsClientProxy; + + @NonNull + public String resourceType; + + @NonNull + public String resourceId; + + @NonNull + public String resourceConfiguration; + + @NonNull + public String outcomeForComplianceTypeInsufficientData; + + private final int millisecondIntervalForGetEvaluationSummary = 2000; + private final String failOutcome = "FAIL"; + + /** + * Start an AWS Config proactive resource evaluation, and return + * the evaluation id. + * + * @return String + */ + public String startResourceEvalution() { + StartResourceEvaluationRequest startResourceEvaluationRequest = RequestBuilders + .buildProactiveStartResourceEvaluationRequest( + resourceType, resourceId, resourceConfiguration); + + final StartResourceEvaluationResponse startResourceEvaluationResponse = awsClientProxy + .injectCredentialsAndInvokeV2( + startResourceEvaluationRequest, + configClient::startResourceEvaluation); + + return startResourceEvaluationResponse.resourceEvaluationId(); + } + + /** + * Assess the compliance of a resource based on an AWS Config + * resourceEvaluationId. + * + * @param resourceEvaluationId the resourceEvaluationId for an AWS Config check + * @return ProgressEvent + * @throws InterruptedException getResourceEvaluationResult threw exception + */ + public ProgressEvent assessCompliance( + String resourceEvaluationId) throws InterruptedException { + + GetResourceEvaluationSummaryResponse getResourceEvaluationSummaryResponse = getResourceEvaluationResult( + resourceEvaluationId); + ComplianceType complianceType = getResourceEvaluationSummaryResponse.compliance(); + + if (complianceType == ComplianceType.NON_COMPLIANT) { + final String failureMessage = String.format( + "Resource [%s] is not compliant with Config proactive compliance rules.", + resourceType); + return ProgressEvent.builder() + .status(OperationStatus.FAILED) + .errorCode(HandlerErrorCode.NonCompliant) + .message(failureMessage) + .build(); + + } else if (complianceType == ComplianceType.INSUFFICIENT_DATA) { + String insufficientDataMessage = String.format( + "Insufficient data to evaluate compliance."); + if (getResourceEvaluationSummaryResponse.evaluationStatus().failureReason() != null) { + insufficientDataMessage = insufficientDataMessage + + " " + + getResourceEvaluationSummaryResponse.evaluationStatus().failureReason(); + } + + if (outcomeForComplianceTypeInsufficientData.equals(failOutcome)) { + return ProgressEvent.builder() + .status(OperationStatus.FAILED) + .errorCode(HandlerErrorCode.NonCompliant) + .message(insufficientDataMessage) + .build(); + } else { + return ProgressEvent.builder() + .status(OperationStatus.SUCCESS) + .message(insufficientDataMessage) + .build(); + } + + } else { // COMPLIANT + final String compliantMessage = String.format( + "Resource [%s] is compliant with Config proactive compliance rules.", + resourceType); + return ProgressEvent.builder() + .status(OperationStatus.SUCCESS) + .message(compliantMessage) + .build(); + } + } + + /** + * Retrieve the evaluation summary for a given resource based on the evaluation + * summary id. + * + * @param resourceEvaluationId the resourceEvaluationId for an AWS Config check + * @return GetResourceEvaluationSummaryResponse + * @throws InterruptedException Thread.sleep was interupted + */ + private GetResourceEvaluationSummaryResponse getResourceEvaluationResult( + String resourceEvaluationId) throws InterruptedException { + + GetResourceEvaluationSummaryRequest getResourceEvaluationSummaryRequest = RequestBuilders + .buildGetResourceEvaluationSummaryRequest(resourceEvaluationId); + + GetResourceEvaluationSummaryResponse getResourceEvaluationSummaryResponse = null; + ResourceEvaluationStatus resourceEvaluationStatus = null; + + do { + getResourceEvaluationSummaryResponse = awsClientProxy.injectCredentialsAndInvokeV2( + getResourceEvaluationSummaryRequest, + configClient::getResourceEvaluationSummary); + + resourceEvaluationStatus = getResourceEvaluationSummaryResponse.evaluationStatus().status(); + + Thread.sleep(millisecondIntervalForGetEvaluationSummary); + } while (resourceEvaluationStatus.equals(ResourceEvaluationStatus.IN_PROGRESS)); + + return getResourceEvaluationSummaryResponse; + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java new file mode 100644 index 00000000..07820e79 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java @@ -0,0 +1,52 @@ +package com.awssamples.configproactiveeval.hook; + +import software.amazon.awssdk.services.config.model.EvaluationMode; +import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryRequest; +import software.amazon.awssdk.services.config.model.ResourceConfigurationSchemaType; +import software.amazon.awssdk.services.config.model.ResourceDetails; +import software.amazon.awssdk.services.config.model.StartResourceEvaluationRequest; + +/** + * Provides a centralized placeholder for request construction. + */ +public class RequestBuilders { + + /** + * Build and return a StartResourceEvaluationRequest with a PROACTIVE evaluation + * mode. + * + * @param resourceType String + * @param resourceId String + * @param resourceConfiguration String + * @return StartResourceEvaluationRequest + */ + public static StartResourceEvaluationRequest buildProactiveStartResourceEvaluationRequest( + final String resourceType, final String resourceId, final String resourceConfiguration) { + + // Use a low value in seconds (e.g., 25) to avoid the 30-second hook timeout. + final int resourceEvaluationRequestTimeout = 25; + + return StartResourceEvaluationRequest.builder() + .evaluationMode(EvaluationMode.PROACTIVE) + .evaluationTimeout(resourceEvaluationRequestTimeout) + .resourceDetails(ResourceDetails.builder() + .resourceConfigurationSchemaType(ResourceConfigurationSchemaType.CFN_RESOURCE_SCHEMA) + .resourceType(resourceType) + .resourceId(resourceId) + .resourceConfiguration(resourceConfiguration) + .build()) + .build(); + } + + /** + * Build and return a GetResourceEvaluationSummaryRequest. + * + * @param resourceEvaluationId String + * @return GetResourceEvaluationSummaryRequest + */ + public static GetResourceEvaluationSummaryRequest buildGetResourceEvaluationSummaryRequest( + final String resourceEvaluationId) { + return GetResourceEvaluationSummaryRequest.builder() + .resourceEvaluationId(resourceEvaluationId).build(); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml b/hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml new file mode 100644 index 00000000..5657dafe --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java new file mode 100644 index 00000000..b1da1a04 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java @@ -0,0 +1,425 @@ +package com.awssamples.configproactiveeval.hook; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import software.amazon.awssdk.services.config.model.ComplianceType; +import software.amazon.awssdk.services.config.model.EvaluationStatus; +import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryRequest; +import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryResponse; +import software.amazon.awssdk.services.config.model.InvalidParameterValueException; +import software.amazon.awssdk.services.config.model.ResourceEvaluationStatus; +import software.amazon.awssdk.services.config.model.StartResourceEvaluationRequest; +import software.amazon.awssdk.services.config.model.StartResourceEvaluationResponse; +import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; +import software.amazon.cloudformation.proxy.HandlerErrorCode; +import software.amazon.cloudformation.proxy.Logger; +import software.amazon.cloudformation.proxy.OperationStatus; +import software.amazon.cloudformation.proxy.ProgressEvent; +import software.amazon.cloudformation.proxy.hook.HookContext; +import software.amazon.cloudformation.proxy.hook.HookHandlerRequest; +import software.amazon.cloudformation.proxy.hook.targetmodel.HookTargetModel; + +/** + * Tests for hook common operations. + */ +@ExtendWith(MockitoExtension.class) +public class BaseHookHandlerStdTest { + + private HookHandlerRequest request; + + @Mock + private AmazonWebServicesClientProxy awsProxy; + + @Mock + private Logger logger; + + @Mock + private TypeConfigurationModel typeConfiguration; + + protected void setup() { + + // Default "Compliant" resource + final Map targetModel = new HashMap(); + final Map resourceProperties = new HashMap(); + resourceProperties.put("InstanceId", "i-1234abcd"); + targetModel.put("resourceProperties", resourceProperties); + + // Default "User configured" OutcomeForComplianceTypeInsufficientData property + when(typeConfiguration.getOutcomeForComplianceTypeInsufficientData()).thenReturn("PASS"); + + final String resourceEvaluationId = "123"; + when(awsProxy.injectCredentialsAndInvokeV2(any(StartResourceEvaluationRequest.class), any())) + .thenReturn(StartResourceEvaluationResponse.builder() + .resourceEvaluationId(resourceEvaluationId) + .build()); + + request = HookHandlerRequest.builder() + .hookContext(HookContext.builder() + .targetName("AWS::EC2::EIP") + .targetLogicalId("sample") + .targetModel(HookTargetModel.of(targetModel)) + .build()) + .build(); + } + + /** + * Test exception handling in preCreatePreUpdateOperations. + * + * @param handler The hook handler + */ + protected void test_exceptionCaughtInPreCreatePreUpdateOperations( + final BaseHookHandlerStd handler) { + + Mockito.reset(awsProxy); + // When an exception is thrown in preCreatePreUpdateOperations + final String exceptionMessage = "Test exception."; + when(awsProxy.injectCredentialsAndInvokeV2(any(), any())) + .thenThrow(new Error(exceptionMessage)); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the exception is caught and the handler + // returns a FAILED status with the exception message + assertNotNull(response); + assertNull(response.getCallbackContext()); + assertThat(response.getMessage()) + .isEqualTo("A handler internal failure error has occurred. " + exceptionMessage); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.HandlerInternalFailure); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test null pointer exception handling in preCreatePreUpdateOperations. + * + * @param handler The hook handler + */ + protected void test_nullPointerExceptionCaughtInPreCreatePreUpdateOperations( + final BaseHookHandlerStd handler) { + + Mockito.reset(awsProxy); + // When a null pointer exception is thrown in preCreatePreUpdateOperations + when(awsProxy.injectCredentialsAndInvokeV2(any(), any())) + .thenThrow(new NullPointerException()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // The exception is caught and the handler returns a FAILED status without the exception message + assertNotNull(response); + assertNull(response.getCallbackContext()); + assertThat(response.getMessage()) + .isEqualTo("A handler internal failure error has occurred."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.HandlerInternalFailure); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test invalidParameterValueException handling in preCreatePreUpdateOperations. + * + * @param handler The hook handler + */ + protected void test_invalidParameterValueExceptionCaughtInPreCreatePreUpdateOperations( + final BaseHookHandlerStd handler) { + + Mockito.reset(awsProxy); + // When an invalidParameterValue Exception is thrown in + // preCreatePreUpdateOperations + final String exceptionMessage = "Test exception."; + when(awsProxy.injectCredentialsAndInvokeV2(any(), any())) + .thenThrow(InvalidParameterValueException.builder().message(exceptionMessage).build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // The exception is caught and the handler returns a FAILED status with the + // exception message + assertNotNull(response); + assertNull(response.getCallbackContext()); + assertThat(response.getMessage()) + .isEqualTo(exceptionMessage + + " Check that you have specified all the required parameters" + + " for the resource type you are describing" + + " in your CloudFormation template, and parameters' key(s)/value(s) are correct."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.InvalidRequest); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that non-compliant resource properties for a given resource returns a + * FAILED status and NonCompliant error code. + * + * @param handler The hook handler + */ + protected void test_nonCompliantResource(final BaseHookHandlerStd handler) { + + // Given resource properties are non-compliant with an enabled AWS Config rule + final Map targetModel = new HashMap(); + final Map resourceProperties = new HashMap(); + resourceProperties.put("Domain", "vpc"); + targetModel.put("resourceProperties", resourceProperties); + targetModel.put("ResourceProperties", resourceProperties); + + final String targetName = "AWS::EC2::EIP"; + final String targetLogicalId = "sample"; + request = HookHandlerRequest.builder() + .hookContext(HookContext.builder() + .targetName(targetName) + .targetLogicalId(targetLogicalId) + .targetModel(HookTargetModel.of(targetModel)) + .build()) + .build(); + + // When the resource is evaluated and the returned compliance type is + // NON_COMPLIANT + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.SUCCEEDED) + .build()) + .compliance(ComplianceType.NON_COMPLIANT) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a FAILED status with the NonCompliant error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Resource [AWS::EC2::EIP] is not compliant with Config proactive compliance rules."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.NonCompliant); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that compliant resource properties for a given resource returns a + * SUCCESS status and no error code. + * + * @param handler The hook handler + */ + protected void test_compliantResource(final BaseHookHandlerStd handler) { + + // Given resource properties are compliant with an enabled AWS Config rule + // When the resource is evaluated and the returned compliance type is COMPLIANT + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.SUCCEEDED) + .build()) + .compliance(ComplianceType.COMPLIANT) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a SUCCESS status with no error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Resource [AWS::EC2::EIP] is compliant with Config proactive compliance rules."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.SUCCESS); + assertNull(response.getErrorCode()); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that when the compliance type is INSUFFICIENT_DATA and + * the hook is configured for OutcomeForComplianceTypeInsufficientData equals PASS + * that a SUCCESS status and no error code are returned. + * + * @param handler The hook handler + */ + protected void test_insufficientDataConfiguredToPass(final BaseHookHandlerStd handler) { + + // Given the hook configuration for OutcomeForComplianceTypeInsufficientData equals PASS + // When the resource is evaluated and the returned compliance type is INSUFFICIENT_DATA + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.FAILED) + .build()) + .compliance(ComplianceType.INSUFFICIENT_DATA) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a SUCCESS status with no error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Insufficient data to evaluate compliance."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.SUCCESS); + assertNull(response.getErrorCode()); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that when the compliance type is INSUFFICIENT_DATA and + * the hook is configured for OutcomeForComplianceTypeInsufficientData equals FAIL + * that a FAILED status and NonCompliant error code are returned. + * + * @param handler The hook handler + */ + protected void test_insufficientDataConfiguredToFail(final BaseHookHandlerStd handler) { + + // Given the hook configuration for OutcomeForComplianceTypeInsufficientData equals FAIL + Mockito.reset(typeConfiguration); + when(typeConfiguration.getOutcomeForComplianceTypeInsufficientData()).thenReturn("FAIL"); + + // When the resource is evaluated and the returned compliance type is INSUFFICIENT_DATA + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.FAILED) + .build()) + .compliance(ComplianceType.INSUFFICIENT_DATA) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a FAILED status with no error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Insufficient data to evaluate compliance."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.NonCompliant); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that when the compliance type is INSUFFICIENT_DATA, and there is a failureReason, + * and the hook is configured for OutcomeForComplianceTypeInsufficientData equals FAIL + * that a FAILED status and NonCompliant error code are returned and the failureReason is + * in the response message. + */ + protected void test_insufficientDataConfiguredToFailWithFailureReason( + final BaseHookHandlerStd handler) { + + // Given the hook configuration for OutcomeForComplianceTypeInsufficientData equals FAIL + Mockito.reset(typeConfiguration); + when(typeConfiguration.getOutcomeForComplianceTypeInsufficientData()).thenReturn("FAIL"); + + // When the resource is evaluated and the returned compliance type is INSUFFICIENT_DATA + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.FAILED) + .failureReason("Resource evaluation timed out.") + .build()) + .compliance(ComplianceType.INSUFFICIENT_DATA) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a FAILED status with no error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Insufficient data to evaluate compliance. Resource evaluation timed out."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.FAILED); + assertThat(response.getErrorCode()).isEqualTo(HandlerErrorCode.NonCompliant); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } + + /** + * Test that when the compliance type is INSUFFICIENT_DATA + * and the hook is configured for the OutcomeForComplianceTypeInsufficientData default value + * that a SUCCESS status and no error code are returned. + */ + protected void test_insufficientDataConfiguredToDefault( + final BaseHookHandlerStd handler) { + + // Given the hook configuration for OutcomeForComplianceTypeInsufficientData equals FAIL + Mockito.reset(typeConfiguration); + + // When the resource is evaluated and the returned compliance type is INSUFFICIENT_DATA + when(awsProxy.injectCredentialsAndInvokeV2( + any(GetResourceEvaluationSummaryRequest.class), any())) + .thenReturn(GetResourceEvaluationSummaryResponse.builder() + .evaluationStatus(EvaluationStatus.builder() + .status(ResourceEvaluationStatus.FAILED) + .failureReason("Resource evaluation timed out.") + .build()) + .compliance(ComplianceType.INSUFFICIENT_DATA) + .build()); + + final ProgressEvent response = handler.handleRequest( + awsProxy, + request, + new CallbackContext(), + logger, + typeConfiguration); + + // Then the handler returns a FAILED status with no error code + assertNotNull(response); + assertThat(response.getMessage()) + .isEqualTo( + "Insufficient data to evaluate compliance. Resource evaluation timed out."); + assertThat(response.getStatus()).isEqualTo(OperationStatus.SUCCESS); + assertNull(response.getErrorCode()); + assertNull(response.getCallbackContext()); + assertThat(response.getCallbackDelaySeconds()).isEqualTo(0); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java new file mode 100644 index 00000000..b4e47004 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java @@ -0,0 +1,66 @@ +package com.awssamples.configproactiveeval.hook; + +import static org.mockito.Mockito.spy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests for the pre-create hook. + */ +public class PreCreateHookHandlerTest extends BaseHookHandlerStdTest { + + private PreCreateHookHandler handler; + + @Override + @BeforeEach + public void setup() { + handler = spy(new PreCreateHookHandler()); + super.setup(); + } + + @Test + public void test_exceptionCaught() { + test_exceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_nullPointerExceptionCaught() { + test_nullPointerExceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_invalidParameterValueExceptionCaught() { + test_invalidParameterValueExceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_nonCompliantResource() { + test_nonCompliantResource(handler); + } + + @Test + public void test_compliantResource() { + test_compliantResource(handler); + } + + @Test + public void test_insufficientDataConfiguredToPass() { + test_insufficientDataConfiguredToPass(handler); + } + + @Test + public void test_insufficientDataConfiguredToFail() { + test_insufficientDataConfiguredToFail(handler); + } + + @Test + public void test_insufficientDataConfiguredToFailWithFailureReason() { + test_insufficientDataConfiguredToFailWithFailureReason(handler); + } + + @Test + public void test_insufficientDataConfiguredToDefault() { + test_insufficientDataConfiguredToDefault(handler); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java new file mode 100644 index 00000000..3a307ce6 --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java @@ -0,0 +1,65 @@ +package com.awssamples.configproactiveeval.hook; + +import static org.mockito.Mockito.spy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests for the pre-create hook. + */ +public class PreUpdateHookHandlerTest extends BaseHookHandlerStdTest { + private PreUpdateHookHandler handler; + + @Override + @BeforeEach + public void setup() { + handler = spy(new PreUpdateHookHandler()); + super.setup(); + } + + @Test + public void test_exceptionCaught() { + test_exceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_nullPointerExceptionCaught() { + test_nullPointerExceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_invalidParameterValueExceptionCaught() { + test_invalidParameterValueExceptionCaughtInPreCreatePreUpdateOperations(handler); + } + + @Test + public void test_nonCompliantResource() { + test_nonCompliantResource(handler); + } + + @Test + public void test_compliantResource() { + test_compliantResource(handler); + } + + @Test + public void test_insufficientDataConfiguredToPass() { + test_insufficientDataConfiguredToPass(handler); + } + + @Test + public void test_insufficientDataConfiguredToFail() { + test_insufficientDataConfiguredToFail(handler); + } + + @Test + public void test_insufficientDataConfiguredToFailWithFailureReason() { + test_insufficientDataConfiguredToFailWithFailureReason(handler); + } + + @Test + public void test_insufficientDataConfiguredToDefault() { + test_insufficientDataConfiguredToDefault(handler); + } +} diff --git a/hooks/Config_ProactiveEvaluation/hooks/template.yml b/hooks/Config_ProactiveEvaluation/hooks/template.yml new file mode 100644 index 00000000..2a1a2dde --- /dev/null +++ b/hooks/Config_ProactiveEvaluation/hooks/template.yml @@ -0,0 +1,23 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: AWS SAM template for the AWSSamples::ConfigProactiveEval::Hook resource type + +Globals: + Function: + Timeout: 180 # docker start-up times can be long for SAM CLI + MemorySize: 512 + +Resources: + TypeFunction: + Type: AWS::Serverless::Function + Properties: + Handler: com.awssamples.configproactiveeval.hook.HookHandlerWrapper::handleRequest + Runtime: java11 + CodeUri: ./target/awssamples-configproactiveeval-hook-handler-1.0-SNAPSHOT.jar + + TestEntrypoint: + Type: AWS::Serverless::Function + Properties: + Handler: com.awssamples.configproactiveeval.hook.HookHandlerWrapper::testEntrypoint + Runtime: java11 + CodeUri: ./target/awssamples-configproactiveeval-hook-handler-1.0-SNAPSHOT.jar \ No newline at end of file From 1ce003e00168a59ffd155fb04e221e917a37c80a Mon Sep 17 00:00:00 2001 From: Trevor Schiavone Date: Mon, 29 Jan 2024 13:22:06 +0100 Subject: [PATCH 2/3] rename folder hooks to hook --- hooks/Config_ProactiveEvaluation/.gitignore | 4 ++-- hooks/Config_ProactiveEvaluation/{hooks => hook}/.rpdk-config | 0 hooks/Config_ProactiveEvaluation/{hooks => hook}/README.md | 0 .../{hooks => hook}/awssamples-configproactiveeval-hook.json | 0 .../Config_ProactiveEvaluation/{hooks => hook}/hook-role.yaml | 0 .../{hooks => hook}/inputs/inputs_1_invalid.json | 0 .../{hooks => hook}/inputs/inputs_1_pre_create.json | 0 .../{hooks => hook}/inputs/inputs_1_pre_update.json | 0 .../Config_ProactiveEvaluation/{hooks => hook}/lombok.config | 0 hooks/Config_ProactiveEvaluation/{hooks => hook}/pom.xml | 0 .../configproactiveeval/hook/BaseHookHandlerStd.java | 0 .../awssamples/configproactiveeval/hook/CallbackContext.java | 0 .../awssamples/configproactiveeval/hook/ClientBuilder.java | 0 .../awssamples/configproactiveeval/hook/Configuration.java | 0 .../configproactiveeval/hook/PreCreateHookHandler.java | 0 .../configproactiveeval/hook/PreUpdateHookHandler.java | 0 .../configproactiveeval/hook/ProactiveComplianceHandler.java | 0 .../awssamples/configproactiveeval/hook/RequestBuilders.java | 0 .../{hooks => hook}/src/resources/log4j2.xml | 0 .../configproactiveeval/hook/BaseHookHandlerStdTest.java | 0 .../configproactiveeval/hook/PreCreateHookHandlerTest.java | 0 .../configproactiveeval/hook/PreUpdateHookHandlerTest.java | 0 hooks/Config_ProactiveEvaluation/{hooks => hook}/template.yml | 0 23 files changed, 2 insertions(+), 2 deletions(-) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/.rpdk-config (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/README.md (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/awssamples-configproactiveeval-hook.json (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/hook-role.yaml (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/inputs/inputs_1_invalid.json (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/inputs/inputs_1_pre_create.json (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/inputs/inputs_1_pre_update.json (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/lombok.config (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/pom.xml (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/resources/log4j2.xml (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java (100%) rename hooks/Config_ProactiveEvaluation/{hooks => hook}/template.yml (100%) diff --git a/hooks/Config_ProactiveEvaluation/.gitignore b/hooks/Config_ProactiveEvaluation/.gitignore index 111ac0c7..be19fe32 100644 --- a/hooks/Config_ProactiveEvaluation/.gitignore +++ b/hooks/Config_ProactiveEvaluation/.gitignore @@ -17,8 +17,8 @@ out/ .vscode # auto-generated files -/hooks/target/ -/hooks/docs/* +/hook/target/ +/hook/docs/* *.zip # contract testing diff --git a/hooks/Config_ProactiveEvaluation/hooks/.rpdk-config b/hooks/Config_ProactiveEvaluation/hook/.rpdk-config similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/.rpdk-config rename to hooks/Config_ProactiveEvaluation/hook/.rpdk-config diff --git a/hooks/Config_ProactiveEvaluation/hooks/README.md b/hooks/Config_ProactiveEvaluation/hook/README.md similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/README.md rename to hooks/Config_ProactiveEvaluation/hook/README.md diff --git a/hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json b/hooks/Config_ProactiveEvaluation/hook/awssamples-configproactiveeval-hook.json similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/awssamples-configproactiveeval-hook.json rename to hooks/Config_ProactiveEvaluation/hook/awssamples-configproactiveeval-hook.json diff --git a/hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml b/hooks/Config_ProactiveEvaluation/hook/hook-role.yaml similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/hook-role.yaml rename to hooks/Config_ProactiveEvaluation/hook/hook-role.yaml diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json b/hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_invalid.json similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_invalid.json rename to hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_invalid.json diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json b/hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_pre_create.json similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_create.json rename to hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_pre_create.json diff --git a/hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json b/hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_pre_update.json similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/inputs/inputs_1_pre_update.json rename to hooks/Config_ProactiveEvaluation/hook/inputs/inputs_1_pre_update.json diff --git a/hooks/Config_ProactiveEvaluation/hooks/lombok.config b/hooks/Config_ProactiveEvaluation/hook/lombok.config similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/lombok.config rename to hooks/Config_ProactiveEvaluation/hook/lombok.config diff --git a/hooks/Config_ProactiveEvaluation/hooks/pom.xml b/hooks/Config_ProactiveEvaluation/hook/pom.xml similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/pom.xml rename to hooks/Config_ProactiveEvaluation/hook/pom.xml diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml b/hooks/Config_ProactiveEvaluation/hook/src/resources/log4j2.xml similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/resources/log4j2.xml rename to hooks/Config_ProactiveEvaluation/hook/src/resources/log4j2.xml diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java diff --git a/hooks/Config_ProactiveEvaluation/hooks/template.yml b/hooks/Config_ProactiveEvaluation/hook/template.yml similarity index 100% rename from hooks/Config_ProactiveEvaluation/hooks/template.yml rename to hooks/Config_ProactiveEvaluation/hook/template.yml From 773b747d4c179fbd9f99e936520fc1cba253df6e Mon Sep 17 00:00:00 2001 From: Trevor Schiavone Date: Tue, 30 Jan 2024 17:33:19 +0100 Subject: [PATCH 3/3] Update extension name to awscommunity config proactiveeval --- hooks/Config_ProactiveEvaluation/README.md | 2 +- hooks/Config_ProactiveEvaluation/hook/.rpdk-config | 14 +++++++------- ...json => awscommunity-config-proactiveeval.json} | 4 ++-- .../Config_ProactiveEvaluation/hook/hook-role.yaml | 2 +- hooks/Config_ProactiveEvaluation/hook/pom.xml | 8 ++++---- .../config/proactiveeval}/BaseHookHandlerStd.java | 3 ++- .../config/proactiveeval}/CallbackContext.java | 2 +- .../config/proactiveeval}/ClientBuilder.java | 2 +- .../config/proactiveeval}/Configuration.java | 4 ++-- .../proactiveeval}/PreCreateHookHandler.java | 2 +- .../proactiveeval}/PreUpdateHookHandler.java | 2 +- .../proactiveeval}/ProactiveComplianceHandler.java | 2 +- .../config/proactiveeval}/RequestBuilders.java | 2 +- .../proactiveeval}/BaseHookHandlerStdTest.java | 2 +- .../proactiveeval}/PreCreateHookHandlerTest.java | 2 +- .../proactiveeval}/PreUpdateHookHandlerTest.java | 2 +- hooks/Config_ProactiveEvaluation/hook/template.yml | 10 +++++----- 17 files changed, 33 insertions(+), 32 deletions(-) rename hooks/Config_ProactiveEvaluation/hook/{awssamples-configproactiveeval-hook.json => awscommunity-config-proactiveeval.json} (93%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/BaseHookHandlerStd.java (98%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/CallbackContext.java (84%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/ClientBuilder.java (89%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/Configuration.java (64%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/PreCreateHookHandler.java (94%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/PreUpdateHookHandler.java (94%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/ProactiveComplianceHandler.java (99%) rename hooks/Config_ProactiveEvaluation/hook/src/main/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/RequestBuilders.java (97%) rename hooks/Config_ProactiveEvaluation/hook/src/test/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/BaseHookHandlerStdTest.java (99%) rename hooks/Config_ProactiveEvaluation/hook/src/test/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/PreCreateHookHandlerTest.java (96%) rename hooks/Config_ProactiveEvaluation/hook/src/test/java/com/{awssamples/configproactiveeval/hook => awscommunity/config/proactiveeval}/PreUpdateHookHandlerTest.java (96%) diff --git a/hooks/Config_ProactiveEvaluation/README.md b/hooks/Config_ProactiveEvaluation/README.md index 5ba3e08e..3690da43 100644 --- a/hooks/Config_ProactiveEvaluation/README.md +++ b/hooks/Config_ProactiveEvaluation/README.md @@ -1,4 +1,4 @@ -# AWSSamples::ConfigProactiveEval::Hook +# AwsCommunity::Config::ProactiveEval - [Overview](#overview) diff --git a/hooks/Config_ProactiveEvaluation/hook/.rpdk-config b/hooks/Config_ProactiveEvaluation/hook/.rpdk-config index a6cf3725..1bd9eee7 100644 --- a/hooks/Config_ProactiveEvaluation/hook/.rpdk-config +++ b/hooks/Config_ProactiveEvaluation/hook/.rpdk-config @@ -1,10 +1,10 @@ { "artifact_type": "HOOK", - "typeName": "AWSSamples::ConfigProactiveEval::Hook", + "typeName": "AwsCommunity::Config::ProactiveEval", "language": "java", "runtime": "java11", - "entrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapper::handleRequest", - "testEntrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapper::testEntrypoint", + "entrypoint": "com.awscommunity.config.proactiveeval.HookHandlerWrapper::handleRequest", + "testEntrypoint": "com.awscommunity.config.proactiveeval.HookHandlerWrapper::testEntrypoint", "settings": { "version": false, "subparser_name": null, @@ -18,12 +18,12 @@ "profile": null, "namespace": [ "com", - "awssamples", - "configproactiveeval", - "hook" + "awscommunity", + "config", + "proactiveeval" ], "codegen_template_path": "guided_aws", "protocolVersion": "2.0.0" }, - "executableEntrypoint": "com.awssamples.configproactiveeval.hook.HookHandlerWrapperExecutable" + "executableEntrypoint": "com.awscommunity.config.proactiveeval.HookHandlerWrapperExecutable" } diff --git a/hooks/Config_ProactiveEvaluation/hook/awssamples-configproactiveeval-hook.json b/hooks/Config_ProactiveEvaluation/hook/awscommunity-config-proactiveeval.json similarity index 93% rename from hooks/Config_ProactiveEvaluation/hook/awssamples-configproactiveeval-hook.json rename to hooks/Config_ProactiveEvaluation/hook/awscommunity-config-proactiveeval.json index a1361de0..dc7c03c0 100644 --- a/hooks/Config_ProactiveEvaluation/hook/awssamples-configproactiveeval-hook.json +++ b/hooks/Config_ProactiveEvaluation/hook/awscommunity-config-proactiveeval.json @@ -1,6 +1,6 @@ { - "typeName": "AWSSamples::ConfigProactiveEval::Hook", - "description": "Sample hook to call AWS Config proactive evaluations", + "typeName": "AwsCommunity::Config::ProactiveEval", + "description": "This hook calls AWS Config proactive evaluations to assess compliance of the resource", "sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-samples/", "documentationUrl": "https://github.com/aws-cloudformation/aws-cloudformation-samples/", "typeConfiguration": { diff --git a/hooks/Config_ProactiveEvaluation/hook/hook-role.yaml b/hooks/Config_ProactiveEvaluation/hook/hook-role.yaml index 141d1247..11a34242 100644 --- a/hooks/Config_ProactiveEvaluation/hook/hook-role.yaml +++ b/hooks/Config_ProactiveEvaluation/hook/hook-role.yaml @@ -23,7 +23,7 @@ Resources: Ref: AWS::AccountId StringLike: aws:SourceArn: - Fn::Sub: arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:type/hook/AWSSamples-ConfigProactiveEval-Hook/* + Fn::Sub: arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:type/hook/AwsCommunity-Config-ProactiveEval/* Path: "/" Policies: - PolicyName: HookTypePolicy diff --git a/hooks/Config_ProactiveEvaluation/hook/pom.xml b/hooks/Config_ProactiveEvaluation/hook/pom.xml index f1dd0da3..e4b7a3be 100644 --- a/hooks/Config_ProactiveEvaluation/hook/pom.xml +++ b/hooks/Config_ProactiveEvaluation/hook/pom.xml @@ -5,9 +5,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.awssamples.configproactiveeval.hook - awssamples-configproactiveeval-hook-handler - awssamples-configproactiveeval-hook-handler + com.awscommunity.config.proactiveeval + awscommunity-config-proactiveeval-handler + awscommunity-config-proactiveeval-handler 1.0-SNAPSHOT jar @@ -239,7 +239,7 @@ ${project.basedir} - awssamples-configproactiveeval-hook.json + awscommunity-config-proactiveeval.json diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStd.java similarity index 98% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStd.java index 55a0e76a..94370240 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStd.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStd.java @@ -1,6 +1,7 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import org.apache.commons.lang3.exception.ExceptionUtils; + import software.amazon.awssdk.services.config.model.InvalidParameterValueException; import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; import software.amazon.cloudformation.proxy.HandlerErrorCode; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/CallbackContext.java similarity index 84% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/CallbackContext.java index 1d40688f..b10c18d8 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/CallbackContext.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/CallbackContext.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import software.amazon.cloudformation.proxy.StdCallbackContext; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ClientBuilder.java similarity index 89% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ClientBuilder.java index 58e405c4..b42d86fd 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ClientBuilder.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ClientBuilder.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import software.amazon.awssdk.services.config.ConfigClient; import software.amazon.cloudformation.HookLambdaWrapper; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/Configuration.java similarity index 64% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/Configuration.java index 068d7c3a..380fefff 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/Configuration.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/Configuration.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; /** * Handle the configuration. @@ -9,6 +9,6 @@ class Configuration extends BaseHookConfiguration { * Initialize with the hook schema configuration file. */ public Configuration() { - super("awssamples-configproactiveeval-hook.json"); + super("awscommunity-config-proactiveeval.json"); } } diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreCreateHookHandler.java similarity index 94% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreCreateHookHandler.java index 978fb995..4c7859eb 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandler.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreCreateHookHandler.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; import software.amazon.cloudformation.proxy.Logger; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandler.java similarity index 94% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandler.java index 3253662a..3701563d 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandler.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandler.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; import software.amazon.cloudformation.proxy.Logger; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ProactiveComplianceHandler.java similarity index 99% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ProactiveComplianceHandler.java index 02e90315..b748023e 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/ProactiveComplianceHandler.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/ProactiveComplianceHandler.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/RequestBuilders.java similarity index 97% rename from hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java rename to hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/RequestBuilders.java index 07820e79..5b431046 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awssamples/configproactiveeval/hook/RequestBuilders.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/main/java/com/awscommunity/config/proactiveeval/RequestBuilders.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import software.amazon.awssdk.services.config.model.EvaluationMode; import software.amazon.awssdk.services.config.model.GetResourceEvaluationSummaryRequest; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStdTest.java similarity index 99% rename from hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStdTest.java index b1da1a04..624801ba 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/BaseHookHandlerStdTest.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/BaseHookHandlerStdTest.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreCreateHookHandlerTest.java similarity index 96% rename from hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreCreateHookHandlerTest.java index b4e47004..c64edacb 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreCreateHookHandlerTest.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreCreateHookHandlerTest.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import static org.mockito.Mockito.spy; diff --git a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandlerTest.java similarity index 96% rename from hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java rename to hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandlerTest.java index 3a307ce6..393bff53 100644 --- a/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awssamples/configproactiveeval/hook/PreUpdateHookHandlerTest.java +++ b/hooks/Config_ProactiveEvaluation/hook/src/test/java/com/awscommunity/config/proactiveeval/PreUpdateHookHandlerTest.java @@ -1,4 +1,4 @@ -package com.awssamples.configproactiveeval.hook; +package com.awscommunity.config.proactiveeval; import static org.mockito.Mockito.spy; diff --git a/hooks/Config_ProactiveEvaluation/hook/template.yml b/hooks/Config_ProactiveEvaluation/hook/template.yml index 2a1a2dde..79793e86 100644 --- a/hooks/Config_ProactiveEvaluation/hook/template.yml +++ b/hooks/Config_ProactiveEvaluation/hook/template.yml @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 -Description: AWS SAM template for the AWSSamples::ConfigProactiveEval::Hook resource type +Description: AWS SAM template for the AwsCommunity::Config::ProactiveEval resource type Globals: Function: @@ -11,13 +11,13 @@ Resources: TypeFunction: Type: AWS::Serverless::Function Properties: - Handler: com.awssamples.configproactiveeval.hook.HookHandlerWrapper::handleRequest + Handler: com.awscommunity.config.proactiveeval.HookHandlerWrapper::handleRequest Runtime: java11 - CodeUri: ./target/awssamples-configproactiveeval-hook-handler-1.0-SNAPSHOT.jar + CodeUri: ./target/awscommunity-config-proactiveeval-handler-1.0-SNAPSHOT.jar TestEntrypoint: Type: AWS::Serverless::Function Properties: - Handler: com.awssamples.configproactiveeval.hook.HookHandlerWrapper::testEntrypoint + Handler: com.awscommunity.config.proactiveeval.HookHandlerWrapper::testEntrypoint Runtime: java11 - CodeUri: ./target/awssamples-configproactiveeval-hook-handler-1.0-SNAPSHOT.jar \ No newline at end of file + CodeUri: ./target/awscommunity-config-proactiveeval-handler-1.0-SNAPSHOT.jar \ No newline at end of file