def run_idl(self, txn): try: port = idlutils.row_by_value(self.api.idl, 'Port', 'name', self.port) except idlutils.RowNotFound: if self.if_exists: return msg = _("Port %s does not exist") % self.port raise RuntimeError(msg) if self.bridge: br = idlutils.row_by_value(self.api.idl, 'Bridge', 'name', self.bridge) else: br = next(b for b in self.api._tables['Bridge'].rows.values() if port in b.ports) if port.uuid not in br.ports and not self.if_exists: # TODO(twilson) Make real errors across both implementations msg = _("Port %(port)s does not exist on %(bridge)s!") % { 'port': self.name, 'bridge': self.bridge } LOG.error(msg) raise RuntimeError(msg) br.verify('ports') ports = br.ports ports.remove(port) br.ports = ports # Also remove port/interface directly for indexing? port.verify('interfaces') for iface in port.interfaces: self.api._tables['Interface'].rows[iface.uuid].delete() self.api._tables['Port'].rows[port.uuid].delete()
def row_by_record(idl_, table, record): t = idl_.tables[table] try: if isinstance(record, uuid.UUID): return t.rows[record] uuid_ = uuid.UUID(record) return t.rows[uuid_] except ValueError: # Not a UUID string, continue lookup by other means pass except KeyError: raise exceptions.RowNotFound(table=table, col='uuid', match=record) rl = _LOOKUP_TABLE.get(table, RowLookup(table, get_index_column(t), None)) # no table means uuid only, no column is just SSL which we don't need if rl.table is None: raise ValueError(_("Table %s can only be queried by UUID") % table) if rl.column is None: raise NotImplementedError(_("'.' searches are not implemented")) row = row_by_value(idl_, rl.table, rl.column, record) if rl.uuid_column: rows = getattr(row, rl.uuid_column) if len(rows) != 1: raise exceptions.RowNotFound( table=table, col=_('record'), match=record) row = rows[0] return row
def run_idl(self, txn): table_schema = self.api._tables[self.table] columns = self.columns or list(table_schema.columns.keys()) + ['_uuid'] if self.records: row_uuids = [] for record in self.records: try: row_uuids.append(idlutils.row_by_record( self.api.idl, self.table, record).uuid) except idlutils.RowNotFound: if self.if_exists: continue # NOTE(kevinbenton): this is converted to a RuntimeError # for compat with the vsctl version. It might make more # sense to change this to a RowNotFoundError in the future. raise RuntimeError(_( "Row doesn't exist in the DB. Request info: " "Table=%(table)s. Columns=%(columns)s. " "Records=%(records)s.") % { "table": self.table, "columns": self.columns, "records": self.records, }) else: row_uuids = table_schema.rows.keys() self.result = [ { c: idlutils.get_column_value(table_schema.rows[uuid], c) for c in columns } for uuid in row_uuids ]
def get_schema_helper(connection, schema_name): err, strm = stream.Stream.open_block( stream.Stream.open(connection)) if err: raise Exception(_("Could not connect to %s") % connection) rpc = jsonrpc.Connection(strm) req = jsonrpc.Message.create_request('get_schema', [schema_name]) err, resp = rpc.transact_block(req) rpc.close() if err: raise Exception(_("Could not retrieve schema from %(conn)s: " "%(err)s") % {'conn': connection, 'err': os.strerror(err)}) elif resp.error: raise Exception(resp.error) return idl.SchemaHelper(None, resp.result)
class OvsDbFrontendException(Exception): """Base Exception To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") def __init__(self, **kwargs): try: super(OvsDbFrontendException, self).__init__(self.message % kwargs) self.msg = self.message % kwargs except Exception: with excutils.save_and_reraise_exception() as ctxt: if not self.use_fatal_exceptions(): ctxt.reraise = False # at least get the core message out if something happened super(OvsDbFrontendException, self).__init__(self.message) if six.PY2: def __unicode__(self): return unicode(self.msg) def __str__(self): return self.msg def use_fatal_exceptions(self): return False
def run_idl(self, txn): table_schema = self.api._tables[self.table] columns = self.columns or list(table_schema.columns.keys()) + ['_uuid'] if self.records: row_uuids = [] for record in self.records: try: row_uuids.append( idlutils.row_by_record(self.api.idl, self.table, record).uuid) except idlutils.RowNotFound: if self.if_exists: continue # NOTE(kevinbenton): this is converted to a RuntimeError # for compat with the vsctl version. It might make more # sense to change this to a RowNotFoundError in the future. raise RuntimeError( _("Row doesn't exist in the DB. Request info: " "Table=%(table)s. Columns=%(columns)s. " "Records=%(records)s.") % { "table": self.table, "columns": self.columns, "records": self.records, }) else: row_uuids = table_schema.rows.keys() self.result = [{ c: idlutils.get_column_value(table_schema.rows[uuid], c) for c in columns } for uuid in row_uuids]
def _delete_acls(self, lswitch_name, acls, acls_delete): for acl_delete in acls_delete: try: acls.remove(acl_delete) except ValueError: msg = _("Logical Switch %s missing acl") % lswitch_name raise RuntimeError(msg) acl_delete.delete()
def delete_lport(self, lport_name=None, lswitch=None, ext_id=None, if_exists=True): if lport_name is not None: return cmd.DelLogicalPortCommand(self, lport_name, lswitch, if_exists) else: raise RuntimeError(_("Currently only supports " "delete by lport-name"))
def wait_for_change(_idl, timeout, seqno=None): if seqno is None: seqno = _idl.change_seqno stop = time.time() + timeout while _idl.change_seqno == seqno and not _idl.run(): ovs_poller = poller.Poller() _idl.wait(ovs_poller) ovs_poller.timer_wait(timeout * 1000) ovs_poller.block() if time.time() > stop: raise Exception(_("Timeout"))
def run_idl(self, txn): try: port = idlutils.row_by_value(self.api.idl, 'Logical_Port', 'name', self.lport) except idlutils.RowNotFound: msg = _("Logical Port %s does not exist") % self.lport raise RuntimeError(msg) options = {'router-port': self.lrouter_port} setattr(port, 'options', options) setattr(port, 'type', 'router')
def run_idl(self, txn): try: lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.name) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Switch %s does not exist") % self.name raise RuntimeError(msg) self.api._tables['Logical_Switch'].rows[lswitch.uuid].delete()
def run_idl(self, txn): try: port = idlutils.row_by_value(self.api.idl, 'Logical_Port', 'name', self.lport) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Port %s does not exist") % self.lport raise RuntimeError(msg) for col, val in self.columns.items(): setattr(port, col, val)
def run_idl(self, txn): try: lrouter_port = idlutils.row_by_value(self.api.idl, 'Logical_Router_Port', 'name', self.name) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Router Port %s does not exist") % self.name raise RuntimeError(msg) try: lrouter = idlutils.row_by_value(self.api.idl, 'Logical_Router', 'name', self.lrouter) except idlutils.RowNotFound: msg = _("Logical Router %s does not exist") % self.lrouter raise RuntimeError(msg) lrouter.verify('ports') lrouter_ports = getattr(lrouter, 'ports', []) if (lrouter_port in lrouter_ports): lrouter_ports.remove(lrouter_port) setattr(lrouter, 'ports', lrouter_ports)
def run_idl(self, txn): try: lrouter = idlutils.row_by_value(self.api.idl, 'Logical_Router', 'name', self.name, None) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Router %s does not exist") % self.name raise RuntimeError(msg) if lrouter: for col, val in self.columns.items(): setattr(lrouter, col, val) return
def run_idl(self, txn): try: lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.lswitch) except idlutils.RowNotFound: msg = _("Logical Switch %s does not exist") % self.lswitch raise RuntimeError(msg) row = txn.insert(self.api._tables['ACL']) for col, val in self.columns.items(): setattr(row, col, val) row.external_ids = {'neutron:lport': self.lport} lswitch.verify('acls') acls = getattr(lswitch, 'acls', []) acls.append(row.uuid) setattr(lswitch, 'acls', acls)
def run_idl(self, txn): try: lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.name) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Switch %s does not exist") % self.name raise RuntimeError(msg) lswitch.verify('external_ids') external_ids = getattr(lswitch, 'external_ids', {}) external_ids[self.field] = self.value lswitch.external_ids = external_ids
def run_idl(self, txn): try: lport = idlutils.row_by_value(self.api.idl, 'Logical_Port', 'name', self.lport) lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.lswitch) ports = getattr(lswitch, 'ports', []) except idlutils.RowNotFound: if self.if_exists: return msg = _("Port %s does not exist") % self.lport raise RuntimeError(msg) lswitch.verify('ports') ports.remove(lport) setattr(lswitch, 'ports', ports) self.api._tables['Logical_Port'].rows[lport.uuid].delete()
def do_commit(self): start_time = time.time() attempts = 0 while True: elapsed_time = time.time() - start_time if attempts > 0 and elapsed_time > self.timeout: raise RuntimeError("OVS transaction timed out") attempts += 1 # TODO(twilson) Make sure we don't loop longer than vsctl_timeout txn = idl.Transaction(self.api.idl) for i, command in enumerate(self.commands): LOG.debug("Running txn command(idx=%(idx)s): %(cmd)s", { 'idx': i, 'cmd': command }) try: command.run_idl(txn) except Exception: with excutils.save_and_reraise_exception() as ctx: txn.abort() if not self.check_error: ctx.reraise = False seqno = self.api.idl.change_seqno status = txn.commit_block() if status == txn.TRY_AGAIN: LOG.debug("OVSDB transaction returned TRY_AGAIN, retrying") idlutils.wait_for_change(self.api.idl, self.timeout - elapsed_time, seqno) continue elif status == txn.ERROR: msg = _("OVSDB Error: %s") % txn.get_error() if self.log_errors: LOG.error(msg) if self.check_error: # For now, raise similar error to vsctl/utils.execute() raise RuntimeError(msg) return elif status == txn.ABORTED: LOG.debug("Transaction aborted") return elif status == txn.UNCHANGED: LOG.debug("Transaction caused no change") return [cmd.result for cmd in self.commands]
def do_commit(self): start_time = time.time() attempts = 0 while True: elapsed_time = time.time() - start_time if attempts > 0 and elapsed_time > self.timeout: raise RuntimeError("OVS transaction timed out") attempts += 1 # TODO(twilson) Make sure we don't loop longer than vsctl_timeout txn = idl.Transaction(self.api.idl) for i, command in enumerate(self.commands): LOG.debug("Running txn command(idx=%(idx)s): %(cmd)s", {'idx': i, 'cmd': command}) try: command.run_idl(txn) except Exception: with excutils.save_and_reraise_exception() as ctx: txn.abort() if not self.check_error: ctx.reraise = False seqno = self.api.idl.change_seqno status = txn.commit_block() if status == txn.TRY_AGAIN: LOG.debug("OVSDB transaction returned TRY_AGAIN, retrying") idlutils.wait_for_change( self.api.idl, self.timeout - elapsed_time, seqno) continue elif status == txn.ERROR: msg = _("OVSDB Error: %s") % txn.get_error() if self.log_errors: LOG.error(msg) if self.check_error: # For now, raise similar error to vsctl/utils.execute() raise RuntimeError(msg) return elif status == txn.ABORTED: LOG.debug("Transaction aborted") return elif status == txn.UNCHANGED: LOG.debug("Transaction caused no change") return [cmd.result for cmd in self.commands]
def run_idl(self, txn): try: br = idlutils.row_by_value(self.api.idl, 'Bridge', 'name', self.name) except idlutils.RowNotFound: if self.if_exists: return else: msg = _("Bridge %s does not exist") % self.name LOG.error(msg) raise RuntimeError(msg) self.api._ovs.verify('bridges') for port in br.ports: cmd = DelPortCommand(self.api, port.name, self.name, if_exists=True) cmd.run_idl(txn) bridges = self.api._ovs.bridges bridges.remove(br) self.api._ovs.bridges = bridges self.api._tables['Bridge'].rows[br.uuid].delete()
def run_idl(self, txn): try: lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.lswitch) except idlutils.RowNotFound: if self.if_exists: return msg = _("Logical Switch %s does not exist") % self.lswitch raise RuntimeError(msg) lswitch.verify('acls') acls_to_del = [] acls = getattr(lswitch, 'acls', []) for acl in acls: ext_ids = getattr(acl, 'external_ids', {}) if ext_ids.get('neutron:lport') == self.lport: acls_to_del.append(acl) for acl in acls_to_del: acls.remove(acl) acl.delete() setattr(lswitch, 'acls', acls)
def run_idl(self, txn): try: lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.lswitch) ports = getattr(lswitch, 'ports', []) except idlutils.RowNotFound: msg = _("Logical Switch %s does not exist") % self.lswitch raise RuntimeError(msg) if self.may_exist: port = idlutils.row_by_value(self.api.idl, 'Logical_Port', 'name', self.lport, None) if port: return lswitch.verify('ports') port = txn.insert(self.api._tables['Logical_Port']) port.name = self.lport for col, val in self.columns.items(): setattr(port, col, val) # add the newly created port to existing lswitch ports.append(port.uuid) setattr(lswitch, 'ports', ports)
def run_idl(self, txn): try: lrouter = idlutils.row_by_value(self.api.idl, 'Logical_Router', 'name', self.lrouter) except idlutils.RowNotFound: msg = _("Logical Router %s does not exist") % self.lrouter raise RuntimeError(msg) try: idlutils.row_by_value(self.api.idl, 'Logical_Router_Port', 'name', self.name) # TODO(chandrav) This might be a case of multiple prefixes # on the same port. yet to figure out if and how OVN needs # to cater to this case except idlutils.RowNotFound: lrouter_port = txn.insert(self.api._tables['Logical_Router_Port']) lrouter_port.name = self.name for col, val in self.columns.items(): setattr(lrouter_port, col, val) lrouter.verify('ports') lrouter_ports = getattr(lrouter, 'ports', []) if lrouter_port not in lrouter_ports: lrouter_ports.append(lrouter_port) setattr(lrouter, 'ports', lrouter_ports)
class RowNotFound(OvsDbFrontendException): message = _("Cannot find %(table)s with %(col)s=%(match)s")
ovsdb_interface_map = { 'vsctl': 'ovsdb_frontend.impl.OvsdbVsctl', 'native': 'ovsdb_frontend.impl.OvsdbIdl', } ovndb_interface_map = { 'native': 'ovsdb_frontend.impl.OvndbIdl' } # Default timeout for ovs-vsctl command DEFAULT_OVS_VSCTL_TIMEOUT = 10 ovs_opts = [ cfg.StrOpt('ovsdb_interface', choices=ovsdb_interface_map.keys(), default='vsctl', help=_('The interface for interacting with the OVSDB')), cfg.StrOpt('ovsdb_connection', default='tcp:127.0.0.1:6640', help=_('The connection string for the native OVSDB backend. ' 'Requires the native ovsdb_interface to be enabled.')), cfg.IntOpt('ovs_vsctl_timeout', default=DEFAULT_OVS_VSCTL_TIMEOUT, help=_('Timeout in seconds for ovs-vsctl commands. ' 'If the timeout expires, ovs commands will fail with ' 'ALARMCLOCK error.')) ] cfg.CONF.register_opts(ovs_opts, 'OVS') ovn_opts = [ cfg.StrOpt('ovsdb_connection', default='tcp:127.0.0.1:6640',
from oslo_ovsdb_frontend._i18n import _ # NOTE: These classes are still missing from the source code tree ovsdb_interface_map = { 'vsctl': 'ovsdb_frontend.impl.OvsdbVsctl', 'native': 'ovsdb_frontend.impl.OvsdbIdl', } ovndb_interface_map = {'native': 'ovsdb_frontend.impl.OvndbIdl'} # Default timeout for ovs-vsctl command DEFAULT_OVS_VSCTL_TIMEOUT = 10 ovs_opts = [ cfg.StrOpt('ovsdb_interface', choices=ovsdb_interface_map.keys(), default='vsctl', help=_('The interface for interacting with the OVSDB')), cfg.StrOpt('ovsdb_connection', default='tcp:127.0.0.1:6640', help=_('The connection string for the native OVSDB backend. ' 'Requires the native ovsdb_interface to be enabled.')), cfg.IntOpt('ovs_vsctl_timeout', default=DEFAULT_OVS_VSCTL_TIMEOUT, help=_('Timeout in seconds for ovs-vsctl commands. ' 'If the timeout expires, ovs commands will fail with ' 'ALARMCLOCK error.')) ] cfg.CONF.register_opts(ovs_opts, 'OVS') ovn_opts = [ cfg.StrOpt('ovsdb_connection', default='tcp:127.0.0.1:6640',
def delete_lswitch(self, lswitch_name=None, ext_id=None, if_exists=True): if lswitch_name is not None: return cmd.DelLSwitchCommand(self, lswitch_name, if_exists) else: raise RuntimeError(_("Currently only supports delete " "by lswitch-name"))