Esempio n. 1
0
def machine_interface_create(id):
    machine = Machine.query.get(id)
    if not machine:
        flash("Machine does not exist", "error")
        return redirect(url_for('.get_machines_admin'))

    if not machine.check_permission(g.user, 'admin'):
        flash('Permission denied', 'error')
        return redirect(url_for('.get_machines_admin'))

    form = validations.InterfaceForm(request.form)
    if form.validate():
        new_intf = Interface(identifier=form.identifier.data,
                             mac=form.mac.data,
                             dhcpv4=True,
                             reserved_ipv4=form.reserved_ipv4.data,
                             machine_id=machine.id)
        db.session.add(new_intf)
        try:
            db.session.commit()
            flash('Interface added successfully', 'success')
        except IntegrityError as e:
            db.session.rollback()
            flash('Integrity Error: either MAC or reserved IP not unique', 'error')
            return redirect(url_for('.machine_admin', id=machine.id))
    else:
        flash_form_errors(form)

    return redirect(url_for('.machine_admin', id=machine.id))
Esempio n. 2
0
def create_machines_admin():
    logger.info("Machine created by %s" % g.user.username)

    if not g.user.admin:
        flash('Permission denied', 'error')
        return redirect(url_for('.get_machines_admin'))

    logger.info("Machine added by %s" % g.user.username)
    form = validations.CreateMachineForm(request.form)
    validations.CreateMachineForm.populate_choices(form, g)
    if form.validate():
        # XXX: Think about adding a new object for PDU and Serial

        if form.bmc_id.data:
            bmc = BMC.query.get(form.bmc_id.data)
            if bmc is None:
                flash('BMC with id=%d does not exist' % form.bmc_id.data)
                return redirect(url_for('.get_machines_admin'))

            try:
                bmc.type_inst.validate_bmc_info(form.bmc_info.data)
            except BMCError as e:
                flash(str(e), 'error')
                return redirect(url_for('.get_machines_admin'))

        new_machine = Machine(name=form.name.data,
                              bmc_id=form.bmc_id.data,
                              bmc_info=form.bmc_info.data,
                              pdu=form.pdu.data,
                              pdu_port=form.pdu_port.data,
                              serial=form.serial.data,
                              serial_port=form.serial_port.data,
                              netboot_enabled=False)
        db.session.add(new_machine)
        try:
            db.session.commit()
            flash('Machine added successfully', 'success')
        except IntegrityError as e:
            db.session.rollback()
            flash('Integrity Error: either name or MAC are not unique', 'error')
            return redirect(url_for('.get_machines_admin'))

        db.session.refresh(new_machine)

        for mac_field in form.macs:
            mac = mac_field.data
            if mac and mac != '':
                new_interface = Interface(machine_id=new_machine.id, mac=mac)
                db.session.add(new_interface)
                try:
                    db.session.commit()
                except IntegrityError as e:
                    db.session.rollback()
                    flash('Integrity Error: failed to add mac: %s' % mac, 'error')

    else:
        flash_form_errors(form)

    return redirect(url_for('.get_machines_admin'))
Esempio n. 3
0
def valid_interface_1(db, valid_plain_machine, valid_network):
    interface = Interface(mac='00:11:22:33:44:55',
                          machine_id=valid_plain_machine.id,
                          network_id=valid_network.id)
    db.session.add(interface)
    db.session.commit()
    db.session.refresh(interface)

    return interface
Esempio n. 4
0
def upgrade():
    bind = op.get_bind()
    session = Session(bind=bind)

    s = sa.sql.text('SELECT id, mac FROM machine').\
        columns(id=sa.Integer, mac=sa.String)
    for id, mac in session.execute(s):
        if mac and mac != '':
            intf = Interface(machine_id=id, mac=mac)
            session.add(intf)

    session.commit()
Esempio n. 5
0
def subnet():
    data = request.get_json(force=True)
    try:
        data = subnet_schema.validate(data)
    except SchemaError as e:
        return str(e), 400

    hwaddr = data['mac']
    if not hwaddr:
        abort(400)

    interface = Interface.by_mac(hwaddr)
    if not interface:
        abort(404)

    if not interface.network:
        abort(404)

    use_static = True if interface.static_ipv4 else False
    use_reserved = True if not use_static and interface.reserved_ipv4 else False

    expected_pool = None
    if use_reserved:
        expected_pool = ipaddress.IPv4Network(interface.network.reserved_net)

    logger.info('expected_pool: %s' % expected_pool)

    if expected_pool is None:
        return jsonify({'subnetId': None}), 200

    response = {}

    for subnet in data['subnets']:
        net = ipaddress.IPv4Network((subnet['prefix'], subnet['prefixLen']), strict=False)
        if not net.overlaps(ipaddress.IPv4Network(interface.network.subnet)):
            continue

        pool_matches = reduce(lambda r, p: r or p['firstIP'] in expected_pool, subnet['pools'], False)
        if pool_matches:
            response['subnetId'] = subnet['subnetId']
            logger.info('matched subnet: %s' % subnet)
            break

    return jsonify(response), 200
Esempio n. 6
0
def index():
    hwaddr = request.args.get('hwaddr')
    if not hwaddr:
        abort(400)

    machine = Machine.by_mac(hwaddr)
    if not machine:
        abort(404)

    interface = Interface.by_mac(hwaddr)
    if not interface:
        abort(404)

    # query param ?hwaddr=
    # response:
    # {
    #   "ipv4": "",
    #   "next-server": "",
    #   "options": [
    #     { "option": number, "value": "" }
    #   ]
    # }
    # option 67 is bootfile
    data = {
        'options': []
    }

    if machine.netboot_enabled:
        bootloader_image = machine.bootloader
        bootfile = bootloader_image.filename if bootloader_image else app.config['DHCP_DEFAULT_BOOTFILE']

        data['next-server'] = app.config['DHCP_TFTP_PROXY_HOST']
        data['options'].append({'option': 67, 'value': bootfile})

    use_static = True if interface.static_ipv4 else False

    if interface.reserved_ipv4 and not use_static:
        data['ipv4'] = interface.reserved_ipv4

    return jsonify(data), 200
Esempio n. 7
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