Skip to content

Commit cfab07e

Browse files
Merge pull request #1125 from allmightyspiff/issues1100
Issues1100 - Event Log Improvements
2 parents 46a2b11 + 018400e commit cfab07e

File tree

12 files changed

+195
-499
lines changed

12 files changed

+195
-499
lines changed

SoftLayer/API.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
:license: MIT, see LICENSE for more details.
77
"""
88
# pylint: disable=invalid-name
9+
from __future__ import generators
910
import warnings
1011

12+
1113
from SoftLayer import auth as slauth
1214
from SoftLayer import config
1315
from SoftLayer import consts

SoftLayer/CLI/call_api.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,19 @@ def cli(env, service, method, parameters, _id, _filters, mask, limit, offset,
8787
output_python=False):
8888
"""Call arbitrary API endpoints with the given SERVICE and METHOD.
8989
90-
\b
91-
Examples:
92-
slcli call-api Account getObject
93-
slcli call-api Account getVirtualGuests --limit=10 --mask=id,hostname
94-
slcli call-api Virtual_Guest getObject --id=12345
95-
slcli call-api Metric_Tracking_Object getBandwidthData --id=1234 \\
96-
"2015-01-01 00:00:00" "2015-01-1 12:00:00" public
97-
slcli call-api Account getVirtualGuests \\
98-
-f 'virtualGuests.datacenter.name=dal05' \\
99-
-f 'virtualGuests.maxCpu=4' \\
100-
--mask=id,hostname,datacenter.name,maxCpu
101-
slcli call-api Account getVirtualGuests \\
102-
-f 'virtualGuests.datacenter.name IN dal05,sng01'
90+
Example::
91+
92+
slcli call-api Account getObject
93+
slcli call-api Account getVirtualGuests --limit=10 --mask=id,hostname
94+
slcli call-api Virtual_Guest getObject --id=12345
95+
slcli call-api Metric_Tracking_Object getBandwidthData --id=1234 \\
96+
"2015-01-01 00:00:00" "2015-01-1 12:00:00" public
97+
slcli call-api Account getVirtualGuests \\
98+
-f 'virtualGuests.datacenter.name=dal05' \\
99+
-f 'virtualGuests.maxCpu=4' \\
100+
--mask=id,hostname,datacenter.name,maxCpu
101+
slcli call-api Account getVirtualGuests \\
102+
-f 'virtualGuests.datacenter.name IN dal05,sng01'
103103
"""
104104

105105
args = [service, method] + list(parameters)

SoftLayer/CLI/event_log/get.py

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
"""Get Event Logs."""
22
# :license: MIT, see LICENSE for more details.
33

4-
import json
5-
64
import click
75

86
import SoftLayer
97
from SoftLayer.CLI import environment
10-
from SoftLayer.CLI import formatting
11-
12-
COLUMNS = ['event', 'object', 'type', 'date', 'username']
8+
from SoftLayer import utils
139

1410

1511
@click.command()
@@ -23,44 +19,65 @@
2319
help="The id of the object we want to get event logs for")
2420
@click.option('--obj-type', '-t',
2521
help="The type of the object we want to get event logs for")
26-
@click.option('--utc-offset', '-z',
27-
help="UTC Offset for searching with dates. The default is -0000")
28-
@click.option('--metadata/--no-metadata', default=False,
22+
@click.option('--utc-offset', '-z', default='-0000', show_default=True,
23+
help="UTC Offset for searching with dates. +/-HHMM format")
24+
@click.option('--metadata/--no-metadata', default=False, show_default=True,
2925
help="Display metadata if present")
26+
@click.option('--limit', '-l', type=click.INT, default=50, show_default=True,
27+
help="Total number of result to return. -1 to return ALL, there may be a LOT of these.")
3028
@environment.pass_env
31-
def cli(env, date_min, date_max, obj_event, obj_id, obj_type, utc_offset, metadata):
32-
"""Get Event Logs"""
33-
mgr = SoftLayer.EventLogManager(env.client)
34-
usrmgr = SoftLayer.UserManager(env.client)
35-
request_filter = mgr.build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset)
36-
logs = mgr.get_event_logs(request_filter)
29+
def cli(env, date_min, date_max, obj_event, obj_id, obj_type, utc_offset, metadata, limit):
30+
"""Get Event Logs
3731
38-
if logs is None:
39-
env.fout('None available.')
40-
return
32+
Example:
33+
slcli event-log get -d 01/01/2019 -D 02/01/2019 -t User -l 10
34+
"""
35+
columns = ['Event', 'Object', 'Type', 'Date', 'Username']
4136

42-
if metadata and 'metadata' not in COLUMNS:
43-
COLUMNS.append('metadata')
37+
event_mgr = SoftLayer.EventLogManager(env.client)
38+
user_mgr = SoftLayer.UserManager(env.client)
39+
request_filter = event_mgr.build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset)
40+
logs = event_mgr.get_event_logs(request_filter)
41+
log_time = "%Y-%m-%dT%H:%M:%S.%f%z"
42+
user_data = {}
4443

45-
table = formatting.Table(COLUMNS)
4644
if metadata:
47-
table.align['metadata'] = "l"
45+
columns.append('Metadata')
4846

47+
row_count = 0
48+
click.secho(", ".join(columns))
4949
for log in logs:
50+
if log is None:
51+
click.secho('No logs available for filter %s.' % request_filter, fg='red')
52+
return
53+
5054
user = log['userType']
55+
label = log.get('label', '')
5156
if user == "CUSTOMER":
52-
user = usrmgr.get_user(log['userId'], "mask[username]")['username']
57+
username = user_data.get(log['userId'])
58+
if username is None:
59+
username = user_mgr.get_user(log['userId'], "mask[username]")['username']
60+
user_data[log['userId']] = username
61+
user = username
62+
5363
if metadata:
54-
try:
55-
metadata_data = json.dumps(json.loads(log['metaData']), indent=4, sort_keys=True)
56-
if env.format == "table":
57-
metadata_data = metadata_data.strip("{}\n\t")
58-
except ValueError:
59-
metadata_data = log['metaData']
64+
metadata_data = log['metaData'].strip("\n\t")
6065

61-
table.add_row([log['eventName'], log['label'], log['objectName'],
62-
log['eventCreateDate'], user, metadata_data])
66+
click.secho("'{0}','{1}','{2}','{3}','{4}','{5}'".format(
67+
log['eventName'],
68+
label,
69+
log['objectName'],
70+
utils.clean_time(log['eventCreateDate'], in_format=log_time),
71+
user,
72+
metadata_data))
6373
else:
64-
table.add_row([log['eventName'], log['label'], log['objectName'],
65-
log['eventCreateDate'], user])
66-
env.fout(table)
74+
click.secho("'{0}','{1}','{2}','{3}','{4}'".format(
75+
log['eventName'],
76+
label,
77+
log['objectName'],
78+
utils.clean_time(log['eventCreateDate'], in_format=log_time),
79+
user))
80+
81+
row_count = row_count + 1
82+
if row_count >= limit and limit != -1:
83+
return

SoftLayer/managers/event_log.py

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
SoftLayer.event_log
3-
~~~~~~~~~~~~~~~~~
3+
~~~~~~~~~~~~~~~~~~~
44
Network Manager/helpers
55
66
:license: MIT, see LICENSE for more details.
@@ -17,16 +17,31 @@ class EventLogManager(object):
1717
"""
1818

