def mutate_and_get_payload(cls, input, context, info):
        type = input.get('type')
        group = input.get('group')
        site = input.get('site')

        temp = Cluster()

        if not_none(type):
            temp.type = ClusterType.objects.get(pk=from_global_id(type)[1])

        if not_none(group):
            temp.group = ClusterGroup.objects.get(pk=from_global_id(group)[1])

        if not_none(site):
            temp.site = Site.objects.get(pk=from_global_id(site)[1])

        fields = ['name', 'comments']
        return NewCluster(cluster=set_and_save(fields, input, temp))
Пример #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"