Example #1
0
    def report(undef):
        if undef._undefined_hint is None:
            if undef._undefined_obj is jinja2.utils.missing:
                hint = '%s is undefined' % undef._undefined_name
            else:
                hint = '%s has no attribute %s' % (
                    jinja2.utils.object_type_repr(
                        undef._undefined_obj), undef._undefined_name)
        else:
            hint = undef._undefined_hint

        MachineEvent.preseed_error(machine.id, None, request.remote_addr, hint)
Example #2
0
def handle_config_request(client_ip, filename):
    m = re.search(MAC_FILE_REGEX, filename)
    machine = Machine.by_mac(m.group(1).replace('-', ':').lower()) if m else None

    use_def_config = any(re.search(regex, filename) for regex in DEFAULT_FILE_REGEXES)

    if machine:
        MachineEvent.tftp_request(machine.id, None, filename)

    if machine or use_def_config:
        return render_config(is_pxelinux_path(filename), machine)
    else:
        return None
Example #3
0
def machine_state_put(id):
    data = request.get_json(force=True)
    data = machine_state_put_schema.validate(data)

    machine = Machine.query.get(id)
    if not machine:
        raise InvalidUsage('machine not found', status_code=404)

    if not machine.check_permission(g.user, 'assignee'):
        return '', 403

    machine.state = data['state']
    db.session.commit()
    db.session.refresh(machine)

    MachineEvent.state_changed(machine.id, g.user, machine.state, "api")

    return jsonify({'state': machine.state}), 200
Example #4
0
def machine_power_post(id):
    data = request.get_json(force=True)
    data = machine_power_schema.validate(data)

    machine = Machine.query.get(id)
    if not machine:
        raise InvalidUsage('machine not found', status_code=404)

    if not machine.check_permission(g.user, 'assignee'):
        return '', 403

    if not machine.bmc:
        raise InvalidUsage('power state changes require a BMC', status_code=400)

    machine.set_power(data['state'])

    MachineEvent.power_changed(machine.id, g.user, data['state'])

    return '', 202
Example #5
0
def seen():
    data = request.get_json(force=True)
    try:
        seen_schema.validate(data)
    except SchemaError as e:
        return str(e), 400

    interface = Interface.by_mac(data['mac'])
    if interface:
        # Already assigned, don't care - but log an event
        MachineEvent.dhcp_request(interface.machine.id, None, discover=data['discover'])
        return "", 200

    options = {o['option']: o['value'] for o in data['options']}

    info = {}

    info['mac_vendor'] = mac_vendor(data['mac'])

    if 12 in options:
        # hostname option
        info['hostname'] = options[12]

    if 93 in options:
        # processor architecture as per rfc4578
        code = options[93]
        info['arch_code'] = code
        info['arch'] = DHCP_ARCH_CODES.get(code, 'unknown')

    discovered_mac = DiscoveredMAC.by_mac(data['mac'])
    if discovered_mac:
        discovered_mac.info = info
        discovered_mac.last_seen = datetime.utcnow()
        db.session.commit()
    else:
        discovered_mac = DiscoveredMAC(mac=data['mac'], info=info)
        db.session.add(discovered_mac)
        db.session.commit()

    return "", 202
Example #6
0
def machine_state_post(id):
    data = request.get_json(force=True)
    data = machine_state_post_schema.validate(data)

    machine = Machine.query.get(id)
    if not machine:
        raise InvalidUsage('machine not found', status_code=404)

    if not machine.check_permission(g.user, 'assignee'):
        return '', 403

    if data['state'] == 'provision':
        if not machine.bmc:
            raise InvalidUsage('provisioning requires a BMC', status_code=400)

        if not machine.kernel:
            raise InvalidUsage('provisioning requires a kernel', status_code=400)

        if not machine.subarch:
            raise InvalidUsage('provisioning requires a subarch', status_code=400)

        if not machine.subarch.bootloader:
            raise InvalidUsage('provisioning requires the subarch to have a bootloader', status_code=400)

        machine.netboot_enabled = True
        machine.state = 'provisioning'
        db.session.commit()
        db.session.refresh(machine)

        machine.set_power('pxe_reboot')

        MachineEvent.state_changed(machine.id, g.user, machine.state, "api")
    else:
        return '', 400

    return jsonify({'state': machine.state}), 202
Example #7
0
def get_preseed(machine_id):
    machine = Machine.query.get(machine_id)
    if not machine:
        return "", 404

    preseed = machine.preseed
    if not preseed:
        return "", 404

    MachineEvent.preseed_accessed(machine.id, None, request.remote_addr)

    assignees = machine.assignees

    ssh_key = assignees[0].ssh_key if len(assignees) > 0 else ''
    ssh_keys = [u.ssh_key for u in assignees]

    interfaces = [
        PInterface(name=i.identifier,
                   static_ipv4=i.static_ipv4,
                   prefix=i.network.prefix,
                   netmask=i.network.netmask) for i in machine.interfaces
        if i.static_ipv4
    ]

    kernel = None
    if machine.kernel:
        kernel = PImage(filename=machine.kernel.filename,
                        description=machine.kernel.description,
                        known_good=machine.kernel.known_good)
    initrd = None
    if machine.initrd:
        initrd = PImage(filename=machine.initrd.filename,
                        description=machine.initrd.description,
                        known_good=machine.initrd.known_good)

    try:
        template = jinja2.Template(preseed.file_content,
                                   undefined=make_reporting_undefined(
                                       machine, request))

        return Response(template.render(ssh_key=ssh_key,
                                        ssh_keys=ssh_keys,
                                        hostname=machine.hostname,
                                        interfaces=interfaces,
                                        kernel=kernel,
                                        initrd=initrd),
                        mimetype='text/plain')
    except jinja2.TemplateSyntaxError as e:
        MachineEvent.preseed_error(machine.id, None, request.remote_addr,
                                   e.message, e.lineno)
    except jinja2.TemplateError as e:
        MachineEvent.preseed_error(machine.id, None, request.remote_addr,
                                   e.message)