def get_port_status(controller, lswitch_id, port_id): """Retrieve the operational status of the port""" # Make sure the network exists first try: do_single_request("GET", "/ws.v1/lswitch/%s" % (lswitch_id), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=lswitch_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() try: r = do_single_request("GET", "/ws.v1/lswitch/%s/lport/%s/status" % (lswitch_id, port_id), controller=controller) r = jsonutils.loads(r) except NvpApiClient.ResourceNotFound as e: LOG.error("Port not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=lswitch_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() if r['link_status_up'] is True: return "UP" else: return "DOWN"
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 update_port(network, port_id, **params): cluster = params["cluster"] lport_obj = {} admin_state_up = params['port'].get('admin_state_up') name = params["port"].get("name") device_id = params["port"].get("device_id") if admin_state_up: lport_obj["admin_status_enabled"] = admin_state_up if name: lport_obj["display_name"] = name if device_id: # device_id can be longer than 40 so we rehash it device_id = hashlib.sha1(device_id).hexdigest() lport_obj["tags"] = ( [dict(scope='os_tid', tag=params["port"].get("tenant_id")), dict(scope='q_port_id', tag=params["port"]["id"]), dict(scope='vm_id', tag=device_id)]) uri = "/ws.v1/lswitch/" + network + "/lport/" + port_id try: resp_obj = do_single_request("PUT", uri, json.dumps(lport_obj), cluster=cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() obj = json.loads(resp_obj) obj["port-op-status"] = get_port_status(cluster, network, obj["uuid"]) return obj
def plug_interface(controller, network, port, type, attachment=None): uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "/attachment" lport_obj = {} if attachment: lport_obj["vif_uuid"] = attachment lport_obj["type"] = type try: resp_obj = do_single_request("PUT", uri, jsonutils.dumps(lport_obj), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) except NvpApiClient.Conflict as e: LOG.error("Conflict while making attachment to port, " "Error: %s" % str(e)) raise exception.AlreadyAttached(att_id=attachment, port_id=port, net_id=network, att_port_id="UNKNOWN") except NvpApiClient.NvpApiException as e: raise exception.QuantumException() result = jsonutils.dumps(resp_obj) return result
def update_port(network, port_id, **params): controller = params["controller"] lport_obj = {} if "state" in params: state = params["state"] check_port_state(state) admin_status = True if state == "DOWN": admin_status = False lport_obj["admin_status_enabled"] = admin_status uri = "/ws.v1/lswitch/" + network + "/lport/" + port_id try: resp_obj = do_single_request("PUT", uri, jsonutils.dumps(lport_obj), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() obj = jsonutils.loads(resp_obj) obj["port-op-status"] = get_port_status(controller, network, obj["uuid"]) return obj
def create_port(tenant, network, port_init_state, **params): # Check initial state -- this throws an exception if the port state is # invalid check_port_state(port_init_state) controller = params["controller"] ls_uuid = network admin_status = True if port_init_state == "DOWN": admin_status = False lport_obj = {"admin_status_enabled": admin_status} path = "/ws.v1/lswitch/" + ls_uuid + "/lport" try: resp_obj = do_single_request("POST", path, jsonutils.dumps(lport_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() result = jsonutils.loads(resp_obj) result['port-op-status'] = get_port_status(controller, ls_uuid, result['uuid']) return result
def _delete_tz(self, uuid): post_uri = "/ws.v1/transport-zone/%s" % uuid try: resp_obj = self.quantum.api_client.request("DELETE", post_uri) except NvpApiClient.NvpApiException as e: LOG.error("Unknown API Error: %s" % str(e)) raise exception.QuantumException()
def delete_port(cluster, port): try: do_single_request("DELETE", port['_href'], cluster=cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port['uuid']) except NvpApiClient.NvpApiException as e: raise exception.QuantumException()
def delete_port(controller, network, port): uri = "/ws.v1/lswitch/" + network + "/lport/" + port try: do_single_request("DELETE", uri, controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException()
def test_unmapped_quantum_error(self): controller = mock.MagicMock() controller.test.side_effect = q_exc.QuantumException() resource = webtest.TestApp(wsgi_resource.Resource(controller)) environ = {'wsgiorg.routing_args': (None, {'action': 'test'})} res = resource.get('', extra_environ=environ, expect_errors=True) self.assertEqual(res.status_int, exc.HTTPInternalServerError.code)
def _create_tz(self, name): post_uri = "/ws.v1/transport-zone" body = {"display_name": name, "tags": [{"tag": "plugin-test"}]} try: resp_obj = self.quantum.api_client.request("POST", post_uri, jsonutils.dumps(body)) except NvpApiClient.NvpApiException as e: print("Unknown API Error: %s" % str(e)) raise exception.QuantumException() return jsonutils.loads(resp_obj)["uuid"]
def test_mapped_quantum_error(self): controller = mock.MagicMock() controller.test.side_effect = q_exc.QuantumException() faults = {q_exc.QuantumException: exc.HTTPGatewayTimeout} resource = webtest.TestApp(wsgi_resource.Resource(controller, faults=faults)) environ = {'wsgiorg.routing_args': (None, {'action': 'test'})} res = resource.get('', extra_environ=environ, expect_errors=True) self.assertEqual(res.status_int, exc.HTTPGatewayTimeout.code)
def delete_networks(controller, networks): for network in networks: path = "/ws.v1/lswitch/%s" % network try: do_single_request("DELETE", path, 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()
def get_network(controller, net_id): path = "/ws.v1/lswitch/%s" % net_id try: resp_obj = do_single_request("GET", path, controller=controller) network = jsonutils.loads(resp_obj) except NvpApiClient.ResourceNotFound as e: raise exception.NetworkNotFound(net_id=net_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() LOG.debug("Got network \"%s\": %s" % (net_id, network)) return network
def get_network(cluster, net_id): path = "/ws.v1/lswitch/%s" % net_id try: resp_obj = do_single_request("GET", path, cluster=cluster) network = json.loads(resp_obj) LOG.warning("### nw:%s", network) except NvpApiClient.ResourceNotFound: raise exception.NetworkNotFound(net_id=net_id) except NvpApiClient.NvpApiException: raise exception.QuantumException() LOG.debug("Got network \"%s\": %s" % (net_id, network)) return network
def delete_networks(cluster, net_id, lswitch_ids): if net_id in _net_type_cache: del _net_type_cache[net_id] for ls_id in lswitch_ids: path = "/ws.v1/lswitch/%s" % ls_id try: do_single_request("DELETE", path, cluster=cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Network not found, Error: %s" % str(e)) raise exception.NetworkNotFound(net_id=ls_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException()
def get_port(controller, network, port, relations=None): uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "?" if relations: uri += "relations=%s" % relations try: resp_obj = do_single_request("GET", uri, controller=controller) port = jsonutils.loads(resp_obj) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() return port
def get_all_networks(cluster, tenant_id, networks): """Append the quantum network uuids we can find in the given cluster to "networks" """ uri = "/ws.v1/lswitch?fields=*&tag=%s&tag_scope=os_tid" % tenant_id try: resp_obj = do_single_request("GET", uri, cluster=cluster) except NvpApiClient.NvpApiException: raise exception.QuantumException() if not resp_obj: return [] lswitches = json.loads(resp_obj)["results"] networks_result = copy(networks) return networks_result
def unplug_interface(controller, network, port): uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "/attachment" lport_obj = {"type": "NoAttachment"} try: resp_obj = do_single_request("PUT", uri, jsonutils.dumps(lport_obj), controller=controller) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() return jsonutils.loads(resp_obj)
def query_networks(cluster, tenant_id, fields="*", tags=None): uri = "/ws.v1/lswitch?fields=%s" % fields if tags: for t in tags: uri += "&tag=%s&tag_scope=%s" % (t[0], t[1]) try: resp_obj = do_single_request("GET", uri, cluster=cluster) except NvpApiClient.NvpApiException: raise exception.QuantumException() if not resp_obj: return [] lswitches = json.loads(resp_obj)["results"] nets = [{'net-id': lswitch["uuid"], 'net-name': lswitch["display_name"]} for lswitch in lswitches] return nets
def query_ports(controller, network, relations=None, fields="*", filters=None): uri = "/ws.v1/lswitch/" + network + "/lport?" if relations: uri += "relations=%s" % relations uri += "&fields=%s" % fields if filters and "attachment" in filters: uri += "&attachment_vif_uuid=%s" % filters["attachment"] try: resp_obj = do_single_request("GET", uri, 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() return jsonutils.loads(resp_obj)["results"]
def get_cluster_version(cluster): """Return major/minor version #""" # Get control-cluster nodes uri = "/ws.v1/control-cluster/node?_page_length=1&fields=uuid" try: res = do_single_request("GET", uri, cluster=cluster) res = json.loads(res) except NvpApiClient.NvpApiException: raise exception.QuantumException() if res["result_count"] == 0: return None node_uuid = res["results"][0]["uuid"] # Get control-cluster node status. It's unsupported to have controllers # running different version so we just need the first node version. uri = "/ws.v1/control-cluster/node/%s/status" % node_uuid try: res = do_single_request("GET", uri, cluster=cluster) res = json.loads(res) except NvpApiClient.NvpApiException: raise exception.QuantumException() version_parts = res["version"].split(".") version = "%s.%s" % tuple(version_parts[:2]) LOG.info("NVP controller cluster version: %s" % version) return version
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 get_port_status(cluster, lswitch_id, port_id): """Retrieve the operational status of the port""" try: r = do_single_request("GET", "/ws.v1/lswitch/%s/lport/%s/status" % (lswitch_id, port_id), cluster=cluster) r = json.loads(r) except NvpApiClient.ResourceNotFound as e: LOG.error("Port not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=lswitch_id) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() if r['link_status_up'] is True: return constants.PORT_STATUS_ACTIVE else: return constants.PORT_STATUS_DOWN
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 get_all_networks(controller, tenant_id, networks): """Append the quantum network uuids we can find in the given controller to "networks" """ uri = "/ws.v1/lswitch?fields=*&tag=%s&tag_scope=os_tid" % tenant_id try: resp_obj = do_single_request("GET", uri, controller=controller) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() if not resp_obj: return [] lswitches = jsonutils.loads(resp_obj)["results"] for lswitch in lswitches: net_id = lswitch["uuid"] if net_id not in [x["net-id"] for x in networks]: networks.append({ "net-id": net_id, "net-name": lswitch["display_name"] }) return networks
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 create_lswitch(cluster, lswitch_obj): LOG.info("Creating lswitch: %s" % lswitch_obj) # Warn if no tenant is specified found = "os_tid" in [x["scope"] for x in lswitch_obj["tags"]] if not found: LOG.warn("No tenant-id tag specified in logical switch: %s" % ( lswitch_obj)) uri = "/ws.v1/lswitch" try: resp_obj = do_single_request("POST", uri, json.dumps(lswitch_obj), cluster=cluster) except NvpApiClient.NvpApiException: raise exception.QuantumException() r = json.loads(resp_obj) d = {} d["net-id"] = r['uuid'] d["net-name"] = r['display_name'] LOG.debug("Created logical switch: %s" % d["net-id"]) return d
def update_port(network, port_id, **params): cluster = params["cluster"] lport_obj = {} admin_state_up = params['port'].get('admin_state_up') name = params["port"].get("name") if admin_state_up: lport_obj["admin_status_enabled"] = admin_state_up if name: lport_obj["display_name"] = name uri = "/ws.v1/lswitch/" + network + "/lport/" + port_id try: resp_obj = do_single_request("PUT", uri, json.dumps(lport_obj), cluster=cluster) except NvpApiClient.ResourceNotFound as e: LOG.error("Port or Network not found, Error: %s" % str(e)) raise exception.PortNotFound(port_id=port_id, net_id=network) except NvpApiClient.NvpApiException as e: raise exception.QuantumException() obj = json.loads(resp_obj) obj["port-op-status"] = get_port_status(cluster, network, obj["uuid"]) return obj
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