コード例 #1
0
    def _lookup(self, table, record):
        if record == "":
            raise TypeError("Cannot look up record by empty string")

        # Handle commands by simply returning its result
        if isinstance(record, cmd.BaseCommand):
            return record.result

        t = self.tables[table]
        if isinstance(record, uuid.UUID):
            try:
                return t.rows[record]
            except KeyError:
                raise idlutils.RowNotFound(table=table,
                                           col='uuid',
                                           match=record) from None
        try:
            uuid_ = uuid.UUID(record)
            return t.rows[uuid_]
        except ValueError:
            # Not a UUID string, continue lookup by other means
            pass
        except KeyError:
            # If record isn't found by UUID , go ahead and look up by the table
            pass

        if not self.lookup_table:
            raise idlutils.RowNotFound(table=table, col='record', match=record)
        # NOTE (twilson) This is an approximation of the db-ctl implementation
        # that allows a partial table, assuming that if a table has a single
        # index, that we should be able to do a lookup by it.
        rl = self.lookup_table.get(
            table, idlutils.RowLookup(table, idlutils.get_index_column(t),
                                      None))
        # no table means uuid only, no column means lookup table has one row
        if rl.table is None:
            raise idlutils.RowNotFound(table=table, col='uuid', match=record)
        if rl.column is None:
            if t.max_rows == 1:
                return next(iter(t.rows.values()))
            raise idlutils.RowNotFound(table=table, col='uuid', match=record)
        row = idlutils.row_by_value(self, rl.table, rl.column, record)
        if rl.uuid_column:
            rows = getattr(row, rl.uuid_column)
            if len(rows) != 1:
                raise idlutils.RowNotFound(table=table,
                                           col='record',
                                           match=record)
            row = rows[0]
        return row
コード例 #2
0
ファイル: command.py プロジェクト: otherwiseguy/ovsdbapp
    def run_idl(self, txn):
        table_schema = self.api._tables[self.table]
        idx = idlutils.get_index_column(table_schema)
        columns = self.columns or list(table_schema.columns.keys()) + ['_uuid']
        # If there's an index for this table, we'll fetch all columns and
        # remove the unwanted ones based on self.records. Otherwise, let's try
        # to get the uuid of the wanted ones which is an O(n^2) operation.
        if not idx and self.records:
            rows = []
            for record in self.records:
                try:
                    rows.append(self.api.idl.lookup(self.table, record))
                except idlutils.RowNotFound:
                    if self.if_exists:
                        continue
                    raise
        else:
            rows = table_schema.rows.values()

        def _match(row):
            elem = getattr(row, idx)
            return elem in self.records

        def _match_remove(row):
            elem = getattr(row, idx)
            found = elem in self.records
            if found:
                records_found.remove(elem)
            return found

        def _match_true(row):
            return True

        records_found = []
        if idx and self.records:
            if self.if_exists:
                match = _match
            else:
                # If we're using the approach of removing the unwanted
                # elements, we'll use a helper list to remove elements as we
                # find them in the DB contents. This will help us identify
                # quickly if there's some record missing to raise a RowNotFound
                # exception later.
                records_found = list(self.records)
                match = _match_remove
        else:
            match = _match_true

        self.result = [
            rowview.RowView(row) if self.row else {
                c: idlutils.get_column_value(row, c)
                for c in columns
            }
            for row in rows if match(row)
        ]

        if records_found:
            raise idlutils.RowNotFound(table=self.table, col=idx,
                                       match=records_found[0])
コード例 #3
0
    def _get_subnet(self):
        for dhcp in self.api._tables['DHCP_Options'].rows.values():
            ext_ids = getattr(dhcp, 'external_ids', {})
            # Ignore ports DHCP Options
            if ext_ids.get('port_id'):
                continue
            if ext_ids.get('subnet_id') == self.name:
                return dhcp

        raise idlutils.RowNotFound(
            table='DHCP_Options', col='external_ids', match=self.name)
コード例 #4
0
ファイル: commands.py プロジェクト: Eliav2/ovsdbapp
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     found = False
     for nat in [r for r in lr.nat
                 if idlutils.row_match(r, self.conditions)]:
         found = True
         lr.delvalue('nat', nat)
         nat.delete()
         if self.match_ip:
             break
     if self.match_ip and not (found or self.if_exists):
         raise idlutils.RowNotFound(table='NAT', col=self.col,
                                    match=self.match_ip)
コード例 #5
0
    def _get_floatingip(self):
        # TODO(lucasagomes): We can't use self.api.lookup() because that
        # method does not introspect map type columns. We could either:
        # 1. Enhance it to look into maps or, 2. Add a new ``name`` column
        # to the NAT table so that we can use lookup() just like we do
        # for other resources
        for nat in self.api._tables['NAT'].rows.values():
            if nat.type != 'dnat_and_snat':
                continue
            ext_ids = getattr(nat, 'external_ids', {})
            if ext_ids.get(ovn_const.OVN_FIP_EXT_ID_KEY) == self.name:
                return nat

        raise idlutils.RowNotFound(
            table='NAT', col='external_ids', match=self.name)
コード例 #6
0
ファイル: commands.py プロジェクト: Eliav2/ovsdbapp
 def run_idl(self, txn):
     try:
         lb = self.api.lookup('Load_Balancer', self.lb)
     except idlutils.RowNotFound:
         if not self.if_exists:
             raise
         return
     if self.vip:
         if self.vip in lb.vips:
             lb.delkey('vips', self.vip)
         elif not self.if_exists:
             raise idlutils.RowNotFound(table='Load_Balancer', col=self.vip,
                                        match=self.lb)
     # Remove load balancer if vips were not provided or no vips are left.
     if not self.vip or not lb.vips:
         lb.delete()
コード例 #7
0
    def _get_floatingip_or_pf(self):
        # TYPE_FLOATINGIPS: Determine table to use based on name.
        # Floating ip port forwarding resources are kept in load
        # balancer table and have a well known name.
        if self.name.startswith(PORT_FORWARDING_PREFIX):
            return self.api.lookup('Load_Balancer', self.name)

        # TODO(lucasagomes): We can't use self.api.lookup() because that
        # method does not introspect map type columns. We could either:
        # 1. Enhance it to look into maps or, 2. Add a new ``name`` column
        # to the NAT table so that we can use lookup() just like we do
        # for other resources
        for nat in self.api._tables['NAT'].rows.values():
            if nat.type != 'dnat_and_snat':
                continue
            ext_ids = getattr(nat, 'external_ids', {})
            if ext_ids.get(ovn_const.OVN_FIP_EXT_ID_KEY) == self.name:
                return nat

        raise idlutils.RowNotFound(table='NAT',
                                   col='external_ids',
                                   match=self.name)