diff --git a/SoftLayer/API.py b/SoftLayer/API.py index c5fd95f3a..e65da3884 100644 --- a/SoftLayer/API.py +++ b/SoftLayer/API.py @@ -6,8 +6,10 @@ :license: MIT, see LICENSE for more details. """ # pylint: disable=invalid-name +from __future__ import generators import warnings + from SoftLayer import auth as slauth from SoftLayer import config from SoftLayer import consts diff --git a/SoftLayer/CLI/call_api.py b/SoftLayer/CLI/call_api.py index 0adb4fa31..6e16a2a77 100644 --- a/SoftLayer/CLI/call_api.py +++ b/SoftLayer/CLI/call_api.py @@ -87,19 +87,19 @@ def cli(env, service, method, parameters, _id, _filters, mask, limit, offset, output_python=False): """Call arbitrary API endpoints with the given SERVICE and METHOD. - \b - Examples: - slcli call-api Account getObject - slcli call-api Account getVirtualGuests --limit=10 --mask=id,hostname - slcli call-api Virtual_Guest getObject --id=12345 - slcli call-api Metric_Tracking_Object getBandwidthData --id=1234 \\ - "2015-01-01 00:00:00" "2015-01-1 12:00:00" public - slcli call-api Account getVirtualGuests \\ - -f 'virtualGuests.datacenter.name=dal05' \\ - -f 'virtualGuests.maxCpu=4' \\ - --mask=id,hostname,datacenter.name,maxCpu - slcli call-api Account getVirtualGuests \\ - -f 'virtualGuests.datacenter.name IN dal05,sng01' + Example:: + + slcli call-api Account getObject + slcli call-api Account getVirtualGuests --limit=10 --mask=id,hostname + slcli call-api Virtual_Guest getObject --id=12345 + slcli call-api Metric_Tracking_Object getBandwidthData --id=1234 \\ + "2015-01-01 00:00:00" "2015-01-1 12:00:00" public + slcli call-api Account getVirtualGuests \\ + -f 'virtualGuests.datacenter.name=dal05' \\ + -f 'virtualGuests.maxCpu=4' \\ + --mask=id,hostname,datacenter.name,maxCpu + slcli call-api Account getVirtualGuests \\ + -f 'virtualGuests.datacenter.name IN dal05,sng01' """ args = [service, method] + list(parameters) diff --git a/SoftLayer/CLI/event_log/get.py b/SoftLayer/CLI/event_log/get.py index b505a4502..3880086f2 100644 --- a/SoftLayer/CLI/event_log/get.py +++ b/SoftLayer/CLI/event_log/get.py @@ -1,15 +1,11 @@ """Get Event Logs.""" # :license: MIT, see LICENSE for more details. -import json - import click import SoftLayer from SoftLayer.CLI import environment -from SoftLayer.CLI import formatting - -COLUMNS = ['event', 'object', 'type', 'date', 'username'] +from SoftLayer import utils @click.command() @@ -23,44 +19,65 @@ help="The id of the object we want to get event logs for") @click.option('--obj-type', '-t', help="The type of the object we want to get event logs for") -@click.option('--utc-offset', '-z', - help="UTC Offset for searching with dates. The default is -0000") -@click.option('--metadata/--no-metadata', default=False, +@click.option('--utc-offset', '-z', default='-0000', show_default=True, + help="UTC Offset for searching with dates. +/-HHMM format") +@click.option('--metadata/--no-metadata', default=False, show_default=True, help="Display metadata if present") +@click.option('--limit', '-l', type=click.INT, default=50, show_default=True, + help="Total number of result to return. -1 to return ALL, there may be a LOT of these.") @environment.pass_env -def cli(env, date_min, date_max, obj_event, obj_id, obj_type, utc_offset, metadata): - """Get Event Logs""" - mgr = SoftLayer.EventLogManager(env.client) - usrmgr = SoftLayer.UserManager(env.client) - request_filter = mgr.build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset) - logs = mgr.get_event_logs(request_filter) +def cli(env, date_min, date_max, obj_event, obj_id, obj_type, utc_offset, metadata, limit): + """Get Event Logs - if logs is None: - env.fout('None available.') - return + Example: + slcli event-log get -d 01/01/2019 -D 02/01/2019 -t User -l 10 + """ + columns = ['Event', 'Object', 'Type', 'Date', 'Username'] - if metadata and 'metadata' not in COLUMNS: - COLUMNS.append('metadata') + event_mgr = SoftLayer.EventLogManager(env.client) + user_mgr = SoftLayer.UserManager(env.client) + request_filter = event_mgr.build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset) + logs = event_mgr.get_event_logs(request_filter) + log_time = "%Y-%m-%dT%H:%M:%S.%f%z" + user_data = {} - table = formatting.Table(COLUMNS) if metadata: - table.align['metadata'] = "l" + columns.append('Metadata') + row_count = 0 + click.secho(", ".join(columns)) for log in logs: + if log is None: + click.secho('No logs available for filter %s.' % request_filter, fg='red') + return + user = log['userType'] + label = log.get('label', '') if user == "CUSTOMER": - user = usrmgr.get_user(log['userId'], "mask[username]")['username'] + username = user_data.get(log['userId']) + if username is None: + username = user_mgr.get_user(log['userId'], "mask[username]")['username'] + user_data[log['userId']] = username + user = username + if metadata: - try: - metadata_data = json.dumps(json.loads(log['metaData']), indent=4, sort_keys=True) - if env.format == "table": - metadata_data = metadata_data.strip("{}\n\t") - except ValueError: - metadata_data = log['metaData'] + metadata_data = log['metaData'].strip("\n\t") - table.add_row([log['eventName'], log['label'], log['objectName'], - log['eventCreateDate'], user, metadata_data]) + click.secho("'{0}','{1}','{2}','{3}','{4}','{5}'".format( + log['eventName'], + label, + log['objectName'], + utils.clean_time(log['eventCreateDate'], in_format=log_time), + user, + metadata_data)) else: - table.add_row([log['eventName'], log['label'], log['objectName'], - log['eventCreateDate'], user]) - env.fout(table) + click.secho("'{0}','{1}','{2}','{3}','{4}'".format( + log['eventName'], + label, + log['objectName'], + utils.clean_time(log['eventCreateDate'], in_format=log_time), + user)) + + row_count = row_count + 1 + if row_count >= limit and limit != -1: + return diff --git a/SoftLayer/managers/event_log.py b/SoftLayer/managers/event_log.py index 4e37e6d67..cc0a7f5cd 100644 --- a/SoftLayer/managers/event_log.py +++ b/SoftLayer/managers/event_log.py @@ -1,6 +1,6 @@ """ SoftLayer.event_log - ~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~ Network Manager/helpers :license: MIT, see LICENSE for more details. @@ -17,16 +17,31 @@ class EventLogManager(object): """ def __init__(self, client): + self.client = client self.event_log = client['Event_Log'] - def get_event_logs(self, request_filter): + def get_event_logs(self, request_filter=None, log_limit=20, iterator=True): """Returns a list of event logs + Example:: + + event_mgr = SoftLayer.EventLogManager(env.client) + request_filter = event_mgr.build_filter(date_min="01/01/2019", date_max="02/01/2019") + logs = event_mgr.get_event_logs(request_filter) + for log in logs: + print("Event Name: {}".format(log['eventName'])) + + :param dict request_filter: filter dict - :returns: List of event logs + :param int log_limit: number of results to get in one API call + :param bool iterator: False will only make one API call for log_limit results. + True will keep making API calls until all logs have been retreived. There may be a lot of these. + :returns: List of event logs. If iterator=True, will return a python generator object instead. """ - results = self.event_log.getAllObjects(filter=request_filter) - return results + if iterator: + # Call iter_call directly as this returns the actual generator + return self.client.iter_call('Event_Log', 'getAllObjects', filter=request_filter, limit=log_limit) + return self.client.call('Event_Log', 'getAllObjects', filter=request_filter, limit=log_limit) def get_event_log_types(self): """Returns a list of event log types @@ -36,30 +51,8 @@ def get_event_log_types(self): results = self.event_log.getAllEventObjectNames() return results - def get_event_logs_by_type(self, event_type): - """Returns a list of event logs, filtered on the 'objectName' field - - :param string event_type: The event type we want to filter on - :returns: List of event logs, filtered on the 'objectName' field - """ - request_filter = {} - request_filter['objectName'] = {'operation': event_type} - - return self.event_log.getAllObjects(filter=request_filter) - - def get_event_logs_by_event_name(self, event_name): - """Returns a list of event logs, filtered on the 'eventName' field - - :param string event_type: The event type we want to filter on - :returns: List of event logs, filtered on the 'eventName' field - """ - request_filter = {} - request_filter['eventName'] = {'operation': event_name} - - return self.event_log.getAllObjects(filter=request_filter) - @staticmethod - def build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset): + def build_filter(date_min=None, date_max=None, obj_event=None, obj_id=None, obj_type=None, utc_offset=None): """Returns a query filter that can be passed into EventLogManager.get_event_logs :param string date_min: Lower bound date in MM/DD/YYYY format @@ -73,8 +66,8 @@ def build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset): :returns: dict: The generated query filter """ - if not date_min and not date_max and not obj_event and not obj_id and not obj_type: - return None + if not any([date_min, date_max, obj_event, obj_id, obj_type]): + return {} request_filter = {} @@ -82,15 +75,9 @@ def build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset): request_filter['eventCreateDate'] = utils.event_log_filter_between_date(date_min, date_max, utc_offset) else: if date_min: - request_filter['eventCreateDate'] = utils.event_log_filter_greater_than_date( - date_min, - utc_offset - ) + request_filter['eventCreateDate'] = utils.event_log_filter_greater_than_date(date_min, utc_offset) elif date_max: - request_filter['eventCreateDate'] = utils.event_log_filter_less_than_date( - date_max, - utc_offset - ) + request_filter['eventCreateDate'] = utils.event_log_filter_less_than_date(date_max, utc_offset) if obj_event: request_filter['eventName'] = {'operation': obj_event} diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py index 48edbefa7..ae42ca405 100644 --- a/SoftLayer/managers/network.py +++ b/SoftLayer/managers/network.py @@ -575,14 +575,16 @@ def _get_cci_event_logs(self): event_log_mgr = event_log.EventLogManager(self.client) # Get CCI Event Logs - return event_log_mgr.get_event_logs_by_type('CCI') + _filter = event_log_mgr.build_filter(obj_type='CCI') + return event_log_mgr.get_event_logs(request_filter=_filter) def _get_security_group_event_logs(self): # Load the event log manager event_log_mgr = event_log.EventLogManager(self.client) # Get CCI Event Logs - return event_log_mgr.get_event_logs_by_type('Security Group') + _filter = event_log_mgr.build_filter(obj_type='Security Group') + return event_log_mgr.get_event_logs(request_filter=_filter) def resolve_global_ip_ids(self, identifier): """Resolve global ip ids.""" diff --git a/docs/api/managers/event_log.rst b/docs/api/managers/event_log.rst new file mode 100644 index 000000000..41adfeaa4 --- /dev/null +++ b/docs/api/managers/event_log.rst @@ -0,0 +1,5 @@ +.. _event_log: + +.. automodule:: SoftLayer.managers.event_log + :members: + :inherited-members: diff --git a/docs/cli.rst b/docs/cli.rst index 709741aa1..ebd62741e 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -11,13 +11,9 @@ functionality not fully documented here. .. toctree:: :maxdepth: 2 + :glob: - cli/account - cli/vs - cli/hardware - cli/ordering - cli/users - cli/ipsec + cli/* .. _config_setup: @@ -179,3 +175,4 @@ Most commands will take in additional options/arguments. To see all available ac --tags TEXT Show instances that have one of these comma- separated tags --help Show this message and exit. + diff --git a/docs/cli/call_api.rst b/docs/cli/call_api.rst new file mode 100644 index 000000000..e309f16eb --- /dev/null +++ b/docs/cli/call_api.rst @@ -0,0 +1,9 @@ +.. _cli_call_api: + +Call API +======== + + +.. click:: SoftLayer.CLI.call_api:cli + :prog: call-api + :show-nested: diff --git a/docs/cli/event_log.rst b/docs/cli/event_log.rst new file mode 100644 index 000000000..47c7639e5 --- /dev/null +++ b/docs/cli/event_log.rst @@ -0,0 +1,36 @@ +.. _cli_event_log: + +Event-Log Commands +==================== + + +.. click:: SoftLayer.CLI.event_log.get:cli + :prog: event-log get + :show-nested: + +There are usually quite a few events on an account, so be careful when using the `--limit -1` option. The command will automatically break requests out into smaller sub-requests, but this command may take a very long time to complete. It will however print out data as it comes in. + +.. click:: SoftLayer.CLI.event_log.types:cli + :prog: event-log types + :show-nested: + + +Currently the types are as follows, more may be added in the future. +:: + + :......................: + : types : + :......................: + : Account : + : CDN : + : User : + : Bare Metal Instance : + : API Authentication : + : Server : + : CCI : + : Image : + : Bluemix LB : + : Facility : + : Cloud Object Storage : + : Security Group : + :......................: \ No newline at end of file diff --git a/tests/CLI/modules/event_log_tests.py b/tests/CLI/modules/event_log_tests.py index b36ff8530..d22847317 100644 --- a/tests/CLI/modules/event_log_tests.py +++ b/tests/CLI/modules/event_log_tests.py @@ -6,325 +6,40 @@ import json -from SoftLayer.CLI import formatting from SoftLayer import testing class EventLogTests(testing.TestCase): - def test_get_event_log_with_metadata(self): - expected = [ - { - 'date': '2017-10-23T14:22:36.221541-05:00', - 'event': 'Disable Port', - 'object': 'test.softlayer.com', - 'username': 'SYSTEM', - 'type': 'CCI', - 'metadata': '' - }, - { - 'date': '2017-10-18T09:40:41.830338-05:00', - 'event': 'Security Group Rule Added', - 'object': 'test.softlayer.com', - 'username': 'SL12345-test', - 'type': 'CCI', - 'metadata': json.dumps(json.loads( - '{"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"53d0b91d392864e062f4958",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"100"}],"securityGroupId":"200",' - '"securityGroupName":"test_SG"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T09:40:32.238869-05:00', - 'event': 'Security Group Added', - 'object': 'test.softlayer.com', - 'username': 'SL12345-test', - 'type': 'CCI', - 'metadata': json.dumps(json.loads( - '{"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"96c9b47b9e102d2e1d81fba",' - '"securityGroupId":"200",' - '"securityGroupName":"test_SG"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:42:13.089536-05:00', - 'event': 'Security Group Rule(s) Removed', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"requestId":"2abda7ca97e5a1444cae0b9",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"800"}]}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:42:11.679736-05:00', - 'event': 'Network Component Removed from Security Group', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"fullyQualifiedDomainName":"test.softlayer.com",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"6b9a87a9ab8ac9a22e87a00"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:41:49.802498-05:00', - 'event': 'Security Group Rule(s) Added', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"requestId":"0a293c1c3e59e4471da6495",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"800"}]}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:41:42.176328-05:00', - 'event': 'Network Component Added to Security Group', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"fullyQualifiedDomainName":"test.softlayer.com",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"4709e02ad42c83f80345904"}' - ), - indent=4, - sort_keys=True - ) - } - ] + def test_get_event_log_with_metadata(self): result = self.run_command(['event-log', 'get', '--metadata']) self.assert_no_fail(result) - self.assertEqual(expected, json.loads(result.output)) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') + self.assertIn('Metadata', result.output) def test_get_event_log_without_metadata(self): - expected = [ - { - 'date': '2017-10-23T14:22:36.221541-05:00', - 'event': 'Disable Port', - 'username': 'SYSTEM', - 'type': 'CCI', - 'object': 'test.softlayer.com' - }, - { - 'date': '2017-10-18T09:40:41.830338-05:00', - 'event': 'Security Group Rule Added', - 'username': 'SL12345-test', - 'type': 'CCI', - 'object': 'test.softlayer.com' - }, - { - 'date': '2017-10-18T09:40:32.238869-05:00', - 'event': 'Security Group Added', - 'username': 'SL12345-test', - 'type': 'CCI', - 'object': 'test.softlayer.com' - }, - { - 'date': '2017-10-18T10:42:13.089536-05:00', - 'event': 'Security Group Rule(s) Removed', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'object': 'test_SG' - }, - { - 'date': '2017-10-18T10:42:11.679736-05:00', - 'event': 'Network Component Removed from Security Group', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'object': 'test_SG' - }, - { - 'date': '2017-10-18T10:41:49.802498-05:00', - 'event': 'Security Group Rule(s) Added', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'object': 'test_SG' - }, - { - 'date': '2017-10-18T10:41:42.176328-05:00', - 'event': 'Network Component Added to Security Group', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'object': 'test_SG' - } - ] - - result = self.run_command(['event-log', 'get']) - + result = self.run_command(['event-log', 'get', '--no-metadata']) self.assert_no_fail(result) - self.assertEqual(expected, json.loads(result.output)) - - def test_get_event_table(self): - table_fix = formatting.Table(['event', 'object', 'type', 'date', 'username', 'metadata']) - table_fix.align['metadata'] = "l" - expected = [ - { - 'date': '2017-10-23T14:22:36.221541-05:00', - 'event': 'Disable Port', - 'object': 'test.softlayer.com', - 'username': 'SYSTEM', - 'type': 'CCI', - 'metadata': '' - }, - { - 'date': '2017-10-18T09:40:41.830338-05:00', - 'event': 'Security Group Rule Added', - 'object': 'test.softlayer.com', - 'username': 'SL12345-test', - 'type': 'CCI', - 'metadata': json.dumps(json.loads( - '{"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"53d0b91d392864e062f4958",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"100"}],"securityGroupId":"200",' - '"securityGroupName":"test_SG"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T09:40:32.238869-05:00', - 'event': 'Security Group Added', - 'object': 'test.softlayer.com', - 'username': 'SL12345-test', - 'type': 'CCI', - 'metadata': json.dumps(json.loads( - '{"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"96c9b47b9e102d2e1d81fba",' - '"securityGroupId":"200",' - '"securityGroupName":"test_SG"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:42:13.089536-05:00', - 'event': 'Security Group Rule(s) Removed', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"requestId":"2abda7ca97e5a1444cae0b9",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"800"}]}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:42:11.679736-05:00', - 'event': 'Network Component Removed from Security Group', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"fullyQualifiedDomainName":"test.softlayer.com",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"6b9a87a9ab8ac9a22e87a00"}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:41:49.802498-05:00', - 'event': 'Security Group Rule(s) Added', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"requestId":"0a293c1c3e59e4471da6495",' - '"rules":[{"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMax":2001,"portRangeMin":2000,"protocol":"tcp",' - '"remoteGroupId":null,"remoteIp":null,"ruleId":"800"}]}' - ), - indent=4, - sort_keys=True - ) - }, - { - 'date': '2017-10-18T10:41:42.176328-05:00', - 'event': 'Network Component Added to Security Group', - 'object': 'test_SG', - 'username': 'SL12345-test', - 'type': 'Security Group', - 'metadata': json.dumps(json.loads( - '{"fullyQualifiedDomainName":"test.softlayer.com",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"4709e02ad42c83f80345904"}' - ), - indent=4, - sort_keys=True - ) - } - ] - - for log in expected: - table_fix.add_row([log['event'], log['object'], log['type'], log['date'], - log['username'], log['metadata'].strip("{}\n\t")]) - expected_output = formatting.format_output(table_fix) + '\n' - - result = self.run_command(args=['event-log', 'get', '--metadata'], fmt='table') - - self.assert_no_fail(result) - self.assertEqual(expected_output, result.output) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') + self.assert_called_with('SoftLayer_User_Customer', 'getObject', identifier=400) + self.assertNotIn('Metadata', result.output) def test_get_event_log_empty(self): mock = self.set_mock('SoftLayer_Event_Log', 'getAllObjects') mock.return_value = None result = self.run_command(['event-log', 'get']) + expected = 'Event, Object, Type, Date, Username\n' \ + 'No logs available for filter {}.\n' + self.assert_no_fail(result) + self.assertEqual(expected, result.output) - self.assertEqual(mock.call_count, 1) + def test_get_event_log_over_limit(self): + result = self.run_command(['event-log', 'get', '-l 1']) self.assert_no_fail(result) - self.assertEqual('"None available."\n', result.output) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') + self.assertEqual(2, result.output.count("\n")) def test_get_event_log_types(self): expected = [ @@ -370,3 +85,9 @@ def test_get_event_log_types(self): self.assert_no_fail(result) self.assertEqual(expected, json.loads(result.output)) + + def test_get_unlimited_events(self): + result = self.run_command(['event-log', 'get', '-l -1']) + self.assert_no_fail(result) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') + self.assertEqual(8, result.output.count("\n")) diff --git a/tests/managers/event_log_tests.py b/tests/managers/event_log_tests.py index 9a933e0d8..e5c220835 100644 --- a/tests/managers/event_log_tests.py +++ b/tests/managers/event_log_tests.py @@ -15,74 +15,32 @@ def set_up(self): self.event_log = SoftLayer.EventLogManager(self.client) def test_get_event_logs(self): - result = self.event_log.get_event_logs(None) + # Cast to list to force generator to get all objects + result = list(self.event_log.get_event_logs()) expected = fixtures.SoftLayer_Event_Log.getAllObjects self.assertEqual(expected, result) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') - def test_get_event_log_types(self): - result = self.event_log.get_event_log_types() - - expected = fixtures.SoftLayer_Event_Log.getAllEventObjectNames - self.assertEqual(expected, result) - - def test_get_event_logs_by_type(self): - expected = [ - { - 'accountId': 100, - 'eventCreateDate': '2017-10-23T14:22:36.221541-05:00', - 'eventName': 'Disable Port', - 'ipAddress': '192.168.0.1', - 'label': 'test.softlayer.com', - 'metaData': '', - 'objectId': 300, - 'objectName': 'CCI', - 'traceId': '100', - 'userId': '', - 'userType': 'SYSTEM' - } - ] - - mock = self.set_mock('SoftLayer_Event_Log', 'getAllObjects') - mock.return_value = expected - - result = self.event_log.get_event_logs_by_type('CCI') + def test_get_event_logs_no_iteration(self): + # Cast to list to force generator to get all objects + result = self.event_log.get_event_logs(iterator=False) + expected = fixtures.SoftLayer_Event_Log.getAllObjects self.assertEqual(expected, result) + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects') - def test_get_event_logs_by_event_name(self): - expected = [ - { - 'accountId': 100, - 'eventCreateDate': '2017-10-18T09:40:32.238869-05:00', - 'eventName': 'Security Group Added', - 'ipAddress': '192.168.0.1', - 'label': 'test.softlayer.com', - 'metaData': '{"securityGroupId":"200",' - '"securityGroupName":"test_SG",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"96c9b47b9e102d2e1d81fba"}', - 'objectId': 300, - 'objectName': 'CCI', - 'traceId': '59e767e03a57e', - 'userId': 400, - 'userType': 'CUSTOMER', - 'username': 'user' - } - ] - - mock = self.set_mock('SoftLayer_Event_Log', 'getAllObjects') - mock.return_value = expected - - result = self.event_log.get_event_logs_by_event_name('Security Group Added') + def test_get_event_log_types(self): + result = self.event_log.get_event_log_types() + expected = fixtures.SoftLayer_Event_Log.getAllEventObjectNames self.assertEqual(expected, result) + self.assert_called_with('SoftLayer_Event_Log', 'getAllEventObjectNames') def test_build_filter_no_args(self): result = self.event_log.build_filter(None, None, None, None, None, None) - self.assertEqual(result, None) + self.assertEqual(result, {}) def test_build_filter_min_date(self): expected = { diff --git a/tests/managers/network_tests.py b/tests/managers/network_tests.py index f9f5ed308..bb2823f7c 100644 --- a/tests/managers/network_tests.py +++ b/tests/managers/network_tests.py @@ -5,6 +5,8 @@ :license: MIT, see LICENSE for more details. """ import mock +import sys +import unittest import SoftLayer from SoftLayer import fixtures @@ -609,60 +611,20 @@ def test_get_event_logs_by_request_id(self): self.assertEqual(expected, result) + @unittest.skipIf(sys.version_info < (3, 6), "__next__ doesn't work in python 2") def test_get_security_group_event_logs(self): - expected = [ - { - 'accountId': 100, - 'eventCreateDate': '2017-10-18T10:42:13.089536-05:00', - 'eventName': 'Security Group Rule(s) Removed', - 'ipAddress': '192.168.0.1', - 'label': 'test_SG', - 'metaData': '{"requestId":"96c9b47b9e102d2e1d81fba",' - '"rules":[{"ruleId":"800",' - '"remoteIp":null,"remoteGroupId":null,"direction":"ingress",' - '"ethertype":"IPv4",' - '"portRangeMin":2000,"portRangeMax":2001,"protocol":"tcp"}]}', - 'objectId': 700, - 'objectName': 'Security Group', - 'traceId': '59e7765515e28', - 'userId': 400, - 'userType': 'CUSTOMER', - 'username': 'user' - } - ] - - mock = self.set_mock('SoftLayer_Event_Log', 'getAllObjects') - mock.return_value = expected - result = self.network._get_security_group_event_logs() + # Event log now returns a generator, so you have to get a result for it to make an API call + log = result.__next__() + _filter = {'objectName': {'operation': 'Security Group'}} + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects', filter=_filter) + self.assertEqual(100, log['accountId']) - self.assertEqual(expected, result) - + @unittest.skipIf(sys.version_info < (3, 6), "__next__ doesn't work in python 2") def test_get_cci_event_logs(self): - expected = [ - { - 'accountId': 100, - 'eventCreateDate': '2017-10-18T09:40:32.238869-05:00', - 'eventName': 'Security Group Added', - 'ipAddress': '192.168.0.1', - 'label': 'test.softlayer.com', - 'metaData': '{"securityGroupId":"200",' - '"securityGroupName":"test_SG",' - '"networkComponentId":"100",' - '"networkInterfaceType":"public",' - '"requestId":"96c9b47b9e102d2e1d81fba"}', - 'objectId': 300, - 'objectName': 'CCI', - 'traceId': '59e767e03a57e', - 'userId': 400, - 'userType': 'CUSTOMER', - 'username': 'user' - } - ] - - mock = self.set_mock('SoftLayer_Event_Log', 'getAllObjects') - mock.return_value = expected - result = self.network._get_cci_event_logs() - - self.assertEqual(expected, result) + # Event log now returns a generator, so you have to get a result for it to make an API call + log = result.__next__() + _filter = {'objectName': {'operation': 'CCI'}} + self.assert_called_with('SoftLayer_Event_Log', 'getAllObjects', filter=_filter) + self.assertEqual(100, log['accountId'])