Exemplo n.º 1
0
 def extid_qos_map(self, port_uuid):
     for qos in self._ovn_nb.tables[self.TYPE].rows.values():
         # TODO(ralonsoh): in "external_ids", add the FIP ID or the port
         #                 ID; that will speed up the search without
         #                 using regex.
         qos_row = rowview.RowView(qos)
         match = self.REGEX_ID.search(qos_row.match)
         if match:
             if port_uuid == match.group('id'):
                 yield rowview.RowView(qos)
Exemplo n.º 2
0
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     if self.logical_port:
         lp = self.api.lookup('Logical_Switch_Port', self.logical_port)
     for nat in lr.nat:
         if ((self.nat_type, self.external_ip, self.logical_ip) ==
                 (nat.type, nat.external_ip, nat.logical_ip)):
             if self.may_exist:
                 nat.logical_port = self.logical_port
                 nat.external_mac = self.external_mac
                 self.result = rowview.RowView(nat)
                 return
             raise RuntimeError("NAT already exists")
     nat = txn.insert(self.api.tables['NAT'])
     nat.type = self.nat_type
     nat.external_ip = self.external_ip
     nat.logical_ip = self.logical_ip
     if self.logical_port:
         # It seems kind of weird that ovn uses a name string instead of
         # a ref to a LSP, especially when ovn-nbctl looks the value up by
         # either name or uuid (and discards the result and store the name).
         nat.logical_port = lp.name
         nat.external_mac = self.external_mac
     lr.addvalue('nat', nat)
     self.result = nat.uuid
Exemplo n.º 3
0
 def run_idl(self, txn):
     self.result = [
         rowview.RowView(r) if self.row else
         {c: idlutils.get_column_value(r, c)
          for c in self.columns} for r in self.table.rows.values()
         if idlutils.row_match(r, self.conditions)
     ]
Exemplo n.º 4
0
 def run_idl(self, txn):
     # ovn-sbctl does a client-side check for duplicate entry, but since
     # there is an index on "name", it will fail if we try to insert a
     # duplicate, so I'm not doing the check unless may_exist is set
     if self.may_exist:
         chassis = idlutils.row_by_value(self.api.idl, self.table_name,
                                         'name', self.chassis)
         if chassis:
             self.result = rowview.RowView(chassis)
             return
     chassis = txn.insert(self.api.tables[self.table_name])
     chassis.name = self.chassis
     encaps = []
     for encap_type in self.encap_types:
         encap = txn.insert(self.api.tables['Encap'])
         encap.type = encap_type
         encap.ip = self.encap_ip
         encap.options = {'csum': 'True'}  # ovn-sbctl silently does this...
         # NOTE(twilson) addvalue seems like it should work, but fails with
         # Chassis table col encaps references nonexistent row error
         # chassis.addvalue('encaps', encap)
         encaps.append(encap)
     chassis.encaps = encaps
     for col, val in self.columns.items():
         setattr(chassis, col, val)
     self.result = chassis.uuid
Exemplo n.º 5
0
 def post_commit(self, txn):
     # Replace the temporary row with the post-commit UUID to match vsctl
     u = txn.get_insert_uuid(self.result.uuid)
     if self.row:
         self.result = rowview.RowView(self.api.tables[self.table].rows[u])
     else:
         self.result = u
Exemplo n.º 6
0
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     try:
         lrp = self.api.lookup('Logical_Router_Port', self.port)
         if self.may_exist:
             msg = None
             if lrp not in lr.ports:
                 msg = "Port %s exists, but is not in router %s" % (
                     self.port, self.router)
             elif netaddr.EUI(lrp.mac) != netaddr.EUI(self.mac):
                 msg = "Port %s exists with different mac" % (self.port)
             elif set(self.networks) != set(lrp.networks):
                 msg = "Port %s exists with different networks" % (
                     self.port)
             elif (not self.peer) != (not lrp.peer) or (self.peer !=
                                                        lrp.peer):
                 msg = "Port %s exists with different peer" % (self.port)
             if msg:
                 raise RuntimeError(msg)
             self.result = rowview.RowView(lrp)
             return
     except idlutils.RowNotFound:
         pass
     lrp = txn.insert(self.api.tables['Logical_Router_Port'])
     # This is what ovn-nbctl does, though the lookup is by uuid or name
     lrp.name = self.port
     lrp.mac = self.mac
     lrp.networks = self.networks
     if self.peer:
         lrp.peer = self.peer
     lr.addvalue('ports', lrp)
     self.set_columns(lrp, **self.columns)
     self.result = lrp.uuid
Exemplo n.º 7
0
    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])
