示例#1
0
    def post(self, request, *args, **kwargs):
        """Add machine."""
        if not request.user.is_superuser:
            return ErrorMessage("Only superusers are allowed to perform this action!").as_json

        data = json.loads(request.body.decode('utf-8'))['form']
        form = MachineAPIForm(data)

        if form.is_valid():

            cleaned_data = form.cleaned_data
            mac_address = cleaned_data['mac_address']
            del cleaned_data['mac_address']

            new_machine = Machine(**cleaned_data)
            new_machine.mac_address = mac_address
            try:
                new_machine.save()
            except Exception as e:
                logger.exception(e)
                return ErrorMessage("Something went wrong!").as_json

            return Message('Ok.').as_json

        return ErrorMessage("\n{}".format(format_cli_form_errors(form))).as_json
示例#2
0
    def setUp(self, m_is_dns_resolvable):
        m_is_dns_resolvable.return_value = True

        ServerConfig.objects.create(key='domain.validendings', value='bar.de')

        m1 = Machine()
        m1.pk = 1
        m1.fqdn = 'machine1.foo.bar.de'
        m1.mac_address = '01:AB:22:33:44:55'
        m1.architecture_id = Architecture.Type.X86_64
        m1.system_id = System.Type.BAREMETAL

        m1.save()

        m2 = Machine()
        m1.pk = 2
        m2.fqdn = 'machine2.foo.bar.de'
        m2.mac_address = '02:AB:22:33:44:55'
        m2.architecture_id = Architecture.Type.X86_64
        m2.system_id = System.Type.BMC

        m2.save()
