def get_ports(self, context, filters=None, fields=None): """ Returns all ports from given tenant :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound """ quantum_lports = super(NvpPluginV2, self).get_ports(context, filters) vm_filter = "" tenant_filter = "" # This is used when calling delete_network. Quantum checks to see if # the network has any ports. if filters.get("network_id"): # FIXME (Aaron) If we get more than one network_id this won't work lswitch = filters["network_id"][0] else: lswitch = "*" if filters.get("device_id"): for vm_id in filters.get("device_id"): vm_filter = ("%stag_scope=vm_id&tag=%s&" % (vm_filter, hashlib.sha1(vm_id).hexdigest())) else: vm_id = "" if filters.get("tenant_id"): for tenant in filters.get("tenant_id"): tenant_filter = ("%stag_scope=os_tid&tag=%s&" % (tenant_filter, tenant)) nvp_lports = {} lport_fields_str = ("tags,admin_status_enabled,display_name," "fabric_status_up") try: for c in self.clusters: lport_query_path = ( "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id" "&relations=LogicalPortStatus" % (lswitch, lport_fields_str, vm_filter, tenant_filter)) ports = nvplib.get_all_query_pages(lport_query_path, c) if ports: for port in ports: for tag in port["tags"]: if tag["scope"] == "q_port_id": nvp_lports[tag["tag"]] = port except Exception: LOG.error("Unable to get ports: %s" % traceback.format_exc()) raise exception.QuantumException() lports = [] for quantum_lport in quantum_lports: try: quantum_lport["admin_state_up"] = ( nvp_lports[quantum_lport["id"]]["admin_status_enabled"]) quantum_lport["name"] = ( nvp_lports[quantum_lport["id"]]["display_name"]) if (nvp_lports[quantum_lport["id"]] ["_relations"] ["LogicalPortStatus"] ["fabric_status_up"]): quantum_lport["status"] = constants.PORT_STATUS_ACTIVE else: quantum_lport["status"] = constants.PORT_STATUS_DOWN del nvp_lports[quantum_lport["id"]] lports.append(quantum_lport) except KeyError: raise Exception("Quantum and NVP Databases are out of Sync!") # do not make the case in which ports are found in NVP # but not in Quantum catastrophic. if len(nvp_lports): LOG.warning("Found %s logical ports not bound " "to Quantum ports. Quantum and NVP are " "potentially out of sync", len(nvp_lports)) if fields: ret_fields = [] for lport in lports: row = {} for field in fields: row[field] = lport[field] ret_fields.append(row) return ret_fields return lports
def get_networks(self, context, filters=None, fields=None): """ Retrieves all attributes of the network, NOT including the ports of that network. :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound :raises: exception.QuantumException """ result = {} nvp_lswitches = [] quantum_lswitches = ( super(NvpPluginV2, self).get_networks(context, filters)) if context.is_admin and not filters.get("tenant_id"): tenant_filter = "" elif filters.get("tenant_id"): tenant_filter = "" for tenant in filters.get("tenant_id"): tenant_filter += "&tag=%s&tag_scope=os_tid" % tenant else: tenant_filter = "&tag=%s&tag_scope=os_tid" % context.tenant_id lswitch_filters = "uuid,display_name,fabric_status" lswitch_url_path = ( "/ws.v1/lswitch?fields=%s&relations=LogicalSwitchStatus%s" % (lswitch_filters, tenant_filter)) try: for c in self.clusters: res = nvplib.get_all_query_pages( lswitch_url_path, c) nvp_lswitches.extend(res) except Exception: LOG.error("Unable to get switches: %s" % traceback.format_exc()) raise exception.QuantumException() # TODO (Aaron) This can be optimized if filters.get("id"): filtered_lswitches = [] for nvp_lswitch in nvp_lswitches: for id in filters.get("id"): if id == nvp_lswitch['uuid']: filtered_lswitches.append(nvp_lswitch) nvp_lswitches = filtered_lswitches for quantum_lswitch in quantum_lswitches: Found = False for nvp_lswitch in nvp_lswitches: if nvp_lswitch["uuid"] == quantum_lswitch["id"]: if (nvp_lswitch["_relations"]["LogicalSwitchStatus"] ["fabric_status"]): quantum_lswitch["status"] = constants.NET_STATUS_ACTIVE else: quantum_lswitch["status"] = constants.NET_STATUS_DOWN quantum_lswitch["name"] = nvp_lswitch["display_name"] nvp_lswitches.remove(nvp_lswitch) Found = True break if not Found: raise Exception("Quantum and NVP Databases are out of Sync!") # do not make the case in which switches are found in NVP # but not in Quantum catastrophic. if len(nvp_lswitches): LOG.warning("Found %s logical switches not bound " "to Quantum networks. Quantum and NVP are " "potentially out of sync", len(nvp_lswitches)) LOG.debug("get_networks() completed for tenant %s" % context.tenant_id) if fields: ret_fields = [] for quantum_lswitch in quantum_lswitches: row = {} for field in fields: row[field] = quantum_lswitch[field] ret_fields.append(row) return ret_fields return quantum_lswitches
def get_network(self, context, id, fields=None): """ Retrieves all attributes of the network, NOT including the ports of that network. :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound :raises: exception.QuantumException """ result = {} lswitch_query = "&uuid=%s" % id # always look for the tenant_id in the resource itself rather than # the context, as with shared networks context.tenant_id and # network['tenant_id'] might differ on GETs # goto to the plugin DB and fecth the network network = self._get_network(context, id) # TODO(salvatore-orlando): verify whether the query on os_tid is # redundant or not. if context.is_admin is False: tenant_query = ("&tag=%s&tag_scope=os_tid" % network['tenant_id']) else: tenant_query = "" # Then fetch the correspondiong logical switch in NVP as well # TODO(salvatore-orlando): verify whether the step on NVP # can be completely avoided lswitch_url_path = ( "/ws.v1/lswitch?" "fields=uuid,display_name%s%s" % (tenant_query, lswitch_query)) try: for c in self.clusters: lswitch_results = nvplib.get_all_query_pages( lswitch_url_path, c) if lswitch_results: result['lswitch-display-name'] = ( lswitch_results[0]['display_name']) break except Exception: LOG.error("Unable to get switches: %s" % traceback.format_exc()) raise exception.QuantumException() if 'lswitch-display-name' not in result: raise exception.NetworkNotFound(net_id=id) # Fetch network in quantum quantum_db = super(NvpPluginV2, self).get_network(context, id, fields) d = {'id': id, 'name': result['lswitch-display-name'], 'tenant_id': network['tenant_id'], 'admin_state_up': True, 'status': constants.NET_STATUS_ACTIVE, 'shared': network['shared'], 'subnets': quantum_db.get('subnets', [])} LOG.debug("get_network() completed for tenant %s: %s" % ( context.tenant_id, d)) return d
def get_ports(self, context, filters=None, fields=None): """ Returns all ports from given tenant :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound """ quantum_lports = super(NvpPluginV2, self).get_ports(context, filters) vm_filter = "" tenant_filter = "" # This is used when calling delete_network. Quantum checks to see if # the network has any ports. if filters.get("network_id"): # FIXME (Aaron) If we get more than one network_id this won't work lswitch = filters["network_id"][0] else: lswitch = "*" if filters.get("device_id"): for vm_id in filters.get("device_id"): vm_filter = ("%stag_scope=vm_id&tag=%s&" % (vm_filter, hashlib.sha1(vm_id).hexdigest())) else: vm_id = "" if filters.get("tenant_id"): for tenant in filters.get("tenant_id"): tenant_filter = ("%stag_scope=os_tid&tag=%s&" % (tenant_filter, tenant)) nvp_lports = {} lport_fields_str = ("tags,admin_status_enabled,display_name," "fabric_status_up") try: for c in self.clusters: lport_query_path = ( "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id" "&relations=LogicalPortStatus" % (lswitch, lport_fields_str, vm_filter, tenant_filter)) ports = nvplib.get_all_query_pages(lport_query_path, c) if ports: for port in ports: for tag in port["tags"]: if tag["scope"] == "q_port_id": nvp_lports[tag["tag"]] = port except Exception: LOG.error("Unable to get ports: %s" % traceback.format_exc()) raise exception.QuantumException() lports = [] for quantum_lport in quantum_lports: try: quantum_lport["admin_state_up"] = ( nvp_lports[quantum_lport["id"]]["admin_status_enabled"]) quantum_lport["name"] = ( nvp_lports[quantum_lport["id"]]["display_name"]) if (nvp_lports[quantum_lport["id"]]["_relations"] ["LogicalPortStatus"]["fabric_status_up"]): quantum_lport["status"] = constants.PORT_STATUS_ACTIVE else: quantum_lport["status"] = constants.PORT_STATUS_DOWN del nvp_lports[quantum_lport["id"]] lports.append(quantum_lport) except KeyError: raise Exception("Quantum and NVP Databases are out of Sync!") # do not make the case in which ports are found in NVP # but not in Quantum catastrophic. if len(nvp_lports): LOG.warning( "Found %s logical ports not bound " "to Quantum ports. Quantum and NVP are " "potentially out of sync", len(nvp_lports)) if fields: ret_fields = [] for lport in lports: row = {} for field in fields: row[field] = lport[field] ret_fields.append(row) return ret_fields return lports
def get_networks(self, context, filters=None, fields=None): """ Retrieves all attributes of the network, NOT including the ports of that network. :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound :raises: exception.QuantumException """ result = {} nvp_lswitches = [] quantum_lswitches = (super(NvpPluginV2, self).get_networks(context, filters)) if context.is_admin and not filters.get("tenant_id"): tenant_filter = "" elif filters.get("tenant_id"): tenant_filter = "" for tenant in filters.get("tenant_id"): tenant_filter += "&tag=%s&tag_scope=os_tid" % tenant else: tenant_filter = "&tag=%s&tag_scope=os_tid" % context.tenant_id lswitch_filters = "uuid,display_name,fabric_status" lswitch_url_path = ( "/ws.v1/lswitch?fields=%s&relations=LogicalSwitchStatus%s" % (lswitch_filters, tenant_filter)) try: for c in self.clusters: res = nvplib.get_all_query_pages(lswitch_url_path, c) nvp_lswitches.extend(res) except Exception: LOG.error("Unable to get switches: %s" % traceback.format_exc()) raise exception.QuantumException() # TODO (Aaron) This can be optimized if filters.get("id"): filtered_lswitches = [] for nvp_lswitch in nvp_lswitches: for id in filters.get("id"): if id == nvp_lswitch['uuid']: filtered_lswitches.append(nvp_lswitch) nvp_lswitches = filtered_lswitches for quantum_lswitch in quantum_lswitches: Found = False for nvp_lswitch in nvp_lswitches: if nvp_lswitch["uuid"] == quantum_lswitch["id"]: if (nvp_lswitch["_relations"]["LogicalSwitchStatus"] ["fabric_status"]): quantum_lswitch["status"] = constants.NET_STATUS_ACTIVE else: quantum_lswitch["status"] = constants.NET_STATUS_DOWN quantum_lswitch["name"] = nvp_lswitch["display_name"] nvp_lswitches.remove(nvp_lswitch) Found = True break if not Found: raise Exception("Quantum and NVP Databases are out of Sync!") # do not make the case in which switches are found in NVP # but not in Quantum catastrophic. if len(nvp_lswitches): LOG.warning( "Found %s logical switches not bound " "to Quantum networks. Quantum and NVP are " "potentially out of sync", len(nvp_lswitches)) LOG.debug("get_networks() completed for tenant %s" % context.tenant_id) if fields: ret_fields = [] for quantum_lswitch in quantum_lswitches: row = {} for field in fields: row[field] = quantum_lswitch[field] ret_fields.append(row) return ret_fields return quantum_lswitches
def get_network(self, context, id, fields=None): """ Retrieves all attributes of the network, NOT including the ports of that network. :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound :raises: exception.QuantumException """ result = {} lswitch_query = "&uuid=%s" % id # always look for the tenant_id in the resource itself rather than # the context, as with shared networks context.tenant_id and # network['tenant_id'] might differ on GETs # goto to the plugin DB and fecth the network network = self._get_network(context, id) # TODO(salvatore-orlando): verify whether the query on os_tid is # redundant or not. if context.is_admin is False: tenant_query = ("&tag=%s&tag_scope=os_tid" % network['tenant_id']) else: tenant_query = "" # Then fetch the correspondiong logical switch in NVP as well # TODO(salvatore-orlando): verify whether the step on NVP # can be completely avoided lswitch_url_path = ("/ws.v1/lswitch?" "fields=uuid,display_name%s%s" % (tenant_query, lswitch_query)) try: for c in self.clusters: lswitch_results = nvplib.get_all_query_pages( lswitch_url_path, c) if lswitch_results: result['lswitch-display-name'] = ( lswitch_results[0]['display_name']) break except Exception: LOG.error("Unable to get switches: %s" % traceback.format_exc()) raise exception.QuantumException() if 'lswitch-display-name' not in result: raise exception.NetworkNotFound(net_id=id) # Fetch network in quantum quantum_db = super(NvpPluginV2, self).get_network(context, id, fields) d = { 'id': id, 'name': result['lswitch-display-name'], 'tenant_id': network['tenant_id'], 'admin_state_up': True, 'status': constants.NET_STATUS_ACTIVE, 'shared': network['shared'], 'subnets': quantum_db.get('subnets', []) } LOG.debug("get_network() completed for tenant %s: %s" % (context.tenant_id, d)) return d