Exemplo n.º 8
0
 def run_idl(self, txn):
     # reduce search space if we have any indexed column and '=' match
     rows = (idlutils.index_condition_match(self.table, *self.conditions)
             or self.table.rows.values())
     self.result = [
         rowview.RowView(r) if self.row else
         {c: idlutils.get_column_value(r, c)
          for c in self.columns} for r in rows
         if idlutils.row_match(r, self.conditions)
     ]
Exemplo n.º 9
0
 def populate_subtree(self, parent_leaf=None, uuids=None):
     for uuid in uuids:
         acl = self._ovn_nb.tables[self.TYPE].rows.get(uuid)
         acl_row = rowview.RowView(acl)
         uuid = str(acl_row.uuid)
         child_leaf = self._treeview.insert(self.own_leaf,
                                            'end',
                                            uuid,
                                            text=uuid,
                                            tags=self.TYPE,
                                            values=uuid)
         self.store_info(acl_row, child_leaf)
Exemplo n.º 10
0
 def run_idl(self, txn):
     if self.router:
         try:
             lr = self.api.lookup('Logical_Router', self.router)
             if self.may_exist:
                 self.result = rowview.RowView(lr)
                 return
         except idlutils.RowNotFound:
             pass
     lr = txn.insert(self.api.tables['Logical_Router'])
     lr.name = self.router if self.router else ""
     self.set_columns(lr, **self.columns)
     self.result = lr.uuid
Exemplo n.º 11
0
    def run_idl(self, txn):
        if self.may_exist:
            try:
                hcg = self.api.lookup(self.table_name, self.name)
                self.result = rowview.RowView(hcg)
                return
            except idlutils.RowNotFound:
                pass

        hcg = txn.insert(self.api._tables[self.table_name])
        hcg.name = self.name
        self.set_columns(hcg, **self.columns)
        self.result = hcg.uuid
Exemplo n.º 12
0
 def run_idl(self, txn):
     # There is requirement for name to be unique
     # (index in ovn-ic-nb.ovsschema)
     switch = idlutils.row_by_value(self.api.idl, self.table_name, 'name',
                                    self.switch, None)
     if switch:
         if self.may_exist:
             self.result = rowview.RowView(switch)
             return
         raise RuntimeError("Transit Switch %s exists" % self.switch)
     switch = txn.insert(self.api.tables[self.table_name])
     switch.name = self.switch
     self.set_columns(switch, **self.columns)
     self.result = switch.uuid
Exemplo n.º 13
0
 def post_commit(self, txn):
     # If get_insert_uuid fails, self.result was not a result of a
     # recent insert. Most likely we are post_commit after a lookup()
     if isinstance(self.result, rowview.RowView):
         return
     if isinstance(self.result, ovs.db.idl.Row):
         row = self.result
     else:
         real_uuid = txn.get_insert_uuid(self.result) or self.result
         # If we have multiple commands in a transation, post_commit can
         # be called even if *this* command caused no change. Theoretically
         # the subclass should have set a UUID/RowView result in that case
         # which is handled above, so raise exception if real_uuid not found
         row = self.api.tables[self.table_name].rows[real_uuid]
     self.result = rowview.RowView(row)
Exemplo n.º 14
0
 def populate_subtree(self, uuids=None):
     for port_uuid in uuids:
         port = self._ovn_nb.tables[self.TYPE].rows.get(port_uuid)
         port_row = rowview.RowView(port)
         uuid = str(port_row.uuid)
         child_leaf = self._treeview.insert(self.own_leaf,
                                            'end',
                                            uuid,
                                            text=uuid,
                                            tags=self.TYPE,
                                            values=uuid)
         self.store_info(port_row, child_leaf)
         qos_tt = QoSes(self._root_tree,
                        self._ovn_nb,
                        self._ovn_sb,
                        parent_leaf=child_leaf,
                        parent_uuid=uuid)
         qos_tt.populate_subtree()
Exemplo n.º 15
0
 def run_idl(self, txn):
     ls = self.api.lookup('Logical_Switch', self.switch)
     acls = [acl for acl in ls.acls if self.acl_match(acl)]
     if acls:
         if self.may_exist:
             self.result = rowview.RowView(acls[0])
             return
         raise RuntimeError("ACL (%s, %s, %s) already exists" %
                            (self.direction, self.priority, self.match))
     acl = txn.insert(self.api.tables[self.table_name])
     acl.direction = self.direction
     acl.priority = self.priority
     acl.match = self.match
     acl.action = self.action
     acl.log = self.log
     ls.addvalue('acls', acl)
     for col, value in self.external_ids.items():
         acl.setkey('external_ids', col, value)
     self.result = acl.uuid
