Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues57 - groundwork for monitoring #429

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions SoftLayer/CLI/monitor/__init__.py
@@ -0,0 +1 @@
"""Monitoring"""
82 changes: 82 additions & 0 deletions SoftLayer/CLI/monitor/status.py
@@ -0,0 +1,82 @@
"""
usage: sl monitor [<command>] [<args>...] [options]

Manage Monitoring.

The available commands are:
status Show basic monitoring status of servers
"""

import click

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting
from SoftLayer import utils


@click.command()
@click.option('--only_hardware', is_flag=True,
help="Show only physical servers")
@click.option('--only_virtual', is_flag=True,
help="Show only virtual servers")
@environment.pass_env
def cli(env, only_hardware=False, only_virtual=False):
"""shows SERVER_PING status of all servers."""

table = formatting.Table([
'id', 'datacenter', 'FQDN', 'IP',
'status', 'Type', 'last checked at'
])
hw_manager = SoftLayer.HardwareMonitorManager(env.client)
vs_manager = SoftLayer.VSMonitorManager(env.client)
if only_virtual:
hardware = []
guest = vs_manager.list_status()
elif only_hardware:
hardware = hw_manager.list_status()
guest = []
else:
hardware = hw_manager.list_status()
guest = vs_manager.list_status()

results = hardware + guest
for server_object in results:
server = utils.NestedDict(server_object)
for monitor in server['networkMonitors']:
try:
res = monitor['lastResult']['responseStatus']
date = monitor['lastResult']['finishTime']
ip_address = monitor['ipAddress']
monitor_type = monitor['queryType']['name']
except KeyError:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more explicit, maybe it's better to do this instead:

if 'lastResult' in monitor:
 ...
else:
...

The way it works now, a key error for another value could happen and subsequently hidden.

# if a monitor does't have the lastResult ususally it is
# still being provisioned
res = 0
date = "--"
ip_address = None
monitor_type = "--"

status = 'UNKNOWN'
status_color = None
if res == 0:
status = 'DOWN'
status_color = 'red'
elif res == 1:
status = 'WARNING'
status_color = 'yellow'
elif res == 2:
status = 'OK'
status_color = 'green'

table.add_row([
server['id'],
server['datacenter']['name'] or formatting.blank(),
server['fullyQualifiedDomainName'],
ip_address or formatting.blank(),
click.style(status, fg=status_color),
monitor_type,
date
])

return table
3 changes: 3 additions & 0 deletions SoftLayer/CLI/routes.py
Expand Up @@ -125,6 +125,9 @@

('metadata', 'SoftLayer.CLI.metadata:cli'),

('monitor', 'SoftLayer.CLI.monitor'),
('monitor:status', 'SoftLayer.CLI.monitor.status:cli'),

('nas', 'SoftLayer.CLI.nas'),
('nas:list', 'SoftLayer.CLI.nas.list:cli'),
('nas:credentials', 'SoftLayer.CLI.nas.credentials:cli'),
Expand Down
5 changes: 4 additions & 1 deletion SoftLayer/managers/__init__.py
Expand Up @@ -18,6 +18,8 @@
from SoftLayer.managers.load_balancer import LoadBalancerManager # NOQA
from SoftLayer.managers.messaging import MessagingManager # NOQA
from SoftLayer.managers.metadata import MetadataManager # NOQA
from SoftLayer.managers.monitor.hw_monitor import HardwareMonitorManager # NOQA
from SoftLayer.managers.monitor.vs_monitor import VSMonitorManager # NOQA
from SoftLayer.managers.network import NetworkManager # NOQA
from SoftLayer.managers.ordering import OrderingManager # NOQA
from SoftLayer.managers.sshkey import SshKeyManager # NOQA
Expand All @@ -30,4 +32,5 @@
'MetadataManager', 'CDNManager', 'NetworkManager',
'SshKeyManager', 'SSLManager', 'TicketManager',
'VSManager', 'ISCSIManager', 'LoadBalancerManager',
'OrderingManager']
'OrderingManager', 'HardwareMonitorManager',
'VSMonitorManager']
6 changes: 6 additions & 0 deletions SoftLayer/managers/monitor/__init__.py
@@ -0,0 +1,6 @@
"""
SoftLayer.managers.monitor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:license: MIT, see LICENSE for more details.
"""
40 changes: 40 additions & 0 deletions SoftLayer/managers/monitor/hw_monitor.py
@@ -0,0 +1,40 @@
"""
SoftLayer.monitor.hw_monitor
~~~~~~~~~~~~~~~~~~
Monitoring Manager/helpers for Hardware_Server

:license: MIT, see LICENSE for more details.
"""


class HardwareMonitorManager(object):
"""Manages monitoring for Hardware Servers

:param SoftLayer.API.CLient client: an API client instance
"""

def __init__(self, client):
self.client = client
self.account = self.client['Account']
self.server = self.client['Hardware_Server']

def list_status(self, **kwargs):
"""List all hardware with their monitoring status

:param dict \\*\\*kwargs: response-level options (mask, limit, filter)
:returns: Retrns a list of dictionaries with server and monitoring
information.
"""

vs_items = [
'id',
'fullyQualifiedDomainName',
'primaryBackendIpAddress',
'primaryIpAddress',
'datacenter',
'networkMonitors[lastResult,queryType]'
]

kwargs['mask'] = ('[mask[%s]]'
% (','.join(vs_items)))
return self.account.call('getHardware', **kwargs)
40 changes: 40 additions & 0 deletions SoftLayer/managers/monitor/vs_monitor.py
@@ -0,0 +1,40 @@
"""
SoftLayer.monitor.vs_monitor
~~~~~~~~~~~~~~~~~~
Monitoring Manager/helpers for Virtual_Guest

:license: MIT, see LICENSE for more details.
"""