1919
def __init__(self, client):
20+
self.client = client
2021
self.event_log = client['Event_Log']
2122

22-
def get_event_logs(self, request_filter):
23+
def get_event_logs(self, request_filter=None, log_limit=20, iterator=True):
2324
"""Returns a list of event logs
2425
26+
Example::
27+
28+
event_mgr = SoftLayer.EventLogManager(env.client)
29+
request_filter = event_mgr.build_filter(date_min="01/01/2019", date_max="02/01/2019")
30+
logs = event_mgr.get_event_logs(request_filter)
31+
for log in logs:
32+
print("Event Name: {}".format(log['eventName']))
33+
34+
2535
:param dict request_filter: filter dict
26-
:returns: List of event logs
36+
:param int log_limit: number of results to get in one API call
37+
:param bool iterator: False will only make one API call for log_limit results.
38+
True will keep making API calls until all logs have been retreived. There may be a lot of these.
39+
:returns: List of event logs. If iterator=True, will return a python generator object instead.
2740
"""
28-
results = self.event_log.getAllObjects(filter=request_filter)
29-
return results
41+
if iterator:
42+
# Call iter_call directly as this returns the actual generator
43+
return self.client.iter_call('Event_Log', 'getAllObjects', filter=request_filter, limit=log_limit)
44+
return self.client.call('Event_Log', 'getAllObjects', filter=request_filter, limit=log_limit)
3045