Exemplo n.º 16
0
 def populate_subtree(self, uuids=None):
     for pg in self._ovn_nb.tables[self.TYPE].rows.values():
         pg_row = rowview.RowView(pg)
         uuid = str(pg_row.uuid)
         text = uuid
         sg = pg._data['external_ids'].get('neutron:security_group_id')
         if sg:
             text += ' (Neutron SG: %s)' % sg
         child_leaf = self._treeview.insert(self.own_leaf,
                                            'end',
                                            uuid,
                                            text=text,
                                            tags=self.TYPE,
                                            values=uuid)
         self.store_info(pg_row, child_leaf)
         acl_tt = ACLs(self._root_tree,
                       self._ovn_nb,
                       self._ovn_sb,
                       parent_leaf=child_leaf,
                       parent_uuid=uuid)
         acl_tt.populate_subtree(uuids=[acls.uuid for acls in pg_row.acls])
Exemplo n.º 17
0
 def run_idl(self, txn):
     ls = self.api.lookup('Logical_Switch', self.switch)
     for qos_rule in iter(r for r in ls.qos_rules if self.qos_match(r)):
         if self.may_exist:
             self.result = rowview.RowView(qos_rule)
             return
         raise RuntimeError("QoS (%s, %s, %s) already exists" % (
             self.direction, self.priority, self.match))
     row = txn.insert(self.api.tables[self.table_name])
     row.direction = self.direction
     row.priority = self.priority
     row.match = self.match
     if self.rate:
         row.setkey('bandwidth', 'rate', self.rate)
         if self.burst:
             row.setkey('bandwidth', 'burst', self.burst)
     if self.dscp is not None:
         row.setkey('action', 'dscp', self.dscp)
     self.set_columns(row, **self.columns)
     ls.addvalue('qos_rules', row)
     self.result = row.uuid
Exemplo n.º 18
0
 def populate_subtree(self, uuids=None):
     for ls in self._ovn_nb.tables[self.TYPE].rows.values():
         ls_row = rowview.RowView(ls)
         uuid = str(ls_row.uuid)
         text = uuid
         network_name = ls._data['external_ids'].get('neutron:network_name')
         if network_name:
             text += ' (network: %s)' % network_name
         child_leaf = self._treeview.insert(self.own_leaf,
                                            'end',
                                            uuid,
                                            text=text,
                                            tags=self.TYPE,
                                            values=str(ls_row.uuid))
         self.store_info(ls_row, child_leaf)
         lsp_tt = LogicalSiwtchPorts(self._root_tree,
                                     self._ovn_nb,
                                     self._ovn_sb,
                                     parent_leaf=child_leaf,
                                     parent_uuid=uuid)
         lsp_tt.populate_subtree(uuids=[port.uuid for port in ls_row.ports])
Exemplo n.º 19
0
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     try:
         lrp = self.api.lookup('Logical_Router_Port', self.port)
         if self.may_exist:
             msg = None
             if lrp not in lr.ports:
                 msg = "Port %s exists, but is not in router %s" % (
                     self.port, self.router)
             elif netaddr.EUI(lrp.mac) != netaddr.EUI(self.mac):
                 msg = "Port %s exists with different mac" % (self.port)
             elif set(self.networks) != set(lrp.networks):
                 msg = "Port %s exists with different networks" % (
                     self.port)
             elif (not self.peer) != (not lrp.peer) or (
                     self.peer != lrp.peer):
                 msg = "Port %s exists with different peer" % (self.port)
             if msg:
                 raise RuntimeError(msg)
             self.result = rowview.RowView(lrp)
             return
     except idlutils.RowNotFound:
         pass
     lrp = txn.insert(self.api.tables['Logical_Router_Port'])
     # This is what ovn-nbctl does, though the lookup is by uuid or name
     lrp.name = self.port
     lrp.mac = self.mac
     lrp.networks = self.networks
     if self.peer:
         lrp.peer = self.peer
     lr.addvalue('ports', lrp)
     gwcs = self.columns.pop('gateway_chassis', [])
     for n, chassis in enumerate(gwcs):
         gwc_name = '%s_%s' % (lrp.name, chassis)
         cmd = GatewayChassisAddCommand(self.api, gwc_name, chassis,
                                        len(gwcs) - n, may_exist=True)
         cmd.run_idl(txn)
         lrp.addvalue('gateway_chassis', cmd.result)
     self.set_columns(lrp, **self.columns)
     self.result = lrp.uuid