class VSMonitorManager(object):
"""Manages monitoring for Virtual Servers

:param SoftLayer.API.CLient client: an API client instance
"""

def __init__(self, client):
self.client = client
self.account = self.client['Account']
self.server = self.client['Virtual_Guest']

def list_status(self, **kwargs):
"""List all virtual guests with their monitoring status

:param dict \\*\\*kwargs: response-level options (mask, limit, filter)
:returns: Retrns a list of dictionaries with server and monitoring
information.
"""

vs_items = [
'id',
'fullyQualifiedDomainName',
'primaryBackendIpAddress',
'primaryIpAddress',
'datacenter',
'networkMonitors[lastResult,queryType]'
]

kwargs['mask'] = ('[mask[%s]]'
% (','.join(vs_items)))
return self.account.call('getVirtualGuests', **kwargs)
Empty file.
74 changes: 70 additions & 4 deletions SoftLayer/testing/fixtures/SoftLayer_Account.py
Expand Up @@ -31,7 +31,6 @@
'globalIdentifier': '1a2b3c-1701',
'primaryBackendIpAddress': '10.45.19.37',
'hourlyBillingFlag': False,

'billingItem': {
'id': 6327,
'recurringFee': 1.54,
Expand All @@ -43,6 +42,24 @@
}
}
},
'networkMonitors': [{
'guestId': 100,
'hardwareId': '',
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 2,
'finishTime': '2015-01-28T17:27:06-06:00'
}
}, {
'guestId': 104,
'hardwareId': '',
'ipAddress': '158.85.177.200',
'queryType': {'name': 'KEY_ERROR'},
'lastResult': {
'responseStatus': 1
}
}],
}, {
'id': 104,
'hostname': 'vs-test2',
Expand All @@ -69,6 +86,25 @@
}
}
},
'networkMonitors': [{
'guestId': 104,
'hardwareId': '',
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 0,
'finishTime': '2014-01-28T17:27:06-06:00'
}
}, {
'guestId': 104,
'hardwareId': '',
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 1,
'finishTime': '2014-01-28T17:27:06-06:00'
}
}],
}]

getMonthlyVirtualGuests = [vs for vs in getVirtualGuests
Expand Down Expand Up @@ -136,7 +172,17 @@
'friendlyName': 'Friendly Transaction Name',
'id': 6660
}
}
},
'networkMonitors': [{
'guestId': '',
'hardwareId': 1000,
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 1,
'finishTime': '2014-01-28T17:27:06-06:00'
}
}],
}, {
'id': 1001,
'globalIdentifier': '1a2b3c-1702',
Expand Down Expand Up @@ -180,7 +226,17 @@
'vlanNumber': 3672,
'id': 19082
},
]
],
'networkMonitors': [{
'guestId': '',
'hardwareId': 1001,
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 0,
'finishTime': '2014-01-28T17:27:06-06:00'
}
}],
}, {
'id': 1002,
'datacenter': {'name': 'TEST00',
Expand Down Expand Up @@ -223,7 +279,17 @@
'vlanNumber': 3672,
'id': 19082
},
]
],
'networkMonitors': [{
'guestId': '',
'hardwareId': 1002,
'ipAddress': '158.85.177.200',
'queryType': {'name': 'SERVICE_PING'},
'lastResult': {
'responseStatus': 2,
'finishTime': '2014-01-28T17:27:06-06:00'
}
}],
}]
getDomains = [{'name': 'example.com',
'id': 12345,
Expand Down
31 changes: 31 additions & 0 deletions SoftLayer/tests/CLI/modules/monitor_tests.py
@@ -0,0 +1,31 @@
"""
SoftLayer.tests.managers.monitor_tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:license: MIT, see LICENSE for more details.
"""
import SoftLayer
from SoftLayer import testing


class MonitorTests(testing.TestCase):

def set_up(self):
self.hw_monitor_manager = SoftLayer.HardwareMonitorManager(self.client)
self.vs_monitor_manager = SoftLayer.VSMonitorManager(self.client)

def test_list_status(self):
result = self.run_command(['monitor', 'status'])
self.assertEqual(result.exit_code, 0)
self.assert_called_with('SoftLayer_Account', 'getVirtualGuests')
self.assert_called_with('SoftLayer_Account', 'getHardware')

def test_list_only_hardware(self):
result = self.run_command(['monitor', 'status', '--only_hardware'])
self.assert_called_with('SoftLayer_Account', 'getHardware')
self.assertEqual(result.exit_code, 0)

def test_list_only_virtual(self):
result = self.run_command(['monitor', 'status', '--only_virtual'])
self.assert_called_with('SoftLayer_Account', 'getVirtualGuests')
self.assertEqual(result.exit_code, 0)
26 changes: 26 additions & 0 deletions SoftLayer/tests/managers/monitor_tests.py
@@ -0,0 +1,26 @@
"""
SoftLayer.tests.managers.monitor_tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:license: MIT, see LICENSE for more details.
"""
import SoftLayer
from SoftLayer import testing
from SoftLayer.testing import fixtures


class MonitorTests(testing.TestCase):

def set_up(self):
self.hw_monitor_manager = SoftLayer.HardwareMonitorManager(self.client)
self.vs_monitor_manager = SoftLayer.VSMonitorManager(self.client)

def test_list_hardware_status(self):
result = self.hw_monitor_manager.list_status()
self.assertEqual(result, fixtures.SoftLayer_Account.getHardware)
self.assert_called_with('SoftLayer_Account', 'getHardware')

def test_list_guest_status(self):
result = self.vs_monitor_manager.list_status()
self.assertEqual(result, fixtures.SoftLayer_Account.getVirtualGuests)
self.assert_called_with('SoftLayer_Account', 'getVirtualGuests')