Skip to content

Commit

Permalink
Merge 72ed1fb into ccb36b0
Browse files Browse the repository at this point in the history
  • Loading branch information
andrzej-jankowski committed Aug 11, 2014
2 parents ccb36b0 + 72ed1fb commit a98e775
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 24 deletions.
8 changes: 4 additions & 4 deletions src/ralph/discovery/admin.py
Expand Up @@ -312,9 +312,9 @@ class InboundConnectionInline(ForeignKeyAutocompleteTabularInline):
model = m.Connection
extra = 1
related_search_fields = {
'inbound': ['^name']
'outbound': ['^name']
}
fk_name = 'outbound'
fk_name = 'inbound'
verbose_name = _("Inbound Connection")
verbose_name_plural = _("Inbound Connections")

Expand All @@ -323,9 +323,9 @@ class OutboundConnectionInline(ForeignKeyAutocompleteTabularInline):
model = m.Connection
extra = 1
related_search_fields = {
'outbound': ['^name'],
'inbound': ['^name'],
}
fk_name = 'inbound'
fk_name = 'outbound'
verbose_name = _("Outbound Connection")
verbose_name_plural = _("Outbound Connections")

Expand Down
6 changes: 4 additions & 2 deletions src/ralph/discovery/models.py
Expand Up @@ -9,19 +9,20 @@
from __future__ import unicode_literals

from ralph.discovery.models_device import (
Connection,
ConnectionType,
DeprecationKind,
Device,
DeviceModel,
DeviceModelGroup,
DeviceType,
DISK_PRODUCT_BLACKLIST,
DISK_VENDOR_BLACKLIST,
Connection,
ConnectionType,
LoadBalancerMember,
LoadBalancerPool,
LoadBalancerVirtualServer,
MarginKind,
NetworkConnection,
ReadOnlyDevice,
SERIAL_BLACKLIST,
UptimeSupport,
Expand Down Expand Up @@ -108,6 +109,7 @@
'LoadBalancerPool',
'LoadBalancerVirtualServer',
'MarginKind',
'NetworkConnection',
'ReadOnlyDevice',
'SERIAL_BLACKLIST',
'UptimeSupport',
Expand Down
4 changes: 2 additions & 2 deletions src/ralph/discovery/models_device.py
Expand Up @@ -828,13 +828,13 @@ class Connection(db.Model):
Device,
verbose_name=_("connected to device"),
on_delete=db.PROTECT,
related_name='inbound_connections',
related_name='outbound_connections',
)
inbound = db.ForeignKey(
Device,
verbose_name=_("connected device"),
on_delete=db.PROTECT,
related_name='outbound_connections',
related_name='inbound_connections',
)
connection_type = db.PositiveIntegerField(
verbose_name=_("connection type"),
Expand Down
103 changes: 102 additions & 1 deletion src/ralph/scan/data.py
Expand Up @@ -32,9 +32,12 @@
IPAddress,
)
from ralph.discovery.models_device import (
Connection,
ConnectionType,
Device,
DeviceType,
DeviceModel,
DeviceType,
NetworkConnection,
)
from ralph.scan.merger import merge as merge_component

Expand Down Expand Up @@ -401,6 +404,37 @@ def get_device_data(device):
data['system_cores_count'] = system.cores_count
if system.model:
data['system_family'] = system.model.family
connections = []
for conn in device.outbound_connections.all():
connected_device_sn = ''
if conn.inbound.sn is not None:
connected_device_sn = conn.inbound.sn
connection_details = {}
if conn.connection_type == ConnectionType.network:
try:
network_connection_details = NetworkConnection.objects.get(
connection=conn
)
except NetworkConnection.DoesNotExist:
pass
else:
connection_details[
'outbound_port'
] = network_connection_details.outbound_port
connection_details[
'inbound_port'
] = network_connection_details.inbound_port
connections.append({
'connection_type': ConnectionType.name_from_id(
conn.connection_type
),
'connected_device_mac_addresses': ",".join([
mac.mac for mac in conn.inbound.ethernet_set.all()
]),
'connected_device_serial_number': connected_device_sn,
'connection_details': connection_details
})
data['connections'] = connections
if 'ralph_assets' in settings.INSTALLED_APPS:
from ralph_assets.api_ralph import get_asset
asset = get_asset(device.id)
Expand Down Expand Up @@ -742,6 +776,30 @@ def set_device_data(device, data, save_priority=SAVE_PRIORITY, warnings=[]):
for subdevice in device.child_set.exclude(id__in=subdevice_ids):
subdevice.parent = None
subdevice.save(priority=save_priority)
if 'connections' in data:
parsed_connections = set()
for connection_data in data['connections']:
connection = connection_from_data(device, connection_data)
if connection.connection_type == ConnectionType.network:
connetion_details = connection_data.get('details', {})
if connetion_details:
outbound_port = connetion_details.get('outbound_port')
inbound_port = connetion_details.get('inbound_port')
try:
details = NetworkConnection.objects.get(
connection=connection
)
except NetworkConnection.DoesNotExist:
details = NetworkConnection(connection=connection)
if outbound_port:
details.outbound_port = outbound_port
if inbound_port:
details.inbound_port = inbound_port
details.save()
parsed_connections.add(connection.pk)
device.outbound_connections.exclude(
pk__in=parsed_connections
).delete()
if 'asset' in data and 'ralph_assets' in settings.INSTALLED_APPS:
from ralph_assets.api_ralph import assign_asset
if data['asset']:
Expand All @@ -753,6 +811,49 @@ def set_device_data(device, data, save_priority=SAVE_PRIORITY, warnings=[]):
assign_asset(device.id, asset_id)


