def test_custom_bad_hours(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=19, minute=00) # default error handling is to exclude the resource with mock_datetime_now(t, datetime): # This isn't considered a bad value, its basically omitted. i = instance(Tags=[{"Key": "maid_offhours", "Value": "off=();tz=et"}]) self.assertEqual(OffHour({})(i), False) i = instance( Tags=[ {"Key": "maid_offhours", "Value": "off=(m-f,90);on=(m-f,7);tz=et"} ] ) # malformed value self.assertEqual(OffHour({})(i), False) t = t.replace(year=2016, month=5, day=26, hour=13, minute=00) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "off=();tz=et"}]) # will go to default values, but not work due to default time self.assertEqual(OffHour({})(i), False) i = instance( Tags=[ {"Key": "maid_offhours", "Value": "off=(m-f,90);on=(m-f,7);tz=et"} ] ) self.assertEqual(OffHour({})(i), False)
def test_on_off_hours(self): t = datetime.datetime.now(tzutils.gettz("pt")) t = t.replace(year=2018, month=8, day=24, hour=18, minute=30) with mock_datetime_now(t, datetime): p = self.load_policy({ 'name': 'test-azure-vm', 'resource': 'azure.vm', 'filters': [ {'type': 'offhour', 'default_tz': "pt", 'offhour': 18, 'tag': 'schedule'} ], }) resources = p.run() self.assertEqual(len(resources), 1) t = t.replace(year=2018, month=8, day=24, hour=8, minute=30) with mock_datetime_now(t, datetime): p = self.load_policy({ 'name': 'test-azure-vm', 'resource': 'azure.vm', 'filters': [ {'type': 'onhour', 'default_tz': "pt", 'onhour': 8, 'tag': 'schedule'} ], }) resources = p.run() self.assertEqual(len(resources), 1)
def test_process(self): f = OffHour({"opt-out": True}) instances = [ instance(Tags=[]), instance(Tags=[{"Key": "maid_offhours", "Value": ""}]), instance(Tags=[{"Key": "maid_offhours", "Value": "on"}]), instance(Tags=[{"Key": "maid_offhours", "Value": "off"}]), instance( Tags=[ { "Key": "maid_offhours", "Value": "off=(m-f,5);zebrablue,on=(t-w,5)", } ] ), ] t = datetime.datetime( year=2015, month=12, day=1, hour=19, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) with mock_datetime_now(t, datetime): self.assertEqual( f.process(instances), [instances[0], instances[1], instances[2]] )
def test_custom_onhours(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=7, minute=00) results = [] with mock_datetime_now(t, datetime): for i in [ instance( Tags=[ { "Key": "maid_offhours", "Value": "off=(m-f,19);on=(m-f,7);tz=et", } ] ), instance( Tags=[ { "Key": "maid_offhours", "Value": "off=(m-f,20);on=(m-f,9);tz=et", } ] ), ]: results.append(OnHour({})(i)) self.assertEqual(results, [True, False])
def test_resource_schedule_error(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2015, month=12, day=1, hour=19, minute=5) f = OffHour({}) f.process_resource_schedule = lambda: False with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) self.assertEqual(f(i), False)
def test_output(bucket, client, request): bucket().blob.return_value = key = mock.MagicMock() with mock_datetime_now(date_parse('2020/06/10 13:00'), datetime): output = get_blob_output(request) assert output.key_prefix == 'policies/xyz/2020/06/10/13' output.upload_file('resources.json', f"{output.key_prefix}/resources.json") key.upload_from_filename.assert_called_once()
def test_output_path(self): with mock_datetime_now(date_parse('2020/06/10 13:00'), datetime): output = self.get_s3_output(output_url='s3://prefix/') self.assertEqual(output.get_output_path('s3://prefix/'), 's3://prefix/xyz/2020/06/10/13') self.assertEqual( output.get_output_path( 's3://prefix/{region}/{account_id}/{policy_name}/{now:%Y}/' ), 's3://prefix/us-east-1/112233445566/xyz/2020')
def test_offhour_weekend_support(self): start_day = 26 t = datetime.datetime(year=2016, day=start_day, month=2, hour=19, minute=20) i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OffHour({}) results = [] with mock_datetime_now(t, datetime) as dt: for n in range(0, 4): dt.target = t.replace(day=start_day + n) results.append(f(i)) self.assertEqual(results, [True, False, False, True])
def test_offhours(self): t = datetime.datetime( year=2015, month=12, day=1, hour=19, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) self.assertEqual(OffHour({})(i), True)
def test_everyday_offhour(self): # weekends on means we match times on the weekend start_day = 14 # sunday t = datetime.datetime(year=2016, day=start_day, month=8, hour=19, minute=20) i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OffHour({"weekends": False}) results = [] with mock_datetime_now(t, datetime) as dt: for n in range(7): dt.target = t.replace(day=start_day + n) results.append(f(i)) self.assertEqual(results, [True] * 7)
def test_on_off_hours(self): t = datetime.datetime.now(tzutils.gettz("pt")) t = t.replace(year=2018, month=8, day=24, hour=18, minute=30) with mock_datetime_now(t, datetime): p = self.load_policy({ 'name': 'test-azure-vm', 'resource': 'azure.vm', 'filters': [{ 'type': 'offhour', 'default_tz': "pt", 'offhour': 18, 'tag': 'schedule' }], }) resources = p.run() self.assertEqual(len(resources), 1) t = t.replace(year=2018, month=8, day=24, hour=8, minute=30) with mock_datetime_now(t, datetime): p = self.load_policy({ 'name': 'test-azure-vm', 'resource': 'azure.vm', 'filters': [{ 'type': 'onhour', 'default_tz': "pt", 'onhour': 8, 'tag': 'schedule' }], }) resources = p.run() self.assertEqual(len(resources), 1)
def test_credential_report(self): session_factory = self.replay_flight_data("test_account_credential_report") p = self.load_policy( { "name": "credential-details", "resource": "account", "filters": [{"type": "credential", "key": "mfa_active", "value": True}], }, session_factory=session_factory, ) with mock_datetime_now(parser.parse("2017-02-23T00:40:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 1)
def test_current_time_test(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2015, month=12, day=1, hour=19, minute=5) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OffHour({}) p = f.get_tag_value(i) self.assertEqual(p, "tz=est") tz = f.get_tz("est") self.assertTrue('America/New_York' in str(tz) or 'US/Eastern' in str(tz)) self.assertEqual(datetime.datetime.now(tz), t) self.assertEqual(t.hour, 19)
def test_weekends_only_offhour_support(self): # start day is a sunday, weekend only means we only stop # on friday evening. start_day = 14 t = datetime.datetime(year=2016, day=start_day, month=8, hour=7, minute=20) i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OnHour({"weekends-only": True}) results = [] with mock_datetime_now(t, datetime) as dt: for n in range(7): dt.target = t.replace(day=start_day + n) results.append(f(i)) self.assertEqual(results, [False, True, False, False, False, False, False])
def test_current_time_test(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2015, month=12, day=1, hour=19, minute=5) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OffHour({}) p = f.get_tag_value(i) self.assertEqual(p, "tz=est") tz = f.get_tz("est") self.assertTrue( 'America/New_York' in str(tz) or 'US/Eastern' in str(tz)) self.assertEqual(datetime.datetime.now(tz), t) self.assertEqual(t.hour, 19)
def test_opt_in_behavior(self): # Given the addition of opt out behavior, verify if its # not configured that we don't touch an instance that # has no downtime tag i = instance(Tags=[]) i2 = instance(Tags=[{"Key": "maid_offhours", "Value": ""}]) i3 = instance(Tags=[{"Key": "maid_offhours", "Value": "on"}]) t = datetime.datetime( year=2015, month=12, day=1, hour=19, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) f = OffHour({}) with mock_datetime_now(t, datetime): self.assertEqual(f(i), False) self.assertEqual(f(i2), True) self.assertEqual(f(i3), True) t = datetime.datetime( year=2015, month=12, day=1, hour=7, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) f = OnHour({}) with mock_datetime_now(t, datetime): self.assertEqual(f(i), False) self.assertEqual(f(i2), True) self.assertEqual(f(i3), True)
def test_raise_service_limit_percent(self): magic_string = "Programmatic test--PLEASE IGNORE {account} {service} in {region}" session_factory = self.replay_flight_data( "test_account_raise_service_limit_percent" ) p = self.load_policy( { "name": "raise-service-limit-policy", "resource": "account", "filters": [ { "type": "service-limit", "services": ["VPC", "RDS"], "limits": ["VPCs", "DB parameter groups"], "threshold": 0, } ], "actions": [ { "type": "request-limit-increase", "percent-increase": 10, "subject": magic_string, } ], }, session_factory=session_factory, ) # use this to prevent attempts at refreshing check with mock_datetime_now(parser.parse("2017-02-23T00:40:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 1) # Validate that a case was created support = session_factory().client("support") cases = support.describe_cases() found = [] for case in cases["cases"]: if case["subject"].startswith("Programmatic test--PLEASE IGNORE"): self.assertTrue( "VPC" in case["subject"] or "RDS" in case["subject"] and "644160558196" in case["subject"] ) found.append(case) self.assertEqual(len(found), 2) self.assertTrue(found)
def test_custom_bad_tz(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=7, minute=00) with mock_datetime_now(t, datetime): i = instance(Tags=[{ "Key": "maid_offhours", "Value": "off=(m-f,19);on=(m-f,7);tz=et" }]) self.assertEqual(OnHour({})(i), True) i = instance(Tags=[{ "Key": "maid_offhours", "Value": "off=(m-f,20);on=(m-f,7);tz=abc" }]) self.assertEqual(OnHour({})(i), False)
def test_service_limit_no_threshold(self): # only warns when the default threshold goes to warning or above session_factory = self.replay_flight_data("test_account_service_limit") p = self.load_policy( { "name": "service-limit", "resource": "account", "filters": [{"type": "service-limit"}], }, session_factory=session_factory, ) # use this to prevent attempts at refreshing check with mock_datetime_now(parser.parse("2017-02-23T00:40:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 0)
def test_custom_bad_tz(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=7, minute=00) with mock_datetime_now(t, datetime): i = instance( Tags=[ {"Key": "maid_offhours", "Value": "off=(m-f,19);on=(m-f,7);tz=et"} ] ) self.assertEqual(OnHour({})(i), True) i = instance( Tags=[ {"Key": "maid_offhours", "Value": "off=(m-f,20);on=(m-f,7);tz=abc"} ] ) self.assertEqual(OnHour({})(i), False)
def test_onhour_skip(self): t = datetime.datetime( year=2015, month=12, day=1, hour=7, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) self.assertEqual(OnHour({})(i), True) self.assertEqual(OnHour({"onhour": 8})(i), False) self.assertEqual(OnHour({"skip-days": ["2015-12-01"]})(i), False) self.assertEqual( OnHour({"skip-days": ["2017-01-01", "2015-12-01"]})(i), False) self.assertEqual(OnHour({"skip-days": ["2015-12-02"]})(i), True)
def test_custom_onhours(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=7, minute=00) results = [] with mock_datetime_now(t, datetime): for i in [ instance(Tags=[{ "Key": "maid_offhours", "Value": "off=(m-f,19);on=(m-f,7);tz=et", }]), instance(Tags=[{ "Key": "maid_offhours", "Value": "off=(m-f,20);on=(m-f,9);tz=et", }]), ]: results.append(OnHour({})(i)) self.assertEqual(results, [True, False])
def test_onhour_skip(self): t = datetime.datetime( year=2015, month=12, day=1, hour=7, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) self.assertEqual(OnHour({})(i), True) self.assertEqual(OnHour({"onhour": 8})(i), False) self.assertEqual(OnHour({"skip-days": ["2015-12-01"]})(i), False) self.assertEqual( OnHour({"skip-days": ["2017-01-01", "2015-12-01"]})(i), False ) self.assertEqual(OnHour({"skip-days": ["2015-12-02"]})(i), True)
def test_rdscluster_snapshot_count_filter(self): factory = self.replay_flight_data( "test_rdscluster_snapshot_count_filter") p = self.load_policy( { "name": "rdscluster-snapshot-count-filter", "resource": "rds-cluster", "filters": [{ "type": "consecutive-snapshots", "days": 2 }], }, session_factory=factory, ) with mock_datetime_now(parser.parse("2022-03-30T00:00:00+00:00"), c7n.resources.rdscluster): resources = p.run() self.assertEqual(len(resources), 1)
def test_offhours_real_world_values(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2015, month=12, day=1, hour=19, minute=5) with mock_datetime_now(t, datetime): results = [ OffHour({})(i) for i in [ instance(Tags=[{"Key": "maid_offhours", "Value": ""}]), instance(Tags=[{"Key": "maid_offhours", "Value": "on"}]), instance( Tags=[{"Key": "maid_offhours", "Value": '"Offhours tz=ET"'}] ), instance( Tags=[{"Key": "maid_offhours", "Value": "Offhours tz=PT"}] ), ] ] # unclear what this is really checking self.assertEqual(results, [True, True, True, True])
def xtest_time_match_stops_after_skew(self): hour = 7 t = datetime.datetime( year=2015, month=12, day=1, hour=hour, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) i = instance(Tags=[{"Key": "maid_offhours", "Value": "tz=est"}]) f = OnHour({"skew": 1}) results = [] with mock_datetime_now(t, datetime) as dt: for n in range(0, 4): dt.target = t.replace(hour=hour + n) results.append(f(i)) self.assertEqual(results, [True, True, False, False])
def test_offhours_records(self): session_factory = self.replay_flight_data("test_offhours_records") t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=8, day=14, hour=19, minute=00) with mock_datetime_now(t, datetime): p = self.load_policy( { "name": "offhours-records", "resource": "ec2", "filters": [ { "State.Name": "running" }, { "type": "offhour", "offhour": 19, "tag": "custodian_downtime", "default_tz": "est", "weekends": False, }, ], }, output_dir=None, session_factory=session_factory, ) resources = p.run() self.assertEqual(resources, []) with open( os.path.join(p.options["output_dir"], "offhours-records", "parse_errors.json")) as fh: data = json.load(fh) self.assertEqual(len(data), 1) self.assertEqual(data[0][0], "i-0ee3a9bc2eeed269f") self.assertEqual(data[0][1], "off=[m-f,8];on=[n-f,5];pz=est") with open( os.path.join(p.options["output_dir"], "offhours-records", "opted_out.json")) as fh: data = json.load(fh) self.assertEqual(len(data), 1) self.assertEqual(data[0]["InstanceId"], "i-0a619b58a7e704a9f")
def test_connection_status_filter(self): session_factory = self.replay_flight_data("test_workspaces_connection_status") p = self.load_policy( { "name": "workspaces-connection-status", "resource": "workspaces", "filters": [{ "type": "connection-status", "value_type": "age", "key": "LastKnownUserConnectionTimestamp", "op": "ge", "value": 30 }] }, session_factory=session_factory ) with mock_datetime_now(parser.parse("2019-04-13T00:00:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 1) self.assertIn('LastKnownUserConnectionTimestamp', annotation(resources[0], filters.ANNOTATION_KEY))
def test_upload(self): with mock_datetime_now(date_parse('2018/09/01 13:00'), datetime): output = self.get_s3_output() self.assertEqual(output.key_prefix, "/policies/xyz/2018/09/01/13") with open(os.path.join(output.root_dir, "foo.txt"), "w") as fh: fh.write("abc") output.transfer = mock.MagicMock() output.transfer.upload_file = m = mock.MagicMock() output.upload() m.assert_called_with( fh.name, "cloud-custodian", "%s/foo.txt" % output.key_prefix.lstrip('/'), extra_args={"ACL": "bucket-owner-full-control", "ServerSideEncryption": "AES256"}, )
def test_raise_service_limit(self): magic_string = "Programmatic test" session_factory = self.replay_flight_data( "test_account_raise_service_limit") p = self.load_policy( { "name": "raise-service-limit-policy", "resource": "account", "filters": [{ "type": "service-limit", "services": ["EBS"], "threshold": 0.01 }], "actions": [{ "type": "request-limit-increase", "percent-increase": 50, "subject": magic_string, }], }, session_factory=session_factory, ) # use this to prevent attempts at refreshing check with mock_datetime_now(parser.parse("2017-02-23T00:40:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 1) # Validate that a case was created support = session_factory().client("support") cases = support.describe_cases() found = False for case in cases["cases"]: if case["subject"] == magic_string: found = True break self.assertTrue(found)
def test_service_limit_specific_check(self): session_factory = self.replay_flight_data("test_account_service_limit") p = self.load_policy( { "name": "service-limit", "resource": "account", "filters": [{ "type": "service-limit", "names": ["RDS DB Instances"], "threshold": 1.0, }], }, session_factory=session_factory, ) # use this to prevent attempts at refreshing check with mock_datetime_now(parser.parse("2017-02-23T00:40:00+00:00"), datetime): resources = p.run() self.assertEqual(len(resources), 1) self.assertEqual( set([ l["service"] for l in resources[0]["c7n:ServiceLimitsExceeded"] ]), set(["RDS"]), ) self.assertEqual( set([ l["region"] for l in resources[0]["c7n:ServiceLimitsExceeded"] ]), set(["us-east-1"]), ) self.assertEqual( set([ l["check"] for l in resources[0]["c7n:ServiceLimitsExceeded"] ]), set(["DB instances"]), ) self.assertEqual(len(resources[0]["c7n:ServiceLimitsExceeded"]), 1)
def test_offhours_records(self): session_factory = self.replay_flight_data("test_offhours_records") t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=8, day=14, hour=19, minute=00) with mock_datetime_now(t, datetime): p = self.load_policy( { "name": "offhours-records", "resource": "ec2", "filters": [ {"State.Name": "running"}, { "type": "offhour", "offhour": 19, "tag": "custodian_downtime", "default_tz": "est", "weekends": False, }, ], }, session_factory=session_factory, ) resources = p.run() self.assertEqual(resources, []) with open( os.path.join( p.options["output_dir"], "offhours-records", "parse_errors.json" ) ) as fh: data = json.load(fh) self.assertEqual(len(data), 1) self.assertEqual(data[0][0], "i-0ee3a9bc2eeed269f") self.assertEqual(data[0][1], "off=[m-f,8];on=[n-f,5];pz=est") with open( os.path.join(p.options["output_dir"], "offhours-records", "opted_out.json") ) as fh: data = json.load(fh) self.assertEqual(len(data), 1) self.assertEqual(data[0]["InstanceId"], "i-0a619b58a7e704a9f")
def test_opt_out_behavior(self): # Some users want to match based on policy filters to # a resource subset with default opt out behavior t = datetime.datetime( year=2015, month=12, day=1, hour=19, minute=5, tzinfo=tzutil.gettz("America/New_York"), ) f = OffHour({"opt-out": True}) with mock_datetime_now(t, datetime): i = instance(Tags=[]) self.assertEqual(f(i), True) i = instance(Tags=[{"Key": "maid_offhours", "Value": ""}]) self.assertEqual(f(i), True) i = instance(Tags=[{"Key": "maid_offhours", "Value": "on"}]) self.assertEqual(f(i), True) i = instance(Tags=[{"Key": "maid_offhours", "Value": "off"}]) self.assertEqual(f(i), False) self.assertEqual(f.opted_out, [i])
def test_on_tag(self): t = datetime.datetime.now(tzutil.gettz("America/New_York")) t = t.replace(year=2016, month=5, day=26, hour=7, minute=00) with mock_datetime_now(t, datetime): i = instance(Tags=[{"Key": "maid_offhours", "Value": "on"}]) self.assertEqual(OnHour({})(i), True)