def test_alert_schedule(cinq_test_service):
    """
    Test whether the auditor respects the alert schedule
    """

    setup_info = setup_test_aws(cinq_test_service)
    account = setup_info['account']

    prep_s3_testing(cinq_test_service)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name',
                               NS_CINQ_TEST,
                               default='testbucket')
    client.create_bucket(Bucket=bucket_name)

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Test 1 --- The auditor should not alert again as we are not at the next scheduled alert time
    auditor.run()
    assert auditor._cinq_test_notices
    auditor.run()
    assert not auditor._cinq_test_notices
def test_collect(cinq_test_service):
    """

    :return:
    """

    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    account = setup_info['account']

    cinq_test_service.start_mocking_services('ec2')

    # Add resources
    client = aws_get_client('ec2')
    resource = client.run_instances(ImageId='i-10000', MinCount=1, MaxCount=1)

    # Start collector
    collect_resources(account=account, resource_types=['ec2'])

    # verify
    assert cinq_test_service.has_resource('non-exist-id') is False
    assert cinq_test_service.has_resource(
        resource['Instances'][0]['InstanceId']) is True

    cinq_test_service.stop_mocking_services('ec2')
def test_collect_only(cinq_test_service):
    """
    Test if the auditor respects "collect_only" config item
    """

    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    account = setup_info['account']

    prep_s3_testing(cinq_test_service, collect_only=True)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name',
                               NS_CINQ_TEST,
                               default='testbucket')
    client.create_bucket(Bucket=bucket_name)

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Setup test
    cinq_test_service.modify_resource(bucket_name, 'creation_date',
                                      '2000-01-01T00:00:00')

    auditor.run()
    assert not auditor._cinq_test_notices
def test_basic_ops(cinq_test_service):
    """
    Test will pass if for an S3 bucket meet the following condition:
        - Bucket is empty
        - No Bucket Policy was set
        - No Lifecycle Policy was set
        - No tag was set

    The Auditor will:
        - Detect non-compliant S3 buckets
        - Respect grace period settings
        - Be able to remove an empty bucket successfully when the "REMOVE" criteria are met
    """
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    prep_s3_testing(cinq_test_service)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name',
                               NS_CINQ_TEST,
                               default='testbucket')
    client.create_bucket(Bucket=bucket_name)

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Test 1 --- Test if auditor respect grace period settings
    cinq_test_service.modify_resource(bucket_name, 'creation_date',
                                      datetime.datetime.utcnow().isoformat())
    auditor.run()
    assert auditor._cinq_test_notices == {}

    # Test 2 --- Test if auditor can pick up non-compliant resources correctly
    cinq_test_service.modify_resource(bucket_name, 'creation_date',
                                      '2000-01-01T00:00:00')

    auditor.run()
    notices = auditor._cinq_test_notices
    assert bucket_name == notices[recipient]['not_fixed'][0]['resource'].id

    # Test 3 --- Modify the issue creation date so it will meet the criteria of "remove" action
    cinq_test_service.modify_issue(
        auditor._cinq_test_notices[recipient]['not_fixed'][0]['issue'].id,
        'created', 0)
    auditor.run()
    notices = auditor._cinq_test_notices
    ''' Check if the action is correct'''
    assert notices[recipient]['not_fixed'][0]['action'] == AuditActions.REMOVE
    ''' Check if the bucket is actually removed '''
    assert len(client.list_buckets()['Buckets']) == 0