Exemplo n.º 20
0
    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:
            rows = []
            for record in self.records:
                try:
                    rows.append(
                        idlutils.row_by_record(self.api.idl, self.table,
                                               record))

                except idlutils.RowNotFound:
                    if self.if_exists:
                        continue
                    raise
        else:
            rows = table_schema.rows.values()
        self.result = [
            rowview.RowView(row) if self.row else
            {c: idlutils.get_column_value(row, c)
             for c in columns} for row in rows
        ]
Exemplo n.º 21
0
 def run_idl(self, txn):
     # There is no requirement for name to be unique, so if a name is
     # specified, we always have to do a lookup since adding it won't
     # fail. If may_exist is set, we just don't do anything when dup'd
     if self.switch:
         sw = idlutils.row_by_value(self.api.idl, self.table_name, 'name',
                                    self.switch, None)
         if sw:
             if self.may_exist:
                 self.result = rowview.RowView(sw)
                 return
             raise RuntimeError("Switch %s exists" % self.switch)
     elif self.may_exist:
         raise RuntimeError("may_exist requires name")
     sw = txn.insert(self.api.tables[self.table_name])
     if self.switch:
         sw.name = self.switch
     else:
         # because ovs.db.idl brokenly requires a changed column
         sw.name = ""
     self.set_columns(sw, **self.columns)
     self.result = sw.uuid
Exemplo n.º 22
0
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     for route in lr.static_routes:
         if self.prefix == route.ip_prefix:
             if not self.may_exist:
                 msg = "Route %s already exists on router %s" % (
                     self.prefix, self.router)
                 raise RuntimeError(msg)
             route.nexthop = self.nexthop
             route.policy = self.policy
             if self.port:
                 route.port = self.port
             self.result = rowview.RowView(route)
             return
     route = txn.insert(self.api.tables['Logical_Router_Static_Route'])
     route.ip_prefix = self.prefix
     route.nexthop = self.nexthop
     route.policy = self.policy
     if self.port:
         route.port = self.port
     lr.addvalue('static_routes', route)
     self.result = route.uuid
Exemplo n.º 23
0
    def run_idl(self, txn):
        ls = self.api.lookup('Logical_Switch', self.switch)
        try:
            lsp = self.api.lookup(self.table_name, self.port)
            if self.may_exist:
                msg = None
                if lsp not in ls.ports:
                    msg = "%s exists, but is not in %s" % (
                        self.port, self.switch)
                if self.parent:
                    if not lsp.parent_name:
                        msg = "%s exists, but has no parent" % self.port
                    # parent_name, being optional, is stored as list
                    if self.parent not in lsp.parent_name:
                        msg = "%s exists with different parent" % self.port
                    if self.tag not in lsp.tag_request:
                        msg = "%s exists with different tag request" % (
                            self.port,)
                elif lsp.parent_name:
                    msg = "%s exists, but with a parent" % self.port

                if msg:
                    raise RuntimeError(msg)
                self.result = rowview.RowView(lsp)
                return
        except idlutils.RowNotFound:
            # This is what we want
            pass
        lsp = txn.insert(self.api.tables[self.table_name])
        lsp.name = self.port
        if self.tag is not None:
            lsp.parent_name = self.parent
            lsp.tag_request = self.tag
        ls.addvalue('ports', lsp)
        self.set_columns(lsp, **self.columns)
        self.result = lsp.uuid
Exemplo n.º 24
0
 def post_commit(self, txn):
     real_uuid = txn.get_insert_uuid(self.result)
     if real_uuid:
         table = self.api.tables['Logical_Router_Static_Route']
         row = table.rows[real_uuid]
         self.result = rowview.RowView(row)
Exemplo n.º 25
0
 def run_idl(self, txn):
     self.result = [rowview.RowView(r) for
                    r in self.api.tables['DHCP_Options'].rows.values()]
Exemplo n.º 26
0
 def run_idl(self, txn):
     self.result = [rowview.RowView(r)
                    for r in self.api.tables['Chassis'].rows.values()]
Exemplo n.º 27
0
 def run_idl(self, txn):
     self.result = [rowview.RowView(r) for
                    r in self.api.tables['Logical_Router'].rows.values()]
Exemplo n.º 28
0
 def run_idl(self, txn):
     lr = self.api.lookup('Logical_Router', self.router)
     self.result = [rowview.RowView(r) for r in lr.nat]
Exemplo n.º 29
0
 def post_commit(self, txn):
     real_uuid = txn.get_insert_uuid(self.result)
     if real_uuid:
         row = self.api.tables['NAT'].rows[real_uuid]
         self.result = rowview.RowView(row)
Exemplo n.º 30
0
 def run_idl(self, txn):
     table = self.api.tables['Logical_Switch']
     self.result = [rowview.RowView(r) for r in table.rows.values()]