def run(self, data): vm = VirtualMachine( name=data["vm_name"], role=data["role"], status=data["status"], cluster=data["cluster"], platform=data["platform"], vcpus=data["vcpus"], memory=data["memory"], disk=data["disk"], comments=data["comments"], tenant=data.get("tenant"), ) vm.save() interface = Interface( name=data["interface_name"], type=InterfaceTypeChoices.TYPE_VIRTUAL, mac_address=data["mac_address"], virtual_machine=vm, ) interface.save() def add_addr(addr, expect_family): if not addr: return if addr.version != expect_family: raise RuntimeError("Wrong family for %r" % a) try: a = IPAddress.objects.get( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Assigned" except ObjectDoesNotExist: a = IPAddress( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Created" a.status = IPAddressStatusChoices.STATUS_ACTIVE a.dns_name = data["dns_name"] if a.interface: raise RuntimeError("Address %s is already assigned" % addr) a.interface = interface a.tenant = data.get("tenant") a.save() self.log_info("%s IP address %s %s" % (result, a.address, a.vrf or "")) setattr(vm, "primary_ip%d" % a.family, a) add_addr(data["primary_ip4"], 4) add_addr(data["primary_ip6"], 6) vm.save() self.log_success("Created VM %s" % vm.name)
def sync_vms(device, vms): """ Syncing VirtualMachines from device :param device: :param vms: :return: """ if not vms: return False, "There is no VM to update" # TODO: cluster tenancy cluster = device.cluster if not cluster: # Will create a new cluster logger.debug("Creating a new cluster {}".format(device.name)) cluster = Cluster() cluster.name = device.name cluster.type = ClusterType.objects.get(name=DEFAULT_CLUSTER_TYPE) cluster.site = device.site logger.debug("Saving a cluster {}".format(device.name)) cluster.save() cluster.devices.add(device) cluster.save() logger.debug("Device was added to cluster {}".format(device.name)) # Determine non-exists VMs and put it offline new_vm_names = [vm_data['NAME'] for vm_data in vms] if new_vm_names: logger.debug("New VMS: {}".format(new_vm_names)) non_exist_vms = VirtualMachine.objects.filter( cluster_id=cluster.id).exclude(name__in=new_vm_names) logger.debug( "VM which located in netbox, but non-exist on current cluster: {}". format(non_exist_vms)) if non_exist_vms: for vm in non_exist_vms: if vm.status != DEVICE_STATUS_STAGED: vm.status = DEVICE_STATUS_STAGED # vm.comments = vm.comments + "\n\nVM not exist on current cluster!\n" vm.save() # TODO: role and platform # By default all VMS - is a linux VMs platform = Platform.objects.get(name='Linux') # with server roles role = DeviceRole.objects.get(name='Server') # TODO: Need a get vm disks from vm objects # for vm_instance in vms: # pass for vm_data in vms: temp_vm = __TempVm(vm_data.get('NAME')) logger.debug("Will sync VM named: {}".format(temp_vm)) temp_vm.cluster_id = cluster.id temp_vm.platform_id = platform.id temp_vm.role_id = role.id temp_vm.memory = int( vm_data['MEM']) / 1024 # its a simple method - we need a MB temp_vm.vcpus = int(vm_data['VCPU']) # Determine VM state if int(vm_data['STATE']) == DEVICE_STATUS_ACTIVE: temp_vm.status = DEVICE_STATUS_ACTIVE # get disks names = vm_data.get('DISKNAMES') sizes = vm_data.get('DISKSIZES') paths = vm_data.get('DISKPATHS') # TODO: govnocode style - rewrite it for pythonic true way # This code parse a strings, like "{'diskindex': 1, 'name': 'sda'}" # Convert it to pythonic code # and split to one dict disks = [] total_size = 0 for name in names: name = ast.literal_eval(name) temp = name.copy() index = temp.get('diskindex') for size in sizes: size = ast.literal_eval(size) size_index = size.get('diskindex') if size_index == index: temp.update(size) for path in paths: path = ast.literal_eval(path) path_index = path.get('diskindex') if path_index == index: temp.update(path) disks.append(temp) del temp # non-urgent logger.info("Disks is: {}, len is {}".format(disks, len(disks))) # Filling VM comments with Disk Section separator = SEPARATOR # saving comments # TODO: fixing adding comments with multiple separator # TODO: Change this try: original_comments = VirtualMachine.objects.get( name=temp_vm.name).comments except: logger.debug("Cannot find a VM for original comments") original_comments = "" try: logger.debug("Tries to detect if comments exist") comments = separator.join(original_comments.split(separator)[1:]) except: logger.debug("Still no any other comments...") comments = original_comments disk_string = "" # and adding disks for disk in disks: try: logger.debug("Size of disk {} is {}".format( disk.get('name'), disk.get('size'))) size = int(disk.get('size')) / pow(1024, 3) disk_string += "**Disk:** {}\t**Size:** {} GB\t**Path:** {}\n".format( disk.get('name'), int(size), disk.get('path')) total_size += size except Exception as e: logger.warning("Cannot add disk {} - error is {}".format( disk.get('name'), e)) disk_string += separator temp_vm.comments = disk_string + comments temp_vm.disk = int(total_size) vm = VirtualMachine.objects.filter(name=temp_vm.name) logger.debug("found VM: {}".format(vm)) logger.debug("VM Data: {}".format(vm.__dict__)) if vm: logger.info("VM {} already exists. Will update this VM".format( temp_vm.name)) vm = vm[0] if _diff_objects(temp_vm, vm) == 0: vm.cluster_id = temp_vm.cluster_id vm.status = temp_vm.status vm.platform_id = temp_vm.platform_id vm.role_id = temp_vm.role_id vm.memory = temp_vm.memory vm.vcpus = temp_vm.vcpus vm.comments = temp_vm.comments vm.disk = temp_vm.disk vm.save() logger.info("VM {} was updated".format(vm.name)) else: logger.info("VM {} was not changed - nothing to change".format( temp_vm.name)) else: logger.info("VM {} is not exist. Will create new VM".format( temp_vm.name)) vm = VirtualMachine() vm.name = temp_vm.name vm.status = temp_vm.status vm.cluster_id = temp_vm.cluster_id vm.platform_id = temp_vm.platform_id vm.role_id = temp_vm.role_id vm.memory = temp_vm.memory vm.vcpus = temp_vm.vcpus vm.comments = temp_vm.comments vm.disk = temp_vm.disk vm.save() logger.info("Saved new VM: {}".format(vm.name)) return True, "VMs successfully synced"
def run(self, data, commit): pve_host = Device.objects.filter(name=data["pve_host"]) vm = VirtualMachine( name=data["vm_name"], role=data["role"], status=data["status"], vcpus=data["vcpus"], memory=data["memory"], disk=data["disk"], comments=data["comments"], ) if commit: vm.save() interface = Interface( name=data["interface_name"], type=InterfaceTypeChoices.TYPE_VIRTUAL, virtual_machine=vm, ) if commit: interface.save() def add_addr(addr, expect_family): if not addr: return if addr.version != expect_family: raise RuntimeError("Wrong family for %r" % a) try: a = IPAddress.objects.get( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Assigned" except ObjectDoesNotExist: a = IPAddress( address=addr, family=addr.version, vrf=data.get("vrf"), ) result = "Created" a.status = IPAddressStatusChoices.STATUS_ACTIVE a.dns_name = data["dns_name"] if a.interface: raise RuntimeError("Address %s is already assigned" % addr) a.interface = interface a.tenant = data.get("tenant") a.save() self.log_info("%s IP address %s %s" % (result, a.address, a.vrf or "")) setattr(vm, "primary_ip%d" % a.family, a) def connect_pve(addr): self.log_info(addr) proxmox = ProxmoxAPI( addr, user='******', token_name='nb1', token_value='0cf6ab07-ff7e-41a3-80e4-e09e7fea6c7d', verify_ssl=False) self.log_success(proxmox.nodes.get()) # self.log_info(data["pve_host"]) pve_ip = str(pve_host.get().primary_ip4)[:-3] self.log_info(pve_ip) connect_pve(pve_ip) if commit: add_addr(data["primary_ip4"], 4) # add_addr(data["primary_ip6"], 6) vm.save() self.log_success("Created VM %s" % vm.name) else: self.log_success("Dry-run Success - Created VM %s" % vm.name)
def run(self, data, commit): vm = VirtualMachine( name=data["vm_name"], role=data["role"], status=data["status"], cluster=data["cluster"], platform=data["platform"], vcpus=data["vcpus"], memory=data["memory"], disk=data["disk"], comments=data["comments"], tenant=data.get("tenant"), ) vm.full_clean() vm.save() vm.tags.set(data["vm_tags"]) vminterface = VMInterface( name=data["interface_name"], mac_address=data["mac_address"], virtual_machine=vm, ) vminterface.full_clean() vminterface.save() def add_addr(addr, family): if not addr: return if addr.version != family: raise RuntimeError(f"Wrong family for {a}") try: a = IPAddress.objects.get( address=addr, vrf=data.get("vrf"), ) result = "Assigned" except ObjectDoesNotExist: a = IPAddress( address=addr, vrf=data.get("vrf"), ) result = "Created" a.status = IPAddressStatusChoices.STATUS_ACTIVE a.dns_name = data["dns_name"] if a.assigned_object: raise RuntimeError(f"Address {addr} is already assigned") a.assigned_object = vminterface a.tenant = data.get("tenant") a.full_clean() a.save() #a.tags.set(data[f"primary_ip{family}_tags"]) self.log_info(f"{result} IP address {a.address} {a.vrf or ''}") setattr(vm, f"primary_ip{family}", a) add_addr(data["primary_ip4"], 4) add_addr(data["primary_ip6"], 6) vm.full_clean() vm.save() self.log_success( f"Created VM [{vm.name}](/virtualization/virtual-machines/{vm.id}/)" )