def _get_lswitch_cluster_pairs(self, netw_id, tenant_id): """Figure out the set of lswitches on each cluster that maps to this network id""" pairs = [] for c in self.clusters: lswitches = [] try: ls = nvplib.get_network(c, netw_id) lswitches.append(ls['uuid']) except exception.NetworkNotFound: continue pairs.append((c, lswitches)) if len(pairs) == 0: raise exception.NetworkNotFound(net_id=netw_id) LOG.debug("Returning pairs for network: %s" % (pairs)) return pairs
def update_vlan_binding(netid, newvlanid=None, newvlanname=None): """Updates a vlan to network association""" LOG.debug("update_vlan_binding() called") session = db.get_session() try: binding = (session.query( network_models_v2.Vlan_Binding).filter_by(network_id=netid).one()) if newvlanid: binding["vlan_id"] = newvlanid if newvlanname: binding["vlan_name"] = newvlanname session.merge(binding) session.flush() return binding except exc.NoResultFound: raise q_exc.NetworkNotFound(net_id=netid)
def update_network(cluster, switch, **params): uri = "/ws.v1/lswitch/" + switch lswitch_obj = {} if params["network"]["name"]: lswitch_obj["display_name"] = params["network"]["name"] try: resp_obj = do_single_request("PUT", uri, json.dumps(lswitch_obj), cluster=cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() obj = json.loads(resp_obj) return obj
def delete_network(self, tenant_id, netw_id): """ Deletes the network with the specified network identifier belonging to the specified tenant. :returns: a sequence of mappings with the following signature: {'net-id': uuid that uniquely identifies the particular quantum network } :raises: exception.NetworkInUse :raises: exception.NetworkNotFound """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) nvplib.delete_network(self.controller, netw_id) LOG.debug("delete_network() completed for tenant: %s" % tenant_id) return {'net-id': netw_id}
def update_network(controller, network, **kwargs): uri = "/ws.v1/lswitch/" + network lswitch_obj = {} if "name" in kwargs: lswitch_obj["display_name"] = kwargs["name"] try: resp_obj = do_single_request("PUT", uri, jsonutils.dumps(lswitch_obj), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() obj = jsonutils.loads(resp_obj) return obj
def network_destroy(net_id): session = get_session() try: net = session.query(models.Network).\ filter_by(uuid=net_id).\ one() ports = session.query(models.Port).\ filter_by(network_id=net_id).\ all() for p in ports: session.delete(p) session.delete(net) session.flush() return net except exc.NoResultFound: raise q_exc.NetworkNotFound(net_id=net_id)
def get_network_details(self, tenant_id, netw_id): """ Retrieves a list of all the remote vifs that are attached to the network. :returns: a sequence of mappings with the following signature: {'net-id': uuid that uniquely identifies the particular quantum network 'net-name': a human-readable name associated with network referenced by net-id 'net-ifaces': ['vif1_on_network_uuid', 'vif2_on_network_uuid',...,'vifn_uuid'] } :raises: exception.NetworkNotFound :raises: exception.QuantumException """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) result = None remote_vifs = [] switch = netw_id lports = nvplib.query_ports(self.controller, switch, relations="LogicalPortAttachment") for port in lports: relation = port["_relations"] vic = relation["LogicalPortAttachment"] if "vif_uuid" in vic: remote_vifs.append(vic["vif_uuid"]) if not result: result = nvplib.get_network(self.controller, switch) d = { "net-id": netw_id, "net-ifaces": remote_vifs, "net-name": result["display_name"], "net-op-status": "UP", } LOG.debug("get_network_details() completed for tenant %s: %s" % (tenant_id, d)) return d
def delete_port(self, tenant_id, netw_id, portw_id): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, the remote interface is first un-plugged and then the port is deleted. :returns: a mapping sequence with the following signature: {'port-id': uuid representing the deleted port on specified quantum network } :raises: exception.PortInUse :raises: exception.PortNotFound :raises: exception.NetworkNotFound """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) nvplib.delete_port(self.controller, netw_id, portw_id) LOG.debug("delete_port() completed for tenant: %s" % tenant_id) return {"port-id": portw_id}
def get_port_stats(self, tenant_id, network_id, port_id): """ Returns port statistics for a given port. { "rx_packets": 0, "rx_bytes": 0, "tx_errors": 0, "rx_errors": 0, "tx_bytes": 0, "tx_packets": 0 } :returns: dict() of stats :raises: exception.NetworkNotFound :raises: exception.PortNotFound """ if not nvplib.check_tenant(self.controller, network_id, tenant_id): raise exception.NetworkNotFound(net_id=network_id) return nvplib.get_port_stats(self.controller, network_id, port_id)
def delete_network(self, tenant_id, net_id, **kwargs): """ Deletes a VLAN in the switch, and removes the VLAN configuration from the relevant interfaces """ LOG.debug("NexusPlugin:delete_network() called\n") vlan_id = self._get_vlan_id_for_network(tenant_id, net_id) ports_id = nxos_db.get_nexusport_binding(vlan_id) LOG.debug("NexusPlugin: Interfaces to be disassociated: %s" % ports_id) nxos_db.remove_nexusport_binding(vlan_id) net = self._get_network(tenant_id, net_id) if net: self._client.delete_vlan( str(vlan_id), self._nexus_ip, self._nexus_username, self._nexus_password, self._nexus_first_port, self._nexus_second_port, self._nexus_ssh_port) return net # Network not found raise exc.NetworkNotFound(net_id=net_id)
def get_port_stats(controller, network_id, port_id): try: do_single_request("GET", "/ws.v1/lswitch/%s" % (network_id), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=network_id) try: path = "/ws.v1/lswitch/%s/lport/%s/statistic" % (network_id, port_id) resp = do_single_request("GET", path, controller=controller) stats = jsonutils.loads(resp) except NvpApiClient.ResourceNotFound as e: LOG.error("Port not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() LOG.debug("Returning stats for port \"%s\" on \"%s\": %s" % (port_id, network_id, stats)) return stats
def plug_interface(self, tenant_id, netw_id, portw_id, remote_interface_id): """ Attaches a remote interface to the specified port on the specified Virtual Network. :returns: None :raises: exception.NetworkNotFound :raises: exception.PortNotFound :raises: exception.AlreadyAttached (? should the network automatically unplug/replug) """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) result = nvplib.plug_interface(self.controller, netw_id, portw_id, "VifAttachment", attachment=remote_interface_id) LOG.debug("plug_interface() completed for %s: %s" % (tenant_id, result))
def get_port_details(self, tenant_id, netw_id, portw_id): """ This method allows the user to retrieve a remote interface that is attached to this particular port. :returns: a mapping sequence with the following signature: {'port-id': uuid representing the port on specified quantum network 'net-id': uuid representing the particular quantum network 'attachment': uuid of the virtual interface bound to the port, None otherwise } :raises: exception.PortNotFound :raises: exception.NetworkNotFound """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) port = nvplib.get_port(self.controller, netw_id, portw_id, "LogicalPortAttachment") state = "ACTIVE" if port["admin_status_enabled"] else "DOWN" op_status = nvplib.get_port_status(self.controller, netw_id, portw_id) relation = port["_relations"] attach_type = relation["LogicalPortAttachment"]["type"] vif_uuid = "None" if attach_type == "VifAttachment": vif_uuid = relation["LogicalPortAttachment"]["vif_uuid"] d = { "port-id": portw_id, "attachment": vif_uuid, "net-id": netw_id, "port-state": state, "port-op-status": op_status, } LOG.debug("Port details for tenant %s: %s" % (tenant_id, d)) return d
def update_network(self, tenant_id, netw_id, **kwargs): """ Updates the properties of a particular Virtual Network. :returns: a sequence of mappings representing the new network attributes, with the following signature: {'net-id': uuid that uniquely identifies the particular quantum network 'net-name': the new human-readable name associated with network referenced by net-id } :raises: exception.NetworkNotFound """ if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) result = nvplib.update_network(self.controller, netw_id, **kwargs) LOG.debug("update_network() completed for tenant: %s" % tenant_id) return { 'net-id': netw_id, 'net-name': result["display_name"], 'net-op-status': "UP", }
def get_all_ports(self, tenant_id, netw_id, **kwargs): """ Retrieves all port identifiers belonging to the specified Virtual Network. :returns: a list of mapping sequences with the following signature: [{'port-id': uuid representing a particular port on the specified quantum network }, .... {'port-id': uuid representing a particular port on the specified quantum network } ] :raises: exception.NetworkNotFound """ ids = [] filters = kwargs.get("filter_opts") or {} if not nvplib.check_tenant(self.controller, netw_id, tenant_id): raise exception.NetworkNotFound(net_id=netw_id) LOG.debug("Getting logical ports on lswitch: %s" % netw_id) lports = nvplib.query_ports(self.controller, netw_id, fields="uuid", filters=filters) for port in lports: ids.append({"port-id": port["uuid"]}) # Delete from the filter so that Quantum doesn't attempt to filter on # this too if filters and "attachment" in filters: del filters["attachment"] LOG.debug("get_all_ports() completed for tenant: %s" % tenant_id) LOG.debug("returning port listing:") LOG.debug(ids) return ids
def create_port(tenant, **params): clusters = params["clusters"] dest_cluster = clusters[0] # primary cluster ls_uuid = params["port"]["network_id"] # device_id can be longer than 40 so we rehash it device_id = hashlib.sha1(params["port"]["device_id"]).hexdigest() lport_obj = dict(admin_status_enabled=params["port"]["admin_state_up"], display_name=params["port"]["name"], tags=[ dict(scope='os_tid', tag=tenant), dict(scope='q_port_id', tag=params["port"]["id"]), dict(scope='vm_id', tag=device_id) ]) path = "/ws.v1/lswitch/" + ls_uuid + "/lport" try: resp_obj = do_single_request("POST", path, json.dumps(lport_obj), cluster=dest_cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=params["port"]["network_id"]) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() result = json.loads(resp_obj) result['port-op-status'] = get_port_status(dest_cluster, ls_uuid, result['uuid']) params["port"].update({ "admin_state_up": result["admin_status_enabled"], "status": result["port-op-status"] }) return (params["port"], result['uuid'])
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_network(self, tenant_id, network_id): try: network = db.network_get(network_id) except: raise exc.NetworkNotFound(net_id=network_id) return network