示例#3
0
def get_hardware_information(fqdn):
    """Retrieve information of the system."""
    try:
        machine = Machine.objects.get(fqdn=fqdn)
    except Machine.DoesNotExist:
        logger.warning("Machine '{}' does not exist".format(fqdn))
        return

    # set needed values for several checks from original machine
    machine_ = Machine(
        architecture=machine.architecture
    )

    conn = None
    timer = None
    try:
        conn = SSH(fqdn)
        conn.connect()
        timer = threading.Timer(5 * 60, conn.close)
        timer.start()

        # CPUs
        logger.debug("Get CPU number...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_cpu_number.sh')
        if output:
            for line in output:
                if line.startswith('SOCKETS'):
                    machine_.cpu_physical = int(line.split('=')[1])
                elif line.startswith('CORES'):
                    machine_.cpu_cores = int(line.split('=')[1])
                elif line.startswith('THREADS'):
                    machine_.cpu_threads = int(line.split('=')[1])

        logger.debug("Get CPU type...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_cpu_type.sh')
        if output and output[0]:
            machine_.cpu_model = output[0].strip()

        logger.debug("Get CPU flags...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_cpu_flags.sh')
        if output and output[0]:
            machine_.cpu_flags = output[0].strip()

        logger.debug("Get CPU speed...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_cpu_speed.sh')
        if output and output[0]:
            machine_.cpu_speed = Decimal(int(output[0].strip()) / 1000000)

        logger.debug("Get CPU ID...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_cpu_id.sh')
        if output and output[0]:
            machine_.cpu_id = output[0].strip()

        # EFI
        logger.debug("Check for EFI...")
        try:
            efi_file = conn.get_file('/sys/firmware/efi', 'r')
            efi_file.close()
            machine_.efi = True
        except IOError:
            machine_.efi = False

        # Memory
        logger.debug("Get RAM amount...")
        for line in conn.read_file('/proc/meminfo'):
            if line.startswith('MemTotal'):
                machine_.ram_amount = int(int(line.split()[1]) / 1024)

        # Virtualization capability
        VM_HOST_MIN_RAM_MB = 7000
        machine_.vm_capable = False

        # Virtualization: x86
        logger.debug("Check for VM capability...")
        if machine_.architecture_id == Architecture.Type.X86_64:
            cpu_flags = machine_.cpu_flags
            if cpu_flags:
                cpu_flags = cpu_flags.upper()
                if ((cpu_flags.find('VMX') >= 0 or cpu_flags.find('SVM') >= 0) and
                        int(machine_.ram_amount) > VM_HOST_MIN_RAM_MB):
                    machine_.vm_capable = True

        # Virtualization: ppc64le
        if machine_.architecture_id == Architecture.Type.PPC64LE:
            for line in conn.read_file('/proc/cpuinfo'):
                if line.startswith('firmware') and 'OPAL' in line:
                    machine_.vm_capable = True

        # Disk
        logger.debug("Get disk information...")
        stdout, stderr, exitstatus = conn.execute('hwinfo --disk')
        for line in stdout:
            line = line.strip()
            if line.startswith('Size:'):
                machine_.disk_primary_size = int(int(line.split()[1]) / 2 / 1024 ** 2)
            elif line.startswith('Attached to:'):
                opening_bracket = line.find('(')
                closing_bracket = line.find(')')
                if opening_bracket > 0 and closing_bracket > 0:
                    machine_.disk_type = line[opening_bracket + 1:closing_bracket]
                else:
                    machine_.disk_type = 'Unknown disk type'
                break

        # lsmod
        logger.debug("Get 'lsmod'...")
        stdout, stderr, exitstatus = conn.execute('lsmod')
        machine_.lsmod = normalize_ascii("".join(stdout))

        # lspci
        logger.debug("Get 'lspci'...")
        stdout, stderr, exitstatus = conn.execute('lspci -vvv -nn')
        machine_.lspci = normalize_ascii("".join(stdout))

        # last
        logger.debug("Get 'last'...")
        output, stderr, exitstatus = conn.execute('last | grep -v reboot | head -n 1')
        string = ''.join(output)
        result = string[0:8] + string[38:49]
        machine_.last = normalize_ascii("".join(result))

        # hwinfo
        logger.debug("Get 'hwinfo' (full)...")
        stdout, stderr, exitstatus = conn.execute(
            'hwinfo --bios ' +
            '--block --bridge --cdrom --cpu --disk --floppy --framebuffer ' +
            '--gfxcard --hub --ide --isapnp --isdn --keyboard --memory ' +
            '--monitor --mouse --netcard --network --partition --pci --pcmcia ' +
            '--scsi --smp --sound --sys --tape --tv --usb --usb-ctrl --wlan'
        )
        machine_.hwinfo = normalize_ascii("".join(stdout))

        # dmidecode
        logger.debug("Get 'dmidecode'...")
        stdout, stderr, exitstatus = conn.execute('dmidecode')
        machine_.dmidecode = normalize_ascii("".join(stdout))

        # dmesg
        logger.debug("Get 'dmesg'...")
        stdout, stderr, exitstatus = conn.execute(
            'if [ -e /var/log/boot.msg ]; then ' +
            'cat /var/log/boot.msg; else journalctl -xl | head -n200; ' +
            'fi'
        )
        machine_.dmesg = normalize_ascii("".join(stdout))

        # lsscsi
        logger.debug("Get 'lsscsi'...")
        stdout, stderr, exitstatus = conn.execute('lsscsi -s')
        machine_.lsscsi = normalize_ascii("".join(stdout))

        # lsusb
        logger.debug("Get 'lsusb'...")
        stdout, stderr, exitstatus = conn.execute('lsusb')
        machine_.lsusb = normalize_ascii("".join(stdout))

        # IPMI
        logger.debug("Check for IPMI...")
        machine_.ipmi = machine_.dmidecode.find('IPMI') >= 0

        # Firmware script
        logger.debug("Get BIOS version...")
        output, stderr, exitstatus = conn.execute_script_remote('machine_get_firmware.sh')
        if output and output[0]:
            machine_.bios_version = output[0].strip()

        return machine_

    except Exception as e:
        logger.error("{} ({})".format(fqdn, e))
        return False
    finally:
        if conn:
            conn.close()
        if timer:
            timer.cancel()

    return None
示例#4
0
def get_status_ip(fqdn):
    """Retrieve information of the systems IPv4/IPv6 status."""
    try:
        machine = Machine.objects.get(fqdn=fqdn)
    except Machine.DoesNotExist:
        logger.warning("Machine '{}' does not exist".format(fqdn))
        return False

    machine_ = Machine()

    conn = None
    timer = None
    try:
        conn = SSH(machine.fqdn)
        conn.connect()
        timer = threading.Timer(5 * 60, conn.close)
        timer.start()

        logger.debug("Check IPv4/IPv6 status...")
        stdout, stderr, exitstatus = conn.execute('/sbin/ip a')

        devices = {}
        current_device = None
        addresses = {'inet': [], 'inet6': []}

        for line in stdout:
            match = re.match(r'^\d+:\s+([a-zA-Z0-9]+):\s+<.*>\s(.*)\n', line)
            if match:
                current_device = match.group(1)
                devices[current_device] = {
                    'mac_address': None,
                    'inet': None,
                    'inet6': None,
                    'flags': None
                }
                devices[current_device]['flags'] = match.group(2).split()
                continue

            line = line.lstrip()

            match = re.match(r'inet ([0-9.]{7,15})\/.*scope', line)
            if match:
                if devices[current_device]['inet'] is None:
                    devices[current_device]['inet'] = []
                devices[current_device]['inet'].append(match.group(1))
                continue

            match = re.match(r'inet6 ([a-f0-9:]*)\/[0-9]+ scope', line)
            if match:
                if devices[current_device]['inet6'] is None:
                    devices[current_device]['inet6'] = []
                devices[current_device]['inet6'].append(match.group(1))
                continue

            match = re.match('link/ether ([a-f0-9:]{17}) brd', line)
            if match:
                devices[current_device]['mac_address'] = match.group(1).upper()

        for device, values in devices.items():
            if values['mac_address'] is None:
                continue

            # ignore device if hooking up another
            if any(device in values['flags'] for device in devices.keys()):
                continue

            if values['mac_address'] == machine.mac_address:
                if values['inet'] is None:
                    machine_.status_ipv4 = Machine.StatusIP.AF_DISABLED
                elif machine.ipv4 not in values['inet']:
                    machine_.status_ipv4 = Machine.StatusIP.NO_ADDRESS
                    if [ipv4 for ipv4 in values['inet'] if not ipv4.startswith('127.0.0.1')]:
                        machine_.status_ipv4 = Machine.StatusIP.ADDRESS_MISMATCH
                elif machine.ipv4 in values['inet']:
                    machine_.status_ipv4 = Machine.StatusIP.CONFIRMED
                else:
                    machine_.status_ipv4 = Machine.StatusIP.MISSING

                if values['inet6'] is None:
                    machine_.status_ipv6 = Machine.StatusIP.AF_DISABLED
                elif machine.ipv6 not in values['inet6']:
                    machine_.status_ipv6 = Machine.StatusIP.NO_ADDRESS
                    if [ipv6 for ipv6 in values['inet6'] if not ipv6.startswith('fe80::')]:
                        machine_.status_ipv6 = Machine.StatusIP.ADDRESS_MISMATCH
                elif machine.ipv6 in values['inet6']:
                    machine_.status_ipv6 = Machine.StatusIP.CONFIRMED

            addresses['inet'].append(values['inet'])
            addresses['inet6'].append(values['inet6'])

        if machine_.status_ipv4 == Machine.StatusIP.NO_ADDRESS:
            if machine.ipv4 in addresses['inet']:
                machine_.status_ipv4 = Machine.StatusIP.MAC_MISMATCH

        if machine_.status_ipv6 == Machine.StatusIP.NO_ADDRESS:
            if machine.ipv6 in addresses['inet6']:
                machine_.status_ipv6 = Machine.StatusIP.MAC_MISMATCH

        return machine_

    except Exception as e:
        logger.error("{} ({})".format(fqdn, e))
        return False
    finally:
        if conn:
            conn.close()
        if timer:
            timer.cancel()

    return None
示例#5
0
    def create(self, *args, **kwargs):
        """
        Create a virtual machine.

        Method returns a new `Machine` object and calls the subclass to actually create the virtual
        machine physically.
        """
        from orthos2.data.models import (Architecture, Machine, RemotePower,
                                         SerialConsole, SerialConsoleType,
                                         System)
        from django.contrib.auth.models import User

        vm = Machine()
        vm.unsaved_networkinterfaces = []

        vm.architecture = Architecture.objects.get(name=kwargs['architecture'])
        vm.system = System.objects.get(pk=kwargs['system'])

        self._create(vm, *args, **kwargs)

        vm.mac_address = vm.unsaved_networkinterfaces[0].mac_address
        vm.check_connectivity = Machine.Connectivity.ALL
        vm.collect_system_information = True
        vm.save()

        for networkinterface in vm.unsaved_networkinterfaces[1:]:
            networkinterface.machine = vm
            networkinterface.save()
        vm.remotepower = RemotePower(fence_name="virsh")
        vm.remotepower.save()

        if self.host.has_serialconsole():
            stype = SerialConsoleType.objects.get(name='libvirt/qemu')
            if not stype:
                raise Exception("Bug: SerialConsoleType not found")
            vm.serialconsole = SerialConsole(stype=stype, baud_rate=115200)
            vm.serialconsole.save()

        if vm.vnc['enabled']:
            vm.annotations.create(text='VNC enabled: {}:{}'.format(
                self.host.fqdn, vm.vnc['port']),
                                  reporter=User.objects.get(username='******'))

        return vm