def lambda_handler(event, context):
    if 'liblogging' in sys.modules:
        liblogging.logEvent(event)

    global AWS_CONFIG_CLIENT

    #print(event)
    check_defined(event, 'event')
    invoking_event = json.loads(event['invokingEvent'])
    rule_parameters = {}
    if 'ruleParameters' in event:
        rule_parameters = json.loads(event['ruleParameters'])

    try:
        valid_rule_parameters = evaluate_parameters(rule_parameters)
    except ValueError as ex:
        return build_parameters_value_error_response(ex)

    try:
        AWS_CONFIG_CLIENT = get_client('config', event)
        if invoking_event['messageType'] in ['ConfigurationItemChangeNotification', 'ScheduledNotification', 'OversizedConfigurationItemChangeNotification']:
            configuration_item = get_configuration_item(invoking_event)
            if is_applicable(configuration_item, event):
                compliance_result = evaluate_compliance(event, configuration_item, valid_rule_parameters)
            else:
                compliance_result = "NOT_APPLICABLE"
        else:
            return build_internal_error_response('Unexpected message type', str(invoking_event))
    except botocore.exceptions.ClientError as ex:
        if is_internal_error(ex):
            return build_internal_error_response("Unexpected error while completing API request", str(ex))
        return build_error_response("Customer error while making API request", str(ex), ex.response['Error']['Code'], ex.response['Error']['Message'])
    except ValueError as ex:
        return build_internal_error_response(str(ex), str(ex))

    evaluations = []
    latest_evaluations = []

    if not compliance_result:
        latest_evaluations.append(build_evaluation(event['accountId'], "NOT_APPLICABLE", event, resource_type='AWS::::Account'))
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, str):
        if configuration_item:
            evaluations.append(build_evaluation_from_config_item(configuration_item, compliance_result))
        else:
            evaluations.append(build_evaluation(event['accountId'], compliance_result, event, resource_type=DEFAULT_RESOURCE_TYPE))
    elif isinstance(compliance_result, list):
        for evaluation in compliance_result:
            missing_fields = False
            for field in ('ComplianceResourceType', 'ComplianceResourceId', 'ComplianceType', 'OrderingTimestamp'):
                if field not in evaluation:
                    print("Missing " + field + " from custom evaluation.")
                    missing_fields = True

            if not missing_fields:
                latest_evaluations.append(evaluation)
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, dict):
        missing_fields = False
        for field in ('ComplianceResourceType', 'ComplianceResourceId', 'ComplianceType', 'OrderingTimestamp'):
            if field not in compliance_result:
                print("Missing " + field + " from custom evaluation.")
                missing_fields = True
        if not missing_fields:
            evaluations.append(compliance_result)
    else:
        return {
            "compliance_type" : "NON_COMPLIANT",
            "annotation" : 'Not in private subnet'
        }
Example #2
0
def lambda_handler(event, context):
    if 'liblogging' in sys.modules:
        liblogging.logEvent(event)

    global AWS_CONFIG_CLIENT

    if DEBUG:
        print("Event (Line 481):", event)
    check_defined(event, 'event')

    # this should only error if you test the lambda function with invalid json
    invoking_event = json.loads(event['invokingEvent'])

    rule_parameters = {}
    if 'ruleParameters' in event:
        rule_parameters = json.loads(event['ruleParameters'])

    try:
        valid_rule_parameters = evaluate_parameters(rule_parameters)
    except ValueError as ex:
        return build_parameters_value_error_response(ex)

    try:
        AWS_CONFIG_CLIENT = get_client('config', event)
        if invoking_event['messageType'] in [
                'ConfigurationItemChangeNotification', 'ScheduledNotification',
                'OversizedConfigurationItemChangeNotification'
        ]:
            configuration_item = get_configuration_item(invoking_event)
            if is_applicable(configuration_item, event):
                if DEBUG:
                    print("configuration item (Line 501)", configuration_item)
                compliance_result = evaluate_compliance(
                    event, configuration_item, valid_rule_parameters)
            else:
                compliance_result = "NOT_APPLICABLE"
        else:
            return build_internal_error_response('Unexpected message type',
                                                 str(invoking_event))
    except botocore.exceptions.ClientError as ex:
        if is_internal_error(ex):
            return build_internal_error_response(
                "Unexpected error while completing API request", str(ex))
        return build_error_response("Customer error while making API request",
                                    str(ex), ex.response['Error']['Code'],
                                    ex.response['Error']['Message'])
    except ValueError as ex:
        return build_internal_error_response(str(ex), str(ex))

    evaluations = []
    latest_evaluations = []

    if not compliance_result:
        latest_evaluations.append(
            build_evaluation(event['accountId'],
                             "NOT_APPLICABLE",
                             event,
                             resource_type='AWS::::Account'))
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, str):
        if configuration_item:
            evaluations.append(
                build_evaluation_from_config_item(configuration_item,
                                                  compliance_result))
        else:
            evaluations.append(
                build_evaluation(event['accountId'],
                                 compliance_result,
                                 event,
                                 resource_type=DEFAULT_RESOURCE_TYPE))
    elif isinstance(compliance_result, list):
        for evaluation in compliance_result:
            missing_fields = False
            for field in ('ComplianceResourceType', 'ComplianceResourceId',
                          'ComplianceType', 'OrderingTimestamp'):
                if field not in evaluation:
                    print("Missing " + field + " from custom evaluation.")
                    missing_fields = True

            if not missing_fields:
                latest_evaluations.append(evaluation)
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, dict):
        missing_fields = False
        for field in ('ComplianceResourceType', 'ComplianceResourceId',
                      'ComplianceType', 'OrderingTimestamp'):
            if field not in compliance_result:
                print("Missing " + field + " from custom evaluation.")
                missing_fields = True
        if not missing_fields:
            evaluations.append(compliance_result)
    else:
        evaluations.append(
            build_evaluation_from_config_item(configuration_item,
                                              'NOT_APPLICABLE'))

    # Put together the request that reports the evaluation status
    result_token = event['resultToken']
    test_mode = False
    if result_token == 'TESTMODE':
        # Used solely for RDK test to skip actual put_evaluation API call
        test_mode = True

    # Invoke the Config API to report the result of the evaluation
    evaluation_copy = []
    evaluation_copy = evaluations[:]
    while evaluation_copy:
        AWS_CONFIG_CLIENT.put_evaluations(Evaluations=evaluation_copy[:100],
                                          ResultToken=result_token,
                                          TestMode=test_mode)
        del evaluation_copy[:100]

    # Used solely for RDK test to be able to test Lambda function
    return evaluations
