def device_from_data(data): """ Create or find a device based on the provided scan data. """ sn = data.get('serial_number') ethernets = [('', mac, None) for mac in data.get('mac_addresses', [])] model_name = data.get('model_name') model_type = DeviceType.from_name(data.get('type', 'unknown').lower()) device = Device.create( sn=sn, ethernets=ethernets, model_name=model_name, model_type=model_type, ) set_device_data(device, data) device.save() return device
def device_from_data(data, save_priority=SAVE_PRIORITY, user=None): """ Create or find a device based on the provided scan data. """ sn = data.get('serial_number') ethernets = [('', mac, None) for mac in data.get('mac_addresses', [])] model_name = data.get('model_name') model_type = DeviceType.from_name( '_'.join( data.get('type', 'unknown',).split(), ).lower(), ) device = Device.create( sn=sn, ethernets=ethernets, model_name=model_name, model_type=model_type, ) set_device_data(device, data, save_priority=save_priority) device.save(priority=save_priority, user=user) return device
def set_device_data(device, data): """ Go through the submitted data, and update the Device object in accordance with the meaning of the particular fields. """ keys = { 'sn': 'serial_number', 'name': 'hostname', 'dc': 'data_center', 'rack': 'rack', 'barcode': 'barcode', 'chassis_position': 'chassis_position', } for field_name, key_name in keys.iteritems(): if key_name in data: setattr(device, field_name, data[key_name]) if 'model_name' in data: try: model_type = DeviceType.from_name(data.get('type', 'unknown')) except ValueError: model_type = ComponentType.unknown try: # Don't use get_or_create, because we are in transaction device.model = DeviceModel.objects.get(name=data['model_name']) except DeviceModel.DoesNotExist: model = DeviceModel( type=model_type, name=data['model_name'], ) model.save() device.model = model else: if all(( device.model.type != model_type, model_type != ComponentType.unknown, )): device.model.type = model_type device.model.save() if 'disks' in data: _update_component_data( device, data['disks'], Storage, { 'sn': 'serial_number', 'device': 'device', 'size': 'size', 'speed': 'speed', 'mount_point': 'mount_point', 'label': 'label', 'family': 'family', 'model_name': 'model_name', }, [ ('sn',), ('device', 'mount_point'), ], ComponentType.disk, {'name'}, ) if 'processors' in data: for index, processor in enumerate(data['processors']): processor['index'] = index _update_component_data( device, data['processors'], Processor, { 'device': 'device', 'label': 'label', 'speed': 'speed', 'cores': 'cores', 'family': 'family', 'index': 'index', 'model_name': 'model_name', }, [ ('device', 'index'), ], ComponentType.processor, ) if 'memory' in data: for index, memory in enumerate(data['memory']): memory['index'] = index memory['speed'] = memory.get('speed', None) or None _update_component_data( device, data['memory'], Memory, { 'device': 'device', 'label': 'label', 'speed': 'speed', 'size': 'size', 'index': 'index', }, [ ('device', 'index'), ], ComponentType.memory, {'name'}, ) if 'mac_addresses' in data: _update_component_data( device, [{'mac': mac} for mac in data['mac_addresses']], Ethernet, { 'mac': 'mac', 'device': 'device', }, [ ('mac',), ], None, ) if 'management_ip_addresses' in data: _update_addresses(device, data['management_ip_addresses'], True) if 'system_ip_addresses' in data: _update_addresses(device, data['system_ip_addresses'], False) if 'fibrechannel_cards' in data: _update_component_data( device, data['fibrechannel_cards'], FibreChannel, { 'device': 'device', 'label': 'label', 'model_name': 'model_name', 'physical_id': 'physical_id', }, [ ('physical_id', 'device'), ], ComponentType.fibre, ) if 'parts' in data: _update_component_data( device, data['parts'], GenericComponent, { 'device': 'device', 'label': 'label', 'model_name': 'model_name', 'sn': 'serial_number', 'type': 'type', }, [ ('sn',), ], ) if 'disk_exports' in data: _update_component_data( device, data['disk_exports'], DiskShare, { 'device': 'device', 'label': 'label', 'wwn': 'serial_number', 'size': 'size', 'full': 'full', 'snapshot_size': 'snapshot_size', 'share_id': 'share_id', 'model_name': 'model_name', }, [ ('wwn',), ], ComponentType.share, ) if 'disk_shares' in data: for share in data['disk_shares']: if share.get('server'): servers = find_devices({ 'server': share['server'], }) if len(servers) > 1: raise ValueError( "Multiple servers found for share mount %r" % share, ) elif len(servers) <= 0: raise ValueError( "No server found for share mount %r" % share, ) share['server'] = servers[0] else: share['server'] = None share['share'] = DiskShare.objects.get(wwn=share['serial_number']) if share.get('address'): share['address'] = IPAddress.objects.get( address=share['address'], ) _update_component_data( device, data['disk_shares'], DiskShareMount, { 'share': 'share', 'size': 'size', 'address': 'address', 'is_virtual': 'is_virtual', 'volume': 'volume', 'server': 'server', 'device': 'device', }, [ ('device', 'share'), ], ) if 'installed_software' in data: _update_component_data( device, data['installed_software'], Software, { 'device': 'device', 'path': 'path', 'label': 'label', 'version': 'version', 'model_name': 'model_name', 'sn': 'serial_number', }, [ ('device', 'path'), ], ComponentType.software, ) if ( 'system_label' in data or 'system_memory' in data or 'system_storage' in data or 'system_cores_count' in data or 'system_family' in data or 'system_model_name' in data ): _update_component_data( device, [data], OperatingSystem, { 'device': 'device', 'memory': 'system_memory', 'storage': 'system_storage', 'cores_count': 'system_cores_count', 'family': 'system_family', 'label': 'system_label', 'model_name': 'system_model_name', }, [ ('device',), ], ComponentType.os, ) if 'subdevices' in data: subdevice_ids = [] for subdevice_data in data['subdevices']: subdevice = device_from_data(subdevice_data) subdevice.parent = device subdevice.save() subdevice_ids.append(subdevice.id) for subdevice in device.child_set.exclude(id__in=subdevice_ids): subdevice.parent = None subdevice.save() if 'asset' in data and 'ralph_assets' in settings.INSTALLED_APPS: from ralph_assets.api_ralph import assign_asset if data['asset']: assign_asset(device.id, data['asset'].id)