def test_cwe_update_config_and_code(self): # Originally this was testing the no update case.. but # That is tricky to record, any updates to the code end up # causing issues due to checksum mismatches which imply updating # the function code / which invalidate the recorded data and # the focus of the test. session_factory = self.replay_flight_data( 'test_cwe_update', zdata=True) p = Policy({ 'resource': 's3', 'name': 's3-bucket-policy', 'mode': { 'type': 'cloudtrail', 'events': ["CreateBucket"], }, 'filters': [ {'type': 'missing-policy-statement', 'statement_ids': ['RequireEncryptedPutObject']}], 'actions': ['no-op'] }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.addCleanup(mgr.remove, pl) p = Policy({ 'resource': 's3', 'name': 's3-bucket-policy', 'mode': { 'type': 'cloudtrail', 'memory': 256, 'events': [ "CreateBucket", {'event': 'PutBucketPolicy', 'ids': 'requestParameters.bucketName', 'source': 's3.amazonaws.com'}] }, 'filters': [ {'type': 'missing-policy-statement', 'statement_ids': ['RequireEncryptedPutObject']}], 'actions': ['no-op'] }, Config.empty()) output = self.capture_logging('custodian.lambda', level=logging.DEBUG) result2 = mgr.publish(PolicyLambda(p), 'Dev', role=self.role) lines = output.getvalue().strip().split('\n') self.assertTrue( 'Updating function custodian-s3-bucket-policy code' in lines) self.assertTrue( 'Updating function: custodian-s3-bucket-policy config' in lines) self.assertEqual(result['FunctionName'], result2['FunctionName']) # drive by coverage functions = [i for i in mgr.list_functions() if i['FunctionName'] == 'custodian-s3-bucket-policy'] self.assertTrue(len(functions), 1) start = 0L end = long(time.time() * 1000) self.assertEqual(list(mgr.logs(pl, start, end)), [])
def test_cwe_schedule(self): session_factory = self.replay_flight_data( 'test_cwe_schedule', zdata=True) p = Policy({ 'resource': 'ec2', 'name': 'periodic-ec2-checker', 'mode': { 'type': 'periodic', 'schedule': 'rate(1 day)' } }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, {'FunctionName': 'c7n-periodic-ec2-checker', 'Handler': 'c7n_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) events = session_factory().client('events') result = events.list_rules(NamePrefix="c7n-periodic-ec2-checker") self.assert_items( result['Rules'][0], { "State": "ENABLED", "ScheduleExpression": "rate(1 day)", "Name": "c7n-periodic-ec2-checker"}) mgr.remove(pl)
def test_consolidate_query_filter(self): session_factory = self.replay_flight_data('test_emr_query_ids') ctx = Bag(session_factory=session_factory, log_dir='', options=Config.empty()) query = { 'query': [{ 'tag:foo': 'val1' }, { 'tag:foo': 'val2' }, { 'tag:bar': 'val3' }] } mgr = emr.EMRCluster(ctx, query) self.assertEqual(mgr.consolidate_query_filter(), [{ 'Values': ['val1', 'val2'], 'Name': 'tag:foo' }, { 'Values': ['val3'], 'Name': 'tag:bar' }])
def test_cwe_asg_instance(self): session_factory = self.replay_flight_data('test_cwe_asg', zdata=True) p = Policy({ 'resource': 'asg', 'name': 'asg-spin-detector', 'mode': { 'type': 'asg-instance-state', 'events': ['launch-failure']} }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) self.addCleanup(mgr.remove, pl) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, {'FunctionName': 'custodian-asg-spin-detector', 'Handler': 'custodian_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) events = session_factory().client('events') result = events.list_rules(NamePrefix="custodian-asg-spin-detector") self.assert_items( result['Rules'][0], {"State": "ENABLED", "Name": "custodian-asg-spin-detector"}) self.assertEqual( json.loads(result['Rules'][0]['EventPattern']), {"source": ["aws.autoscaling"], "detail-type": ["EC2 Instance Launch Unsuccessful"]})
def test_cwe_schedule(self): session_factory = self.replay_flight_data( 'test_cwe_schedule', zdata=True) p = Policy({ 'resource': 'ec2', 'name': 'periodic-ec2-checker', 'mode': { 'type': 'periodic', 'schedule': 'rate(1 day)' } }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) self.addCleanup(mgr.remove, pl) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, {'FunctionName': 'custodian-periodic-ec2-checker', 'Handler': 'custodian_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) events = session_factory().client('events') result = events.list_rules(NamePrefix="custodian-periodic-ec2-checker") self.assert_items( result['Rules'][0], { "State": "ENABLED", "ScheduleExpression": "rate(1 day)", "Name": "custodian-periodic-ec2-checker"})
def test_cwe_asg_instance(self): session_factory = self.replay_flight_data('test_cwe_asg', zdata=True) p = Policy({ 'resource': 'asg', 'name': 'asg-spin-detector', 'mode': { 'type': 'asg-instance-state', 'events': ['launch-failure']} }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, {'FunctionName': 'c7n-asg-spin-detector', 'Handler': 'c7n_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) events = session_factory().client('events') result = events.list_rules(NamePrefix="c7n-asg-spin-detector") self.assert_items( result['Rules'][0], {"State": "ENABLED", "Name": "c7n-asg-spin-detector"}) self.assertEqual( json.loads(result['Rules'][0]['EventPattern']), {"source": ["aws.autoscaling"], "detail-type": ["EC2 Instance Launch Unsuccessful"]}) mgr.remove(pl)
def get_s3_output(self): output = S3Output( ExecutionContext( None, Bag(name="xyz"), Config.empty(output_dir="s3://cloud-custodian/policies"))) self.addCleanup(shutil.rmtree, output.root_dir) return output
def test_policy_account_expand(self): original = policy.PolicyCollection.from_data( {'policies': [{ 'name': 'foo', 'resource': 'account' }]}, Config.empty(regions=['us-east-1', 'us-west-2'])) collection = original.expand_regions(['all']) self.assertEqual(len(collection), 1)
def test_get_emr_by_ids(self): session_factory = self.replay_flight_data('test_emr_query_ids') ctx = Bag(session_factory=session_factory, log_dir='', options=Config.empty()) mgr = emr.EMRCluster(ctx, {}) resources = mgr.get_resources(["j-1EJMJNTXC63JW"]) self.assertEqual(resources[0]['Id'], "j-1EJMJNTXC63JW")
def test_get_emr_by_ids(self): session_factory = self.replay_flight_data( 'test_emr_query_ids') ctx = Bag( session_factory=session_factory, log_dir='', options=Config.empty()) mgr = emr.EMRCluster(ctx, {}) resources = mgr.get_resources(["j-1EJMJNTXC63JW"]) self.assertEqual(resources[0]['Id'], "j-1EJMJNTXC63JW")
def test_config_rule_provision(self): session_factory = self.replay_flight_data('test_config_rule') p = Policy({ 'resource': 'security-group', 'name': 'sg-modified', 'mode': {'type': 'config-rule'}, }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.assertEqual(result['FunctionName'], 'custodian-sg-modified') self.addCleanup(mgr.remove, pl)
def update_a_lambda(self, mgr, **config): mode = { 'type': 'config-rule', 'role':'arn:aws:iam::644160558196:role/custodian-mu'} mode.update(config) p = Policy({ 'resource': 's3', 'name': 'hello-world', 'actions': ['no-op'], 'mode': mode }, Config.empty()) pl = PolicyLambda(p) return mgr.publish(pl)
def test_resource_permissions(self): self.capture_logging('c7n.cache') missing = [] cfg = Config.empty() for k, v in manager.resources.items(): p = Bag({'name': 'permcheck', 'resource': k}) ctx = self.get_context(config=cfg, policy=p) mgr = v(ctx, p) perms = mgr.get_permissions() if not perms: missing.append(k) for n, a in v.action_registry.items(): p['actions'] = [n] perms = a({}, mgr).get_permissions() found = bool(perms) if not isinstance(perms, (list, tuple, set)): found = False if not found: missing.append("%s.actions.%s" % ( k, n)) for n, f in v.filter_registry.items(): if n in ('and', 'or', 'not'): continue p['filters'] = [n] perms = f({}, mgr).get_permissions() if not isinstance(perms, (tuple, list, set)): missing.append("%s.filters.%s" % ( k, n)) # in memory filters if n in ('event', 'value', 'tag-count', 'marked-for-op', 'offhour', 'onhour', 'age', 'state-age', 'egress', 'ingress', 'capacity-delta', 'is-ssl', 'global-grants', 'missing-policy-statement', 'missing-statement', 'healthcheck-protocol-mismatch', 'image-age', 'has-statement', 'instance-age', 'ephemeral', 'instance-uptime'): continue if not perms: missing.append("%s.filters.%s" % ( k, n)) if missing: self.fail("Missing permissions %d on \n\t%s" % ( len(missing), "\n\t".join(sorted(missing))))
def test_consolidate_query_filter(self): session_factory = self.replay_flight_data( 'test_emr_query_ids') ctx = Bag( session_factory=session_factory, log_dir='', options=Config.empty()) query = { 'query': [ {'tag:foo': 'val1'}, {'tag:foo': 'val2'}, {'tag:bar': 'val3'} ] } mgr = emr.EMRCluster(ctx, query) self.assertEqual( mgr.consolidate_query_filter(), [ {'Values': ['val1', 'val2'], 'Name': 'tag:foo'}, {'Values': ['val3'], 'Name': 'tag:bar'}, # default query { 'Values': ['WAITING', 'RUNNING', 'BOOTSTRAPPING'], 'Name': 'ClusterStates', }, ] ) query = { 'query': [ {'tag:foo': 'val1'}, {'tag:foo': 'val2'}, {'tag:bar': 'val3'}, {'ClusterStates': 'terminated'}, ] } mgr = emr.EMRCluster(ctx, query) self.assertEqual( mgr.consolidate_query_filter(), [ {'Values': ['val1', 'val2'], 'Name': 'tag:foo'}, {'Values': ['val3'], 'Name': 'tag:bar'}, # verify default is overridden { 'Values': ['terminated'], 'Name': 'ClusterStates', }, ] )
def test_resource_manager(self): config = Config.empty(account_id='644160558196') factory = self.replay_flight_data('test_elasticsearch_query') p = self.load_policy({ 'name': 'es-query', 'resource': 'elasticsearch', 'filters': [{'DomainName': 'c7n-test'}] }, session_factory=factory, config=config) resources = p.run() self.assertEqual(len(resources), 1) self.assertEqual(resources[0]['DomainName'], 'c7n-test') self.assertEqual(resources[0]['Tags'], [{u'Key': u'Env', u'Value': u'Dev'}]) self.assertTrue( resources[0]['Endpoint'].startswith( 'search-c7n-test-ug4l2nqtnwwrktaeagxsqso'))
def create_a_lambda(self, flight, **extra): session_factory = self.replay_flight_data(flight, zdata=True) mode = { 'type': 'config-rule', 'role':'arn:aws:iam::644160558196:role/custodian-mu'} mode.update(extra) p = Policy({ 'resource': 's3', 'name': 'hello-world', 'actions': ['no-op'], 'mode': mode, }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) self.addCleanup(mgr.remove, pl) return mgr, mgr.publish(pl)
def test_delete_search(self): config = Config.empty(account_id='644160558196') factory = self.replay_flight_data('test_elasticsearch_delete') p = self.load_policy({ 'name': 'es-query', 'resource': 'elasticsearch', 'filters': [{'DomainName': 'c7n-test'}], 'actions': ['delete'] }, session_factory=factory, config=config) resources = p.run() self.assertEqual(len(resources), 1) self.assertEqual(resources[0]['DomainName'], 'c7n-test') client = factory().client('es') state = client.describe_elasticsearch_domain( DomainName='c7n-test')['DomainStatus'] self.assertEqual(state['Deleted'], True)
def test_cwe_trail(self): session_factory = self.replay_flight_data('test_cwe_trail', zdata=True) p = Policy( { 'resource': 's3', 'name': 's3-bucket-policy', 'mode': { 'type': 'cloudtrail', 'events': ["CreateBucket"], }, 'filters': [{ 'type': 'missing-policy-statement', 'statement_ids': ['RequireEncryptedPutObject'] }], 'actions': ['no-op'] }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) events = pl.get_events(session_factory) self.assertEqual(len(events), 1) event = events.pop() self.assertEqual( json.loads(event.render_event_pattern()), { u'detail': { u'eventName': [u'CreateBucket'], u'eventSource': [u's3.amazonaws.com'] }, u'detail-type': ['AWS API Call via CloudTrail'] }) self.assert_items( result, { 'Description': 'cloud-custodian lambda policy', 'FunctionName': 'custodian-s3-bucket-policy', 'Handler': 'custodian_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60 }) mgr.remove(pl)
def test_mu_metrics(self): session_factory = self.replay_flight_data('test_mu_metrics') p = Policy({ 'resources': 's3', 'name': 's3-bucket-policy', 'resource': 's3', 'mode': { 'type': 'cloudtrail', 'events': ['CreateBucket'], }, 'actions': ['no-op']}, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) end = datetime.utcnow() start = end - timedelta(1) results = mgr.metrics([pl], start, end, 3600) self.assertEqual( results, [{'Durations': [], 'Errors': [], 'Throttles': [], 'Invocations': []}])
def test_cwe_instance(self): session_factory = self.replay_flight_data('test_cwe_instance', zdata=True) p = Policy( { 'resource': 's3', 'name': 'ec2-encrypted-vol', 'mode': { 'type': 'ec2-instance-state', 'events': ['pending'] } }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, { 'Description': 'cloud-custodian lambda policy', 'FunctionName': 'c7n-ec2-encrypted-vol', 'Handler': 'c7n_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60 }) events = session_factory().client('events') result = events.list_rules(NamePrefix="c7n-ec2-encrypted-vol") self.assert_items(result['Rules'][0], { "State": "ENABLED", "Name": "c7n-ec2-encrypted-vol" }) self.assertEqual( json.loads(result['Rules'][0]['EventPattern']), { "source": ["aws.ec2"], "detail": { "state": ["pending"] }, "detail-type": ["EC2 Instance State-change Notification"] }) mgr.remove(pl)
def test_cwe_instance(self): session_factory = self.replay_flight_data( 'test_cwe_instance', zdata=True) p = Policy({ 'resource': 's3', 'name': 'ec2-encrypted-vol', 'mode': { 'type': 'ec2-instance-state', 'events': ['pending']} }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) self.assert_items( result, {'Description': 'cloud-custodian lambda policy', 'FunctionName': 'c7n-ec2-encrypted-vol', 'Handler': 'c7n_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) events = session_factory().client('events') result = events.list_rules(NamePrefix="c7n-ec2-encrypted-vol") self.assert_items( result['Rules'][0], {"State": "ENABLED", "Name": "c7n-ec2-encrypted-vol"}) self.assertEqual( json.loads(result['Rules'][0]['EventPattern']), {"source": ["aws.ec2"], "detail": { "state": ["pending"]}, "detail-type": ["EC2 Instance State-change Notification"]}) mgr.remove(pl)
def test_policy_region_expand_global(self): original = policy.PolicyCollection.from_data( { 'policies': [{ 'name': 'foo', 'resource': 's3' }, { 'name': 'iam', 'resource': 'iam-user' }] }, Config.empty(regions=['us-east-1', 'us-west-2'])) collection = original.expand_regions(['all']) self.assertEqual(len(collection.resource_types), 2) self.assertEqual(len(collection), 15) iam = [p for p in collection if p.resource_type == 'iam-user'] self.assertEqual(len(iam), 1) self.assertEqual(iam[0].options.region, 'us-east-1') collection = original.expand_regions(['eu-west-1', 'eu-west-2']) iam = [p for p in collection if p.resource_type == 'iam-user'] self.assertEqual(len(iam), 1) self.assertEqual(iam[0].options.region, 'eu-west-1') self.assertEqual(len(collection), 3)
def test_cwe_trail(self): session_factory = self.replay_flight_data('test_cwe_trail', zdata=True) p = Policy({ 'resource': 's3', 'name': 's3-bucket-policy', 'mode': { 'type': 'cloudtrail', 'events': ["CreateBucket"], }, 'filters': [ {'type': 'missing-policy-statement', 'statement_ids': ['RequireEncryptedPutObject']}], 'actions': ['no-op'] }, Config.empty()) pl = PolicyLambda(p) mgr = LambdaManager(session_factory) result = mgr.publish(pl, 'Dev', role=self.role) events = pl.get_events(session_factory) self.assertEqual(len(events), 1) event = events.pop() self.assertEqual( json.loads(event.render_event_pattern()), {u'detail': {u'eventName': [u'CreateBucket'], u'eventSource': [u's3.amazonaws.com']}, u'detail-type': ['AWS API Call via CloudTrail']}) self.assert_items( result, {'Description': 'cloud-custodian lambda policy', 'FunctionName': 'custodian-s3-bucket-policy', 'Handler': 'custodian_policy.run', 'MemorySize': 512, 'Runtime': RUNTIME, 'Timeout': 60}) mgr.remove(pl)
def get_manager(self, data, config=None, session_factory=None): ctx = ExecutionContext(session_factory, Bag({'name': 'test-policy'}), config or Config.empty()) return EC2(ctx, data)
# See the License for the specific language governing permissions and # limitations under the License. import unittest from dateutil.parser import parse as date_parse from c7n.policy import Policy from c7n.reports.csvout import Formatter from common import Config, load_data EC2_POLICY = Policy( { 'name': 'report-test-ec2', 'resource': 'ec2', }, Config.empty(), ) ASG_POLICY = Policy( { 'name': 'report-test-asg', 'resource': 'asg', }, Config.empty(), ) ELB_POLICY = Policy( { 'name': 'report-test-elb', 'resource': 'elb', }, Config.empty(), )
def test_consolidate_query_filter(self): session_factory = self.replay_flight_data('test_emr_query_ids') ctx = Bag(session_factory=session_factory, log_dir='', options=Config.empty()) query = { 'query': [{ 'tag:foo': 'val1' }, { 'tag:foo': 'val2' }, { 'tag:bar': 'val3' }] } mgr = emr.EMRCluster(ctx, query) self.assertEqual( mgr.consolidate_query_filter(), [ { 'Values': ['val1', 'val2'], 'Name': 'tag:foo' }, { 'Values': ['val3'], 'Name': 'tag:bar' }, # default query { 'Values': ['WAITING', 'RUNNING', 'BOOTSTRAPPING'], 'Name': 'ClusterStates', }, ]) query = { 'query': [ { 'tag:foo': 'val1' }, { 'tag:foo': 'val2' }, { 'tag:bar': 'val3' }, { 'ClusterStates': 'terminated' }, ] } mgr = emr.EMRCluster(ctx, query) self.assertEqual( mgr.consolidate_query_filter(), [ { 'Values': ['val1', 'val2'], 'Name': 'tag:foo' }, { 'Values': ['val3'], 'Name': 'tag:bar' }, # verify default is overridden { 'Values': ['terminated'], 'Name': 'ClusterStates', }, ])
def test_file_not_found(self): self.assertRaises( IOError, policy.load, Config.empty(), "/asdf12")
# limitations under the License. import unittest from dateutil.parser import parse as date_parse from c7n.policy import Policy from c7n.reports.csvout import Formatter from common import Config, load_data EC2_POLICY = Policy( { 'name': 'report-test-ec2', 'resource': 'ec2', }, Config.empty(), ) ASG_POLICY = Policy( { 'name': 'report-test-asg', 'resource': 'asg', }, Config.empty(), ) ELB_POLICY = Policy( { 'name': 'report-test-elb', 'resource': 'elb', }, Config.empty(), )
def get_manager(self, data, config=None, session_factory=None): ctx = ExecutionContext( session_factory, Bag({'name':'test-policy'}), config or Config.empty()) return EC2(ctx, data)