Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
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"
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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}/)"
        )