3146
def get_event_log_types(self):
3247
"""Returns a list of event log types
@@ -36,30 +51,8 @@ def get_event_log_types(self):
3651
results = self.event_log.getAllEventObjectNames()
3752
return results
3853

39-
def get_event_logs_by_type(self, event_type):
40-
"""Returns a list of event logs, filtered on the 'objectName' field
41-
42-
:param string event_type: The event type we want to filter on
43-
:returns: List of event logs, filtered on the 'objectName' field
44-
"""
45-
request_filter = {}
46-
request_filter['objectName'] = {'operation': event_type}
47-
48-
return self.event_log.getAllObjects(filter=request_filter)
49-
50-
def get_event_logs_by_event_name(self, event_name):
51-
"""Returns a list of event logs, filtered on the 'eventName' field
52-
53-
:param string event_type: The event type we want to filter on
54-
:returns: List of event logs, filtered on the 'eventName' field
55-
"""
56-
request_filter = {}
57-
request_filter['eventName'] = {'operation': event_name}
58-
59-
return self.event_log.getAllObjects(filter=request_filter)
60-
6154
@staticmethod
62-
def build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset):
55+
def build_filter(date_min=None, date_max=None, obj_event=None, obj_id=None, obj_type=None, utc_offset=None):
6356
"""Returns a query filter that can be passed into EventLogManager.get_event_logs
6457
6558
:param string date_min: Lower bound date in MM/DD/YYYY format
@@ -73,24 +66,18 @@ def build_filter(date_min, date_max, obj_event, obj_id, obj_type, utc_offset):
7366
:returns: dict: The generated query filter
7467
"""
7568

76-
if not date_min and not date_max and not obj_event and not obj_id and not obj_type:
77-
return None
69+
if not any([date_min, date_max, obj_event, obj_id, obj_type]):
70+
return {}
7871

7972
request_filter = {}
8073

8174
if date_min and date_max:
8275
request_filter['eventCreateDate'] = utils.event_log_filter_between_date(date_min, date_max, utc_offset)
8376
else:
8477
if date_min:
85-
request_filter['eventCreateDate'] = utils.event_log_filter_greater_than_date(
86-
date_min,
87-
utc_offset
88-
)
78+
request_filter['eventCreateDate'] = utils.event_log_filter_greater_than_date(date_min, utc_offset)
8979
elif date_max:
90-
request_filter['eventCreateDate'] = utils.event_log_filter_less_than_date(
91-
date_max,
92-
utc_offset
93-
)
80+
request_filter['eventCreateDate'] = utils.event_log_filter_less_than_date(date_max, utc_offset)
9481

9582
if obj_event:
9683
request_filter['eventName'] = {'operation': obj_event}

SoftLayer/managers/network.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,14 +575,16 @@ def _get_cci_event_logs(self):
575575
event_log_mgr = event_log.EventLogManager(self.client)
576576

577577
# Get CCI Event Logs
578-
return event_log_mgr.get_event_logs_by_type('CCI')
578+
_filter = event_log_mgr.build_filter(obj_type='CCI')
579+
return event_log_mgr.get_event_logs(request_filter=_filter)
579580

580581
def _get_security_group_event_logs(self):
581582
# Load the event log manager
582583
event_log_mgr = event_log.EventLogManager(self.client)
583584

584585
# Get CCI Event Logs
585-
return event_log_mgr.get_event_logs_by_type('Security Group')
586+
_filter = event_log_mgr.build_filter(obj_type='Security Group')
587+
return event_log_mgr.get_event_logs(request_filter=_filter)
586588

587589
def resolve_global_ip_ids(self, identifier):
588590
"""Resolve global ip ids."""

docs/api/managers/event_log.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. _event_log:
2+
3+
.. automodule:: SoftLayer.managers.event_log
4+
:members:
5+
:inherited-members:

docs/cli.rst

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,9 @@ functionality not fully documented here.
1111

1212
.. toctree::
1313
:maxdepth: 2
14+
:glob:
1415

15-
cli/account
16-
cli/vs
17-
cli/hardware
18-
cli/ordering
19-
cli/users
20-
cli/ipsec
16+
cli/*
2117

2218
.. _config_setup:
2319

@@ -179,3 +175,4 @@ Most commands will take in additional options/arguments. To see all available ac
179175
--tags TEXT Show instances that have one of these comma-
180176
separated tags
181177
--help Show this message and exit.
178+

docs/cli/call_api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. _cli_call_api:
2+
3+
Call API
4+
========
5+
6+
7+
.. click:: SoftLayer.CLI.call_api:cli
8+
:prog: call-api
9+
:show-nested:

docs/cli/event_log.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.. _cli_event_log:
2+
3+
Event-Log Commands
4+
====================
5+
6+
7+
.. click:: SoftLayer.CLI.event_log.get:cli
8+
:prog: event-log get
9+
:show-nested:
10+
11+
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.
12+
13+
.. click:: SoftLayer.CLI.event_log.types:cli
14+
:prog: event-log types
15+
:show-nested:
16+
17+
18+
Currently the types are as follows, more may be added in the future.
19+
::
20+
21+
:......................:
22+
: types :
23+
:......................:
24+
: Account :
25+
: CDN :
26+
: User :
27+
: Bare Metal Instance :
28+
: API Authentication :
29+
: Server :
30+
: CCI :
31+
: Image :
32+
: Bluemix LB :
33+
: Facility :
34+
: Cloud Object Storage :
35+
: Security Group :
36+
:......................:

0 commit comments

Comments
 (0)