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))
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'))
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
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()
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
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
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