Example #3
0
def lambda_handler(event, context):
    if "liblogging" in sys.modules:
        liblogging.logEvent(event)

    global AWS_CONFIG_CLIENT

    check_defined(event, "event")
    invoking_event = json.loads(event["invokingEvent"])

    try:
        AWS_CONFIG_CLIENT = get_redshift_client("config", event)
        if invoking_event["messageType"] in [
                "ConfigurationItemChangeNotification",
                "ScheduledNotification",
                "OversizedConfigurationItemChangeNotification",
        ]:
            configuration_item = get_configuration_item(invoking_event)
            if is_applicable(configuration_item, event):
                compliance_result = evaluate_compliance(
                    event, configuration_item)
            else:
                compliance_result = "NOT_APPLICABLE"
        else:
            return build_internal_error_response("Unexpected message type",
                                                 str(invoking_event))
    except botocore.exceptions.ClientError as ex:
        if is_internal_error(ex):
            return build_internal_error_response(
                "Unexpected error while completing API request", str(ex))
        return build_error_response(
            "Customer error while making API request",
            str(ex),
            ex.response["Error"]["Code"],
            ex.response["Error"]["Message"],
        )
    except ValueError as ex:
        return build_internal_error_response(str(ex), str(ex))

    evaluations = []
    latest_evaluations = []

    if not compliance_result:
        latest_evaluations.append(
            build_evaluation(
                event["accountId"],
                "NOT_APPLICABLE",
                event,
                resource_type="AWS::::Account",
            ))
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, str):
        if configuration_item:
            evaluations.append(
                build_evaluation_from_config_item(configuration_item,
                                                  compliance_result))
        else:
            evaluations.append(
                build_evaluation(
                    event["accountId"],
                    compliance_result,
                    event,
                    resource_type=DEFAULT_RESOURCE_TYPE,
                ))
    elif isinstance(compliance_result, list):
        for evaluation in compliance_result:
            missing_fields = False
            for field in (
                    "ComplianceResourceType",
                    "ComplianceResourceId",
                    "ComplianceType",
                    "OrderingTimestamp",
            ):
                if field not in evaluation:
                    print("Missing " + field + " from custom evaluation.")
                    missing_fields = True

            if not missing_fields:
                latest_evaluations.append(evaluation)
        evaluations = clean_up_old_evaluations(latest_evaluations, event)
    elif isinstance(compliance_result, dict):
        missing_fields = False
        for field in (
                "ComplianceResourceType",
                "ComplianceResourceId",
                "ComplianceType",
                "OrderingTimestamp",
        ):
            if field not in compliance_result:
                print("Missing " + field + " from custom evaluation.")
                missing_fields = True
        if not missing_fields:
            evaluations.append(compliance_result)
    else:
        evaluations.append(
            build_evaluation_from_config_item(configuration_item,
                                              "NOT_APPLICABLE"))

    # Put together the request that reports the evaluation status
    result_token = event["resultToken"]
    test_mode = False
    if result_token == "TESTMODE":
        # Used solely for RDK test to skip actual put_evaluation API call
        test_mode = True

    # Invoke the Config API to report the result of the evaluation
    evaluation_copy = []
    evaluation_copy = evaluations[:]
    while evaluation_copy:
        AWS_CONFIG_CLIENT.put_evaluations(
            Evaluations=evaluation_copy[:100],
            ResultToken=result_token,
            TestMode=test_mode,
        )
        del evaluation_copy[:100]

    # Used solely for RDK test to be able to test Lambda function
    return evaluations