def connection_from_data(device, connection_data):
query = {}
serial_number = connection_data.get('connected_device_serial_number')
if serial_number:
query['sn'] = serial_number
mac_addresses = connection_data.get('connected_device_mac_addresses')
if mac_addresses:
mac_addresses = [mac.strip() for mac in mac_addresses.split(",")]
query['ethernet__mac__in'] = mac_addresses
if not query:
raise ValueError(
"Can not find connected device. Please specify connected device "
"mac address or serial number."
)
connected_devices = Device.objects.filter(**query)
if not connected_devices:
raise ValueError(
"Can not find connected device. Please specify connected device "
"mac address or serial number."
)
if len(connected_devices) > 1:
raise ValueError(
"Many devices found. Probably specified mac addresses are not "
"connected with one device..."
)
connected_device = connected_devices[0]
connection_type = _get_choice_by_name(
ConnectionType,
connection_data.get('connection_type', '')
)
try:
return device.outbound_connections.get(
inbound=connected_device,
connection_type=connection_type
)
except Connection.DoesNotExist:
return Connection.objects.create(
outbound=device,
inbound=connected_device,
connection_type=connection_type
)


def device_from_data(
data, save_priority=SAVE_PRIORITY, user=None, warnings=[]
):
Expand Down
2 changes: 1 addition & 1 deletion src/ralph/scan/diff.py
Expand Up @@ -174,7 +174,7 @@ def diff_results(data, ignored_fields=set(['device', 'model_name'])):

diffs = {}
for component, results in data.iteritems():
if component == 'subdevices':
if component in ('subdevices', 'connections'):
continue # skipped because this is not component...
db_results_key = _find_database_key(results)
if not db_results_key:
Expand Down
5 changes: 5 additions & 0 deletions src/ralph/scan/forms.py
Expand Up @@ -337,6 +337,11 @@ class DiffForm(forms.Form):
'mgmt_firmware',
]),
'subdevices': CSVInfo(['hostname', 'serial_number', 'id']),
'connections': CSVInfo([
'connection_type',
'connected_device_mac_addresses',
'connected_device_serial_number',
]),
}

def __init__(self, data, *args, **kwargs):
Expand Down
6 changes: 4 additions & 2 deletions src/ralph/scan/plugins/ssh_linux.py
Expand Up @@ -183,15 +183,17 @@ def _get_lldp_info(ssh, messages=[]):
for line in stdout.readlines():
if not connection:
connection = {
'connection_type': ConnectionType.network.raw,
'connection_type': ConnectionType.network.name,
'details': {}
}
if "Interface:" in line:
connection['details']['outbound_port'] = line.strip().split(
":"
)[1].split(",")[0].strip()
if "ChassisID:" in line:
connection['mac_address'] = MACAddressField.normalize(
connection[
'connected_device_mac_addresses'
] = MACAddressField.normalize(
line.strip().split(':', 1)[1].replace('mac', '').strip()
)
if "PortID:" in line:
Expand Down
17 changes: 11 additions & 6 deletions src/ralph/scan/tests/plugins/test_ssh_linux.py
Expand Up @@ -248,20 +248,25 @@ def test_get_lldp_info(self):
_get_lldp_info(ssh),
[
{
'connection_type': 'network connection',
'connected_device_mac_addresses': 'AABBCC112233',
'connection_type': 'network',
'details': {
'outbound_port': 'eth0',
'inbound_port': 'local Server bay 1'
},
'mac_address': 'AABBCC112233'
}
},
{
'connection_type': 'network connection',
'connected_device_mac_addresses': 'AABBCC112244',
'connection_type': 'network',
'details': {
'outbound_port': 'eth1',
'inbound_port': 'gr2'
},
'mac_address': 'AABBCC112244'
}
}
]
)
ssh = MockSSH([(
"/usr/bin/sudo /usr/sbin/lldpctl",
""
)])
self.assertEqual(_get_lldp_info(ssh), [])

0 comments on commit a98e775

Please sign in to comment.