示例#5
0
def test_remove_non_empty_bucket(cinq_test_service):
    """
    Test will pass if for an S3 bucket meet the following condition:
        - Bucket is NOT empty
        - No Bucket Policy was set
        - No Lifecycle Policy was set
        - No tag was set

    The Auditor will:
        - Apply Cinq lifecycle policy to the bucket
    """
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    prep_s3_testing(cinq_test_service)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name', NS_CINQ_TEST, default='testbucket')
    client.create_bucket(Bucket=bucket_name)
    s3_upload_file_from_string(client, bucket_name, 'sample', 'sample text')

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Setup test case
    cinq_test_service.modify_resource(
        bucket_name,
        'creation_date',
        '2000-01-01T00:00:00'
    )
    auditor.run()

    with pytest.raises(ClientError):
        client.get_bucket_lifecycle_configuration(Bucket=bucket_name)['Rules']

    cinq_test_service.modify_issue(
        auditor._cinq_test_notices[recipient]['not_fixed'][0]['issue'].id,
        'created',
        0
    )
    auditor.run()

    # Verify if the Lifecycle policy is added
    current_policy = client.get_bucket_lifecycle_configuration(Bucket=bucket_name)['Rules'][0]
    assert current_policy['ID'] == 'cloudInquisitor'
    assert current_policy['Status'] == 'Enabled'
    assert current_policy['Expiration'] == {
        'Days': dbconfig.get('lifecycle_expiration_days', NS_AUDITOR_REQUIRED_TAGS, 3)
    }

    '''
def test_fixed_buckets(cinq_test_service):
    """
    Test will pass if for an S3 bucket meet the following condition:
        - Bucket is empty
        - No Bucket Policy was set
        - No Lifecycle Policy was set
        - There was no tag doing the initial audit but missing tags were added during the second audit

    The Auditor will:
        - Detect non-compliant S3 buckets during the first audit
        - Detect Fixed Buckets correctly
    """
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    prep_s3_testing(cinq_test_service)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name', NS_CINQ_TEST, default='testbucket')
    client.create_bucket(Bucket=bucket_name)

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Setup test case
    cinq_test_service.modify_resource(
        bucket_name,
        'creation_date',
        '2000-01-01T00:00:00'
    )
    auditor.run()

    notices = auditor._cinq_test_notices
    assert notices[recipient]['not_fixed'][0]['resource']['resource_id'] == bucket_name

    client.put_bucket_tagging(
        Bucket=bucket_name,
        Tagging={'TagSet': VALID_TAGSET}
    )
    collect_resources(account=account, resource_types=['s3'])
    auditor.run()
    notices = auditor._cinq_test_notices

    # Verify if the auditor will report the issue fixed
    assert notices[recipient]['fixed'][0]['action'] == AuditActions.FIXED
    assert notices[recipient]['fixed'][0]['resource'].resource_id == bucket_name
def test_basic_ops(cinq_test_service):
    """
    Test will pass if:
    1. Auditor can detect non-compliant EC2 instances
    2. Auditor respect grace period settings
    """

    # Prep
    cinq_test_service.start_mocking_services('ec2')

    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    db_setting = dbconfig.get('audit_scope', NS_AUDITOR_REQUIRED_TAGS)
    db_setting['enabled'] = ['aws_ec2_instance']
    dbconfig.set(NS_AUDITOR_REQUIRED_TAGS, 'audit_scope', DBCJSON(db_setting))
    dbconfig.set(NS_AUDITOR_REQUIRED_TAGS, 'collect_only', False)

    # Add resources
    client = aws_get_client('ec2')
    resource = client.run_instances(ImageId='i-10000', MinCount=1, MaxCount=1)

    # Collect resources
    collect_resources(account=account, resource_types=['ec2'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Test 1 --- Test if auditor respect grace period settings
    cinq_test_service.modify_resource(resource['Instances'][0]['InstanceId'],
                                      'launch_date',
                                      datetime.datetime.utcnow().isoformat())
    auditor.run()
    assert auditor._cinq_test_notices == {}

    # Test 2 --- Test if auditor can pick up non-compliant resources correctly
    ''' Modify resource property'''
    assert cinq_test_service.modify_resource(
        resource['Instances'][0]['InstanceId'], 'launch_date',
        '2000-01-01T00:00:00') is True

    auditor.run()
    notices = auditor._cinq_test_notices

    assert recipient in notices
    assert notices[recipient]['not_fixed'][0][
        'resource'].resource_id == resource['Instances'][0]['InstanceId']
def test_rds_corrupted_data(cinq_test_service):
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    auditor = MockRequiredTagsAuditor()

    new_resource = create_resource(resource_type=RDSInstance,
                                   resource_id=uuid.uuid4().hex,
                                   account_id=account.account_id,
                                   properties={},
                                   tags={},
                                   auto_add=True,
                                   auto_commit=True)

    auditor.run(enable_process_action=False)
    assert auditor._cinq_test_notices == {}
示例#9
0
def test_audit(cinq_test_service):
    """

    :return:
    """

    # Prep
    cinq_test_service.start_mocking_services('ec2')

    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    db_setting = dbconfig.get('audit_scope', NS_AUDITOR_REQUIRED_TAGS)
    db_setting['enabled'] = ['aws_ec2_instance']
    dbconfig.set(NS_AUDITOR_REQUIRED_TAGS, 'audit_scope', DBCJSON(db_setting))

    # Tests
    case_1(cinq_test_service, account, recipient)
def test_compliant_bucket(cinq_test_service):
    """
    Test will pass if for an S3 bucket meet the following condition:
        - Is compliant

    The Auditor will:
        - Not mark compliant buckets as non-compliant
    """

    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    account = setup_info['account']

    prep_s3_testing(cinq_test_service)

    # Add resources
    client = aws_get_client('s3')
    bucket_name = dbconfig.get('test_bucket_name', NS_CINQ_TEST, default='testbucket')
    client.create_bucket(Bucket=bucket_name)

    client.put_bucket_tagging(
        Bucket=bucket_name,
        Tagging={'TagSet': VALID_TAGSET}
    )

    # Collect resources
    collect_resources(account=account, resource_types=['s3'])

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()

    # Setup test case
    cinq_test_service.modify_resource(
        bucket_name,
        'creation_date',
        '2000-01-01T00:00:00'
    )
    auditor.run()
    assert auditor._cinq_test_notices == {}
def test_rds_generic(cinq_test_service):
    """
    1. We will generate batch of compliant and non-compliant RDS resources, run the auditor and check if it works as
        expected
    2. We will make random non-compliant RDS instance meets the FIXED, STOP or REMOVE criteria and check if it works as
        expected
    """
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']
    compliant_resources = []
    non_compliant_resources = []

    prep_rds_testing(cinq_test_service)

    # Add resources
    num_resources = 50

    for i in range(0, num_resources):
        compliance_selector = random.randint(0, 1)
        if compliance_selector:
            tags = VALID_TAGS
        else:
            tags = {}

        new_resource = create_resource(resource_type=RDSInstance,
                                       resource_id=uuid.uuid4().hex,
                                       account_id=account.account_id,
                                       properties={
                                           'creation_date':
                                           datetime.datetime(2000, 1, 1),
                                           'metrics': {},
                                           'engine':
                                           'mysql'
                                       },
                                       tags=tags,
                                       auto_add=True,
                                       auto_commit=True)

        if compliance_selector:
            compliant_resources.append(new_resource.id)
        else:
            non_compliant_resources.append(new_resource.id)

    # Initialize auditor
    auditor = MockRequiredTagsAuditor()
    auditor.run(enable_process_action=False)

    issue_not_fixed = auditor._cinq_test_notices[recipient]['not_fixed']

    for item in issue_not_fixed:
        assert item['resource'].id not in compliant_resources
        assert item['resource'].id in non_compliant_resources
        assert item['action'] == AuditActions.ALERT

    resources_to_terminate = []
    resources_to_stop = []
    resources_fixed = []

    for item in issue_not_fixed:
        mock_selector = random.randint(0, 3)

        if mock_selector == 3:
            # Mock resources that should be terminated
            cinq_test_service.modify_issue(item['issue'].id, 'created', 0)
            resources_to_terminate.append(item['resource'].id)

        elif mock_selector == 2:
            # Mock resources that should be stopped
            cinq_test_service.modify_issue(
                item['issue'].id, 'created',
                item['issue'].created - STANDARD_ALERT_SETTINGS_STOP - 1)
            resources_to_stop.append(item['resource'].id)
        elif mock_selector == 1:
            set_tags(item['resource'], VALID_TAGS)
            resources_fixed.append(item['resource'].id)
        else:
            # Leave the issue as-is
            pass

    auditor.run(enable_process_action=False)
    issue_not_fixed = auditor._cinq_test_notices[recipient]['not_fixed']
    issue_fixed = auditor._cinq_test_notices[recipient]['fixed']

    for item in issue_not_fixed:
        if item['action'] == AuditActions.STOP:
            resources_to_stop.remove(item['resource'].id)
        elif item['action'] == AuditActions.REMOVE:
            resources_to_terminate.remove(item['resource'].id)

    for item in issue_fixed:
        resources_fixed.remove(item['resource'].resource_id)

    assert resources_to_stop == []
    assert resources_to_terminate == []
    assert resources_fixed == []
示例#12
0
def test_volume_ec2_s3(cinq_test_service):
    """

    :return:
    """
    # Prep
    setup_info = setup_test_aws(cinq_test_service)
    recipient = setup_info['recipient']
    account = setup_info['account']

    set_audit_scope('aws_ec2_instance', 'aws_s3_bucket')
    dbconfig.set(NS_AUDITOR_REQUIRED_TAGS, 'collect_only', False)
    cinq_test_service.start_mocking_services('cloudwatch', 'ec2', 's3')

    num_resources = 100
    compliant_buckets = []
    non_compliant_buckets = []
    compliant_ec2 = []
    non_compliant_ec2 = []

    client_s3 = aws_get_client('s3')
    client_ec2 = aws_get_client('ec2')
    regions = get_aws_regions('s3')

    # Workaround for a moto cloudwatch KeyError bug
    regions.remove('eu-west-3')

    # Setup resources
    for i in range(0, num_resources):
        bucket_name = uuid.uuid4().hex
        client_s3.create_bucket(
            Bucket=bucket_name,
            CreateBucketConfiguration={'LocationConstraint': random.choice(regions)}
        )
        compliant_buckets.append(bucket_name) if random.randint(0, 1) else non_compliant_buckets.append(bucket_name)

        resource = client_ec2.run_instances(ImageId='i-{}'.format(i), MinCount=1, MaxCount=1)
        instance_id = resource['Instances'][0]['InstanceId']
        compliant_ec2.append(instance_id) if random.randint(0, 1) else non_compliant_ec2.append(instance_id)

    for instance_id in compliant_ec2:
        client_ec2.create_tags(
            Resources=[instance_id],
            Tags=VALID_TAGSET
        )

    for item in compliant_buckets:
        client_s3.put_bucket_tagging(
            Bucket=item,
            Tagging={'TagSet': VALID_TAGSET}
        )

    # collection
    collect_resources(account=account, resource_types=['ec2', 's3'])

    for item in compliant_buckets + non_compliant_buckets:
        cinq_test_service.modify_resource(
            item,
            'creation_date',
            '2000-01-01T00:00:00'
        )

    for instance_id in compliant_ec2 + non_compliant_ec2:
        cinq_test_service.modify_resource(
            instance_id,
            'launch_date',
            '2000-01-01T00:00:00'
        )

    auditor = MockRequiredTagsAuditor()
    auditor.run()

    compliant_resources = compliant_buckets + compliant_ec2
    non_compliant_resources = non_compliant_buckets + non_compliant_ec2
    for item in auditor._cinq_test_notices[recipient]['not_fixed']:
        assert item['resource'].id not in compliant_resources
        assert item['resource'].id in non_compliant_resources

    assert len(non_compliant_resources) == len(auditor._cinq_test_notices[recipient]['not_fixed'])