def _save_shares(dev, luns, mounts): wwns = [] for lun, volume in luns.iteritems(): rest, wwn_end = lun.rsplit('_', 1) try: share = DiskShare.objects.get(wwn__endswith=wwn_end) except DiskShare.DoesNotExist: continue wwns.append(share.wwn) clients = mounts.get(volume, []) for client in clients: ipaddr, ip_created = IPAddress.concurrent_get_or_create( address=client) mount, created = DiskShareMount.concurrent_get_or_create( address=ipaddr, device=ipaddr.device, share=share, server=dev) mount.volume = volume mount.save(update_last_seen=True) if not clients: mount, created = DiskShareMount.concurrent_get_or_create( address=None, device=None, share=share, server=dev) mount.volume = volume mount.save(update_last_seen=True) for mount in DiskShareMount.objects.filter(server=dev).exclude( share__wwn__in=wwns): mount.delete()
def test_validate_deploy_children(self): _validate_deploy_children('deadbeefcafe', 0) parent = Device.create( ethernets=[('', 'deadbeefcafe', 0)], model_name='splat', model_type=DeviceType.unknown, ) _validate_deploy_children('deadbeefcafe', 0) device = Device.create( ethernets=[('', 'cafedeadbeef', 0)], model_name='splat', model_type=DeviceType.unknown, parent=parent, ) with self.assertRaises(forms.ValidationError): _validate_deploy_children('deadbeefcafe', 0) device.parent = None device.save() _validate_deploy_children('deadbeefcafe', 0) _validate_deploy_children('cafedeadbeef', 0) share = DiskShare(wwn='a' * 33, device=parent) share.save() mount = DiskShareMount(share=share, device=device, server=device) mount.save() with self.assertRaises(forms.ValidationError): _validate_deploy_children('deadbeefcafe', 0) with self.assertRaises(forms.ValidationError): _validate_deploy_children('cafedeadbeef', 0)
def _save_shares(dev, luns, mounts): wwns = [] for lun, volume in luns.iteritems(): rest, wwn_end = lun.rsplit('_', 1) try: share = DiskShare.objects.get(wwn__endswith=wwn_end) except DiskShare.DoesNotExist: continue wwns.append(share.wwn) clients = mounts.get(volume, []) for client in clients: ipaddr, ip_created = IPAddress.concurrent_get_or_create(address=client) mount, created = DiskShareMount.concurrent_get_or_create( address=ipaddr, device=ipaddr.device, share=share, server=dev) mount.volume = volume mount.save(update_last_seen=True) if not clients: mount, created = DiskShareMount.concurrent_get_or_create( address=None, device=None, share=share, server=dev) mount.volume = volume mount.save(update_last_seen=True) for mount in DiskShareMount.objects.filter( server=dev ).exclude( share__wwn__in=wwns ): mount.delete()
def test_disk_shares_and_exports(self): model = ComponentModel( type=ComponentType.share, name="3par share", ) model.save() share = DiskShare( device=self.device, model=model, label="pr0n", size="2048", wwn="deadbeefcafe1234", ) share.save() address = IPAddress(address='127.0.0.1') address.save() DiskShareMount( device=self.device, share=share, address=address, ).save() data = get_device_data(Device.objects.get(sn='123456789')) exports = data['disk_exports'] mounts = data['disk_shares'] self.assertEqual(len(exports), 1) self.assertEqual(len(mounts), 1) self.assertEqual(mounts[0]['serial_number'], "deadbeefcafe1234")
def setUp(self): device = Device.create( ethernets=[('', 'deadbeefcafe', 0)], model_name='HAL 9000', model_type=DeviceType.unknown, remarks="I'm sorry, Dave.", ) self.deployment = Deployment( hostname='discovery.one', ip='127.0.0.1', mac='deadbeefcafe', device=device, preboot=None, venture=None, venture_role=None, ) self.deployment.save() self.ip = IPAddress(address='127.0.0.1', device=device) self.ip.save() IPAddress(address='127.0.0.2', device=device).save() share_model = ComponentModel(type=ComponentType.share, name="share") share_model.save() share = DiskShare(wwn='x' * 33, device=device, model=share_model) share.save() DiskShareMount(share=share, device=device).save() OperatingSystem.create(os_name='GladOS', dev=device, family='', priority=0) Software.create(dev=device, model_name='soft', path='/', family='', priority=0)
def make_mount(wwn): try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: return None mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) return mount
def make_mount(wwn): try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: return None mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) return mount
def _create_or_update_share_mount(ip, device, share_mount): share_address = None if share_mount.get('address'): try: share_address = IPAddress.objects.get( address=share_mount['address']) except IPAddress.DoesNotExist: pass try: share = DiskShare.objects.get(wwn=share_mount['serial_number']) except DiskShare.DoesNotExist: logger.warning( '%s%sNo share found for share mount: ' 'WWN=%s; Volume=%s; device=%s; venture=%s; device_ip=%s' % ('(3PAR) ' if _it_is_3par(share_mount['serial_number']) else '', '(virtual) ' if share_mount.get('is_virtual', False) else '', share_mount['serial_number'], share_mount.get('volume'), device, device.venture, ip.address)) return False, None try: mount = DiskShareMount.objects.get(device=device, share=share) except DiskShareMount.DoesNotExist: mount = DiskShareMount( device=device, share=share, ) logger.info( '%s%sCreate mount point on device %s (venture=%s). ' 'Share WWN=%s; Volume=%s; Share label=%s; IP address=%s' % ('(3PAR) ' if _it_is_3par(share_mount['serial_number']) else '', '(virtual) ' if share_mount.get('is_virtual', False) else '', device, device.venture, share_mount['serial_number'], share_mount.get('volume'), share.label, ip.address)) else: logger.info( '%s%sMount point on device %s (venture=%s) exists. ' 'Share WWN=%s; Volume=%s; Share label=%s; IP address=%s' % ('(3PAR) ' if _it_is_3par(share_mount['serial_number']) else '', '(virtual) ' if share_mount.get('is_virtual', False) else '', device, device.venture, share_mount['serial_number'], share_mount.get('volume'), share.label, ip.address)) if share_mount.get('size'): mount.size = share_mount['size'] if share_mount.get('volume'): mount.volume = share_mount['volume'] if share_address: mount.address = share_address mount.is_virtual = share_mount.get('is_virtual', False) mount.save() return True, mount
def update_shares(ssh, dev): """Update remote disk shares""" wwns = [] for lv, (wwn, size) in get_disk_shares(ssh).iteritems(): share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.size = size if not mount.volume: mount.volume = lv mount.save() for ds in dev.disksharemount_set.filter(is_virtual=False).exclude(share__wwn__in=wwns): ds.delete()
def save_shares(shares, dev, ip): wwns = [] for s in shares: wwn_end = s.get("sn") if not wwn_end: continue try: share = DiskShare.objects.get(wwn__endswith=wwn_end.upper()) except DiskShare.DoesNotExist: continue wwns.append(share.wwn) mount, _ = DiskShareMount.concurrent_get_or_create(device=dev, share=share) mount.volume = s.get("volume") mount.save(update_last_seen=True) for mount in DiskShareMount.objects.filter(device=dev).exclude(share__wwn__in=wwns): mount.delete()
def update_shares(ssh, dev): """Update remote disk shares""" wwns = [] for lv, (wwn, size) in get_disk_shares(ssh).iteritems(): share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.size = size if not mount.volume: mount.volume = lv mount.save() for ds in dev.disksharemount_set.filter(is_virtual=False).exclude( share__wwn__in=wwns): ds.delete()
def save_shares(shares, dev, ip): wwns = [] for s in shares: wwn_end = s.get('sn') if not wwn_end: continue try: share = DiskShare.objects.get(wwn__endswith=wwn_end.upper()) except DiskShare.DoesNotExist: continue wwns.append(share.wwn) mount, _ = DiskShareMount.concurrent_get_or_create(device=dev, share=share) mount.volume = s.get('volume') mount.save(update_last_seen=True) for mount in DiskShareMount.objects.filter(device=dev).exclude( share__wwn__in=wwns): mount.delete()
def _add_virtual_machine(ssh, vmid, parent, master, storage): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) disks = {} lan_model = None name = "unknown" for line in stdout: line = line.strip() key, value = line.split(":", 1) if key.startswith("vlan"): lan_model, lan_mac = value.split("=", 1) elif key == "name": name = value.strip() elif key == "sockets": cpu_count = int(value.strip()) elif key.startswith("ide") or key.startswith("virtio"): disks[key] = value.strip() if lan_model is None: return None dev = Device.create( model_name="Proxmox qemu kvm", model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name, ) wwns = [] for slot, disk in disks.iteritems(): params = {} if "," in disk: disk, rawparams = disk.split(",", 1) for kv in rawparams.split(","): if not kv.strip(): continue k, v = kv.split("=", 1) params[k] = v.strip() if ":" in disk: vg, lv = disk.split(":", 1) else: vg = "" lv = disk if vg == "local": model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family="QEMU disk image" ) if created: model.save() storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ("", "local", "pve-local"): continue vol = "%s:%s" % (vg, lv) try: wwn, size = storage[lv] except KeyError: logger.warning("Volume %r does not exist." % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning("A share with WWN %r does not exist." % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family="QEMU Virtual", cores=0 ) if cpu_model_created: cpu_model.name = "QEMU Virtual CPU version 0.12.4" cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = "CPU {}".format(i + 1) cpu.model = cpu_model cpu.family = "QEMU Virtual" cpu.save() dev.save(update_last_seen=True) return dev
def run_ssh_xen(ipaddr, parent): ssh = _connect_ssh(ipaddr.address) try: vms = get_running_vms(ssh) macs = get_macs(ssh) disks = get_disks(ssh) shares = hardware.get_disk_shares(ssh) finally: ssh.close() for dev in parent.child_set.exclude( sn__in=[vm_uuid for (vm_name, vm_uuid, vm_cores, vm_memory) in vms] ): dev.deleted = True dev.save() for vm_name, vm_uuid, vm_cores, vm_memory in vms: ethernets = [Eth('vif %d' % i, mac, 0) for i, mac in enumerate(macs.get(vm_name, []))] dev = Device.create(ethernets=ethernets, parent=parent, sn=vm_uuid, model_type=DeviceType.virtual_server, model_name='XEN Virtual Server', priority=SAVE_PRIORITY) dev.name = vm_name dev.save(priority=SAVE_PRIORITY) cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='XEN Virtual', cores=0) if cpu_model_created: cpu_model.name = 'XEN Virtual CPU' cpu_model.save() for i in xrange(vm_cores): cpu, created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if created: cpu.label = 'CPU %d' % i cpu.model = cpu_model cpu.family = 'XEN Virtual' cpu.save() for cpu in dev.processor_set.filter(index__gt=vm_cores+1): cpu.delete() mem_model, mem_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.memory.id, family='XEN Virtual', cores=0, size=0) if mem_model_created: mem_model.name = 'XEN Virtual Memory' mem_model.save() memory, created = Memory.concurrent_get_or_create(device=dev, index=1) memory.size = vm_memory memory.model = mem_model memory.label = 'XEN Memory' memory.save() for mem in dev.memory_set.filter(index__gt=1): mem.delete() disk_model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='XEN virtual disk') if created: disk_model.name = 'XEN virtual disk' disk_model.save() vm_disks = disks.get(vm_name, []) wwns = [] for uuid, sr_uuid, size, device in vm_disks: wwn, mount_size = shares.get('VHD-%s' % sr_uuid, (None, None)) if wwn: try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=ipaddr, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = mount_size mount.volume = device mount.save() else: storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=device, sn=uuid) storage.size = size storage.model = disk_model storage.label = device storage.save() for disk in dev.storage_set.exclude(sn__in={ uuid for uuid, x , y , z in vm_disks }): disk.delete() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() return ', '.join(vm_name for (vm_name, vm_uuid, vm_cores, vm_memory) in vms)
def test_disk_share(self): storage_dev = Device.create( sn='device', model_type=DeviceType.storage, model_name='storage device', ) storage_dev.save() share_group = ComponentModelGroup( price=1, type=ComponentType.share, per_size=False, size_unit='', size_modifier=1, ) share_group.save() share_model = ComponentModel( speed=0, cores=0, size=7, type=ComponentType.share, group=share_group, family='', ) share_model.save() disk_share = DiskShare( device=storage_dev, model=share_model, share_id=1, label="share", size=7, snapshot_size=5, wwn='123456789012345678901234567890123', full=True, ) disk_share.save() share_mount = DiskShareMount( share=disk_share, device=storage_dev, size=17, ) share_mount.save() today = date.today() this_month = date(year=today.year, month=today.month, day=1) pricing_group = PricingGroup( name='group', date=this_month, ) pricing_group.save() pricing_group.devices.add(storage_dev) pricing_group.save() pricing_formula = PricingFormula( group=pricing_group, component_group=share_group, formula='3+size+11*variable', ) pricing_formula.save() pricing_variable = PricingVariable( name='variable', group=pricing_group, aggregate=PricingAggregate.sum, ) pricing_variable.save() pricing_value = PricingValue( device=storage_dev, variable=pricing_variable, value=13, ) pricing_value.save() variable_value = pricing_variable.get_value() self.assertEqual(variable_value, 13) formula_value = pricing_formula.get_value(size=7) self.assertEqual(formula_value, 3 + 7 + 11 * 13) share_price = disk_share.get_price() self.assertEqual(share_price, 3 + (7.0 + 5.0) / 1024 + 11 * 13) mount_price = share_mount.get_price() self.assertEqual(mount_price, 3 + 17.0 / 1024 + 11 * 13)
def _add_virtual_machine(ssh, vmid, parent, master, storages): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: return None dev = Device.create(model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='QEMU disk image') if created: model.save() storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with WWN %r does not exist.' % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='QEMU Virtual', cores=0) if cpu_model_created: cpu_model.name = 'QEMU Virtual CPU version 0.12.4' cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True) return dev
def _add_virtual_machine(ssh, vmid, parent, master, storages, hypervisor_ip): stdin, stdout, stderr = ssh.exec_command( "cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() if line.startswith('#') or ':' not in line: continue key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: DiscoveryWarning( message="No LAN for virtual server %r." % vmid, plugin=__name__, device=parent, ip=hypervisor_ip ).save() return None dev = Device.create( model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name ) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': size = _get_local_disk_size(ssh, lv, parent, hypervisor_ip) if not size > 0: continue model, created = ComponentModel.create( ComponentType.disk, family='QEMU disk image', priority=SAVE_PRIORITY, ) # The model's size is deliberately 0 because it's a virtual # volume: there would be potentially as many models as volumes. storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=lv) storage.size = size storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) DiscoveryWarning( message="Volume %r does not exist." % lv, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.create( ComponentType.processor, family='QEMU Virtual', name='QEMU Virtual CPU version 0.12.4', # FIXME: why so specific? priority=SAVE_PRIORITY, ) for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True, priority=SAVE_PRIORITY) return dev
def run_ssh_xen(ipaddr, parent): ssh = _connect_ssh(ipaddr.address) try: vms = get_running_vms(ssh) macs = get_macs(ssh) disks = get_disks(ssh) shares = hardware.get_disk_shares(ssh) finally: ssh.close() for dev in parent.child_set.exclude(sn__in=[ vm_uuid for (vm_name, vm_uuid, vm_cores, vm_memory) in vms ]): dev.deleted = True dev.save() for vm_name, vm_uuid, vm_cores, vm_memory in vms: ethernets = [ Eth('vif %d' % i, mac, 0) for i, mac in enumerate(macs.get(vm_name, [])) ] dev = Device.create(ethernets=ethernets, parent=parent, sn=vm_uuid, model_type=DeviceType.virtual_server, model_name='XEN Virtual Server', priority=SAVE_PRIORITY) dev.name = vm_name dev.save(priority=SAVE_PRIORITY) cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='XEN Virtual', cores=0) if cpu_model_created: cpu_model.name = 'XEN Virtual CPU' cpu_model.save() for i in xrange(vm_cores): cpu, created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if created: cpu.label = 'CPU %d' % i cpu.model = cpu_model cpu.family = 'XEN Virtual' cpu.save() for cpu in dev.processor_set.filter(index__gt=vm_cores + 1): cpu.delete() mem_model, mem_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.memory.id, family='XEN Virtual', cores=0, size=0) if mem_model_created: mem_model.name = 'XEN Virtual Memory' mem_model.save() memory, created = Memory.concurrent_get_or_create(device=dev, index=1) memory.size = vm_memory memory.model = mem_model memory.label = 'XEN Memory' memory.save() for mem in dev.memory_set.filter(index__gt=1): mem.delete() disk_model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='XEN virtual disk') if created: disk_model.name = 'XEN virtual disk' disk_model.save() vm_disks = disks.get(vm_name, []) wwns = [] for uuid, sr_uuid, size, device in vm_disks: wwn, mount_size = shares.get('VHD-%s' % sr_uuid, (None, None)) if wwn: try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=ipaddr, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = mount_size mount.volume = device mount.save() else: storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=device, sn=uuid) storage.size = size storage.model = disk_model storage.label = device storage.save() for disk in dev.storage_set.exclude( sn__in={uuid for uuid, x, y, z in vm_disks}): disk.delete() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() return ', '.join(vm_name for (vm_name, vm_uuid, vm_cores, vm_memory) in vms)
def _create_or_update_share_mount(ip, device, share_mount): share_address = None if share_mount.get('address'): try: share_address = IPAddress.objects.get( address=share_mount['address'] ) except IPAddress.DoesNotExist: pass try: share = DiskShare.objects.get( wwn=share_mount['serial_number'] ) except DiskShare.DoesNotExist: logger.warning( '%s%sNo share found for share mount: ' 'WWN=%s; Volume=%s; device=%s; venture=%s; device_ip=%s' % ( '(3PAR) ' if _it_is_3par( share_mount['serial_number'] ) else '', '(virtual) ' if share_mount.get( 'is_virtual', False ) else '', share_mount['serial_number'], share_mount.get('volume'), device, device.venture, ip.address ) ) return try: mount = DiskShareMount.objects.get(device=device, share=share) except DiskShareMount.DoesNotExist: mount = DiskShareMount( device=device, share=share, ) logger.info( '%s%sCreate mount point on device %s (venture=%s). ' 'Share WWN=%s; Volume=%s; Share label=%s; IP address=%s' % ( '(3PAR) ' if _it_is_3par( share_mount['serial_number'] ) else '', '(virtual) ' if share_mount.get( 'is_virtual', False ) else '', device, device.venture, share_mount['serial_number'], share_mount.get('volume'), share.label, ip.address ) ) else: logger.info( '%s%sMount point on device %s (venture=%s) exists. ' 'Share WWN=%s; Volume=%s; Share label=%s; IP address=%s' % ( '(3PAR) ' if _it_is_3par( share_mount['serial_number'] ) else '', '(virtual) ' if share_mount.get( 'is_virtual', False ) else '', device, device.venture, share_mount['serial_number'], share_mount.get('volume'), share.label, ip.address ) ) if share_mount.get('size'): mount.size = share_mount['size'] if share_mount.get('volume'): mount.volume = share_mount['volume'] if share_address: mount.address = share_address mount.is_virtual = share_mount.get('is_virtual', False)
def _add_virtual_machine(ssh, vmid, parent, master, storages): stdin, stdout, stderr = ssh.exec_command( "cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: return None dev = Device.create( model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name ) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='QEMU disk image') if created: model.save() storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with WWN %r does not exist.' % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='QEMU Virtual', cores=0) if cpu_model_created: cpu_model.name = 'QEMU Virtual CPU version 0.12.4' cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i+1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True) return dev
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^modelname'): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, 'netstat -ia | grep link'): interface, mtu, net, mac, rest = mac_line.split(None, 4) if '.' not in mac: continue octets = mac.split('.') mac = ''.join('%02x' % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} os_storage_size = 0 for disk_line in _ssh_lines(ssh, 'lsdev -c disk'): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, 'lscfg -vl %s' % disk): if 'hdisk' in line: match = re.search(r'\(([0-9]+) MB\)', line) if match: os_storage_size += int(match.group(1)) elif 'Serial Number...' in line: label, sn = line.split('.', 1) sn = sn.strip('. \n') elif 'Machine Type and Model.' in line: label, model = line.split('.', 1) model = model.strip('. \n') disks[disk] = (model, sn) os_version = '' for line in _ssh_lines(ssh, 'oslevel'): os_version = line.strip() break os_memory = 0 for line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^realmem'): match = re.search(r'[0-9]+', line) if match: os_memory = int(int(match.group(0)) / 1024) break os_corescount = 0 for line in _ssh_lines(ssh, 'lparstat -i|grep ^Active\ Phys'): match = re.search(r'[0-9]+', line) if match: os_corescount += int(match.group(0)) finally: ssh.close() dev = Device.create(ethernets=ethernets, model_type=DeviceType.rack_server, model_name='%s AIX' % MODELS.get(machine_model, machine_model)) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == 'VV': wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev, is_virtual=False) mount.volume = disk mount.save() for disk, model_name, sn in stors: model, mcreated = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family=model_name, extra_hash='') model.name = model_name model.save() stor, created = Storage.concurrent_get_or_create(device=dev, sn=sn) stor.model = model stor.label = disk stor.save() mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = 'Memory' mem.model, c = ComponentModel.concurrent_get_or_create( size=0, speed=0, type=ComponentType.memory.id, family='pSeries', extra_hash='') mem.model.name = 'pSeries Memory' mem.model.save() mem.save() cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = 'CPU' cpu.model, c = ComponentModel.concurrent_get_or_create( speed=0, cores=0, type=ComponentType.processor.id, extra_hash='', family='pSeries CPU') cpu.model.name = 'pSeries CPU' cpu.model.save() cpu.save() os = OperatingSystem.create(dev=dev, os_name='AIX', version=os_version, family='AIX') os.memory = os_memory if os_memory else None os.cores_count = os_corescount if os_corescount else None os.storage = os_storage_size if os_storage_size else None os.save() return machine_model
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, "lsattr -El sys0 | grep ^modelname"): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, "netstat -ia | grep link"): interface, mtu, net, mac, rest = mac_line.split(None, 4) if "." not in mac: continue octets = mac.split(".") mac = "".join("%02x" % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} for disk_line in _ssh_lines(ssh, "lsdev -c disk"): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, "lscfg -vl %s" % disk): if "Serial Number..." in line: label, sn = line.split(".", 1) sn = sn.strip(". \n") elif "Machine Type and Model." in line: label, model = line.split(".", 1) model = model.strip(". \n") disks[disk] = (model, sn) finally: ssh.close() dev = Device.create( ethernets=ethernets, model_type=DeviceType.rack_server, model_name="%s AIX" % MODELS.get(machine_model, machine_model), ) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == "VV": wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = network.normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev, is_virtual=False) mount.volume = disk mount.save() for disk, model_name, sn in stors: model, mcreated = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family=model_name, extra_hash="" ) model.name = model_name model.save() stor, created = Storage.concurrent_get_or_create(device=dev, sn=sn) stor.model = model stor.label = disk stor.save() mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = "Memory" mem.model, c = ComponentModel.concurrent_get_or_create( size=0, speed=0, type=ComponentType.memory.id, family="pSeries", extra_hash="" ) mem.model.name = "pSeries Memory" mem.model.save() mem.save() cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = "CPU" cpu.model, c = ComponentModel.concurrent_get_or_create( speed=0, cores=0, type=ComponentType.processor.id, extra_hash="", family="pSeries CPU" ) cpu.model.name = "pSeries CPU" cpu.model.save() cpu.save() return machine_model
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^modelname'): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, 'netstat -ia | grep link'): interface, mtu, net, mac, rest = mac_line.split(None, 4) if '.' not in mac: continue octets = mac.split('.') mac = ''.join('%02x' % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} os_storage_size = 0 for disk_line in _ssh_lines(ssh, 'lsdev -c disk'): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, 'lscfg -vl %s' % disk): if 'hdisk' in line: match = re.search(r'\(([0-9]+) MB\)', line) if match: os_storage_size += int(match.group(1)) elif 'Serial Number...' in line: label, sn = line.split('.', 1) sn = sn.strip('. \n') elif 'Machine Type and Model.' in line: label, model = line.split('.', 1) model = model.strip('. \n') disks[disk] = (model, sn) os_version = '' for line in _ssh_lines(ssh, 'oslevel'): os_version = line.strip() break os_memory = 0 for line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^realmem'): match = re.search(r'[0-9]+', line) if match: os_memory = int(int(match.group(0)) / 1024) break os_corescount = 0 for line in _ssh_lines(ssh, 'lparstat -i|grep ^Active\ Phys'): match = re.search(r'[0-9]+', line) if match: os_corescount += int(match.group(0)) finally: ssh.close() dev = Device.create( ethernets=ethernets, model_type=DeviceType.rack_server, model_name='%s AIX' % MODELS.get(machine_model, machine_model)) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == 'VV': wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev, defaults={'is_virtual':False}) mount.volume = disk mount.save(priority=SAVE_PRIORITY) for disk, model_name, sn in stors: # FIXME: storage with no size model, c = ComponentModel.create( ComponentType.disk, family=model_name, priority=SAVE_PRIORITY, ) stor, created = Storage.concurrent_get_or_create( device=dev, sn=sn, mount_point=None, ) stor.model = model stor.label = disk stor.save(priority=SAVE_PRIORITY) # FIXME: memory with no size mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = 'Memory' mem.model, c = ComponentModel.create( ComponentType.memory, family='pSeries', priority=SAVE_PRIORITY, ) mem.save(priority=SAVE_PRIORITY) # FIXME: CPUs without info cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = 'CPU' cpu.model, c = ComponentModel.create( ComponentType.processor, family='pSeries', name='pSeries CPU', priority=SAVE_PRIORITY, ) cpu.save(priority=SAVE_PRIORITY) OperatingSystem.create(dev=dev, os_name='AIX', version=os_version, family='AIX', memory=os_memory or None, cores_count=os_corescount or None, storage=os_storage_size or None, priority=SAVE_PRIORITY ) return machine_model
def _add_virtual_machine(ssh, vmid, parent, master, storages, hypervisor_ip): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() if line.startswith('#') or ':' not in line: continue key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: DiscoveryWarning(message="No LAN for virtual server %r." % vmid, plugin=__name__, device=parent, ip=hypervisor_ip).save() return None dev = Device.create(model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': size = _get_local_disk_size(ssh, lv, parent, hypervisor_ip) if not size > 0: continue model, created = ComponentModel.create( ComponentType.disk, family='QEMU disk image', priority=SAVE_PRIORITY, ) # The model's size is deliberately 0 because it's a virtual # volume: there would be potentially as many models as volumes. storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = size storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) DiscoveryWarning( message="Volume %r does not exist." % lv, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.create( ComponentType.processor, family='QEMU Virtual', name='QEMU Virtual CPU version 0.12.4', # FIXME: why so specific? priority=SAVE_PRIORITY, ) for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True, priority=SAVE_PRIORITY) return dev