From: peusterm Date: Mon, 19 Jun 2017 10:56:07 +0000 (+0200) Subject: Merge remote-tracking branch 'upstream/master' into demo-mano-integration X-Git-Tag: v3.1~19^2 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2Fvim-emu.git;a=commitdiff_plain;h=c9abfbec5b0e0ae589c8ad66426e207fbe2385b1;hp=dcc79542278d7f4ff4ba1beac95bb9789efd2a0b Merge remote-tracking branch 'upstream/master' into demo-mano-integration --- diff --git a/src/emuvim/api/openstack/compute.py b/src/emuvim/api/openstack/compute.py index 45cef59..fd9b1ac 100755 --- a/src/emuvim/api/openstack/compute.py +++ b/src/emuvim/api/openstack/compute.py @@ -8,6 +8,9 @@ import time import ip_handler as IP +LOG = logging.getLogger("api.openstack.compute") + + class HeatApiStackInvalidException(Exception): """ Exception thrown when a submitted stack is invalid. @@ -95,25 +98,25 @@ class OpenstackCompute(object): for server in stack.servers.values(): for port_name in server.port_names: if port_name not in stack.ports: - logging.warning("Server %s of stack %s has a port named %s that is not known." % + LOG.warning("Server %s of stack %s has a port named %s that is not known." % (server.name, stack.stack_name, port_name)) everything_ok = False if server.image is None: - logging.warning("Server %s holds no image." % (server.name)) + LOG.warning("Server %s holds no image." % (server.name)) everything_ok = False if server.command is None: - logging.warning("Server %s holds no command." % (server.name)) + LOG.warning("Server %s holds no command." % (server.name)) everything_ok = False for port in stack.ports.values(): if port.net_name not in stack.nets: - logging.warning("Port %s of stack %s has a network named %s that is not known." % + LOG.warning("Port %s of stack %s has a network named %s that is not known." % (port.name, stack.stack_name, port.net_name)) everything_ok = False if port.intf_name is None: - logging.warning("Port %s has no interface name." % (port.name)) + LOG.warning("Port %s has no interface name." % (port.name)) everything_ok = False if port.ip_address is None: - logging.warning("Port %s has no IP address." % (port.name)) + LOG.warning("Port %s has no IP address." % (port.name)) everything_ok = False for router in stack.routers.values(): for subnet_name in router.subnet_names: @@ -123,7 +126,7 @@ class OpenstackCompute(object): found = True break if not found: - logging.warning("Router %s of stack %s has a network named %s that is not known." % + LOG.warning("Router %s of stack %s has a network named %s that is not known." % (router.name, stack.stack_name, subnet_name)) everything_ok = False return everything_ok @@ -208,6 +211,7 @@ class OpenstackCompute(object): * *False*: else :rtype: ``bool`` """ + LOG.debug("updating stack {} with new_stack {}".format(old_stack_id, new_stack)) if old_stack_id not in self.stacks: return False old_stack = self.stacks[old_stack_id] @@ -399,7 +403,7 @@ class OpenstackCompute(object): :param server: Specifies the compute resource. :type server: :class:`heat.resources.server` """ - logging.debug("Starting new compute resources %s" % server.name) + LOG.debug("Starting new compute resources %s" % server.name) network = list() for port_name in server.port_names: @@ -447,7 +451,7 @@ class OpenstackCompute(object): :param server: The server that should be removed :type server: ``heat.resources.server`` """ - logging.debug("Stopping container %s with full name %s" % (server.name, server.full_name)) + LOG.debug("Stopping container %s with full name %s" % (server.name, server.full_name)) link_names = list() for port_name in server.port_names: link_names.append(self.find_port_by_name_or_id(port_name).intf_name) @@ -553,9 +557,9 @@ class OpenstackCompute(object): :type stack_operation: ``bool`` :return: :class:`heat.resources.net` """ - logging.debug("Creating network with name %s" % name) + LOG.debug("Creating network with name %s" % name) if self.find_network_by_name_or_id(name) is not None and not stack_operation: - logging.warning("Creating network with name %s failed, as it already exists" % name) + LOG.warning("Creating network with name %s failed, as it already exists" % name) raise Exception("Network with name %s already exists." % name) network = Net(name) network.id = str(uuid.uuid4()) @@ -593,9 +597,9 @@ class OpenstackCompute(object): """ port = self.find_port_by_name_or_id(name) if port is not None and not stack_operation: - logging.warning("Creating port with name %s failed, as it already exists" % name) + LOG.warning("Creating port with name %s failed, as it already exists" % name) raise Exception("Port with name %s already exists." % name) - logging.debug("Creating port with name %s" % name) + LOG.debug("Creating port with name %s" % name) port = Port(name) if not stack_operation: self.ports[port.id] = port diff --git a/src/emuvim/api/openstack/heat_parser.py b/src/emuvim/api/openstack/heat_parser.py index a926c10..a641647 100755 --- a/src/emuvim/api/openstack/heat_parser.py +++ b/src/emuvim/api/openstack/heat_parser.py @@ -8,6 +8,9 @@ import logging import ip_handler as IP +LOG = logging.getLogger("api.openstack.heat.parser") + + class HeatParser: """ The HeatParser will parse a heat dictionary and create a stack and its components, to instantiate it within son-emu. @@ -64,7 +67,10 @@ class HeatParser: if len(self.bufferResource) > 0: print(str(len(self.bufferResource)) + - ' classes could not be created, because the dependencies could not be found.') + ' classes of the HOT could not be created, because the dependencies could not be found.') + print("the problem classes are:") + for br in self.bufferResource: + print("class: %s" % str(br)) return False return True @@ -93,7 +99,7 @@ class HeatParser: stack.nets[net_name] = self.compute.create_network(net_name, True) except Exception as e: - logging.warning('Could not create Net: ' + e.message) + LOG.warning('Could not create Net: ' + e.message) return if 'OS::Neutron::Subnet' in resource['type'] and "Net" not in resource['type']: @@ -113,7 +119,7 @@ class HeatParser: if not stack_update: net.set_cidr(IP.get_new_cidr(net.subnet_id)) except Exception as e: - logging.warning('Could not create Subnet: ' + e.message) + LOG.warning('Could not create Subnet: ' + e.message) return if 'OS::Neutron::Port' in resource['type']: @@ -125,14 +131,14 @@ class HeatParser: else: port = stack.ports[port_name] - if resource['properties']['network']['get_resource'] in stack.nets: + if str(resource['properties']['network']['get_resource']) in stack.nets: net = stack.nets[resource['properties']['network']['get_resource']] if net.subnet_id is not None: port.net_name = net.name port.ip_address = net.get_new_ip_address(port.name) return except Exception as e: - logging.warning('Could not create Port: ' + e.message) + LOG.warning('Could not create Port: ' + e.message) self.bufferResource.append(resource) return @@ -165,7 +171,7 @@ class HeatParser: server.port_names.append(port_name) return except Exception as e: - logging.warning('Could not create Server: ' + e.message) + LOG.warning('Could not create Server: ' + e.message) return if 'OS::Neutron::RouterInterface' in resource['type']: @@ -186,7 +192,7 @@ class HeatParser: stack.routers[router_name].add_subnet(subnet_name) return except Exception as e: - logging.warning('Could not create RouterInterface: ' + e.__repr__()) + LOG.warning('Could not create RouterInterface: ' + e.__repr__()) self.bufferResource.append(resource) return @@ -199,7 +205,7 @@ class HeatParser: stack.ports[port_name].floating_ip = floating_network_id except Exception as e: - logging.warning('Could not create FloatingIP: ' + e.message) + LOG.warning('Could not create FloatingIP: ' + e.message) return if 'OS::Neutron::Router' in resource['type']: @@ -211,7 +217,17 @@ class HeatParser: print('Could not create Router: ' + e.message) return - logging.warning('Could not determine resource type!') + if 'OS::Heat::ResourceGroup' in resource['type']: + try: + embedded_resource = resource['properties']['resource_def'] + LOG.debug("Found resource in resource group: {}".format(embedded_resource)) + # recursively parse embedded resource + self.handle_resource(embedded_resource, stack, dc_label, stack_update) + except Exception as e: + print('Could not create Router: ' + e.message) + return + + LOG.warning('Could not determine resource type: {}'.format(resource['type'])) return def shorten_server_name(self, server_name, stack): diff --git a/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py b/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py index a2c4714..714b727 100755 --- a/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py +++ b/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py @@ -2,6 +2,8 @@ from flask import Flask, request from flask_restful import Api, Resource import logging +LOG = logging.getLogger("api.openstack.base") + class BaseOpenstackDummy(Resource): """ @@ -22,7 +24,7 @@ class BaseOpenstackDummy(Resource): self.api = Api(self.app) def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) if self.app is not None: self.app.before_request(self.dump_playbook) self.app.run(self.ip, self.port, debug=True, use_reloader=False) diff --git a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py index e4b49b2..7819fb9 100755 --- a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py @@ -5,6 +5,9 @@ import logging import json +LOG = logging.getLogger("api.openstack.glance") + + class GlanceDummyApi(BaseOpenstackDummy): def __init__(self, in_ip, in_port, compute): super(GlanceDummyApi, self).__init__(in_ip, in_port) @@ -29,7 +32,7 @@ class GlanceDummyApi(BaseOpenstackDummy): resource_class_kwargs={'api': self}) def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % ("GlanceDummyApi", self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % ("GlanceDummyApi", self.ip, self.port)) if self.app is not None: self.app.before_request(self.dump_playbook) self.app.run(self.ip, self.port, debug=True, use_reloader=False) @@ -37,7 +40,7 @@ class GlanceDummyApi(BaseOpenstackDummy): class Shutdown(Resource): def get(self): - logging.debug(("%s is beeing shut down") % (__name__)) + LOG.debug(("%s is beeing shut down") % (__name__)) func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') @@ -46,7 +49,7 @@ class Shutdown(Resource): class GlanceListApiVersions(Resource): def get(self): - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['versions'] = dict() versions = [{ @@ -65,7 +68,7 @@ class GlanceListApiVersions(Resource): class GlanceSchema(Resource): def get(self): - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['name'] = 'someImageName' resp['properties'] = dict() @@ -78,7 +81,7 @@ class GlanceListImagesApi(Resource): self.api = api def get(self): - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['next'] = None @@ -117,7 +120,7 @@ class GlanceListImagesApi(Resource): return Response(json.dumps(resp), status=200, mimetype="application/json") except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of images." % __name__) + LOG.exception(u"%s: Could not retrieve the list of images." % __name__) return ex.message, 500 def post(self): @@ -126,20 +129,28 @@ class GlanceListImagesApi(Resource): should already be registered with Docker. However, this function returns a reply that looks like the image was just created to make orchestrators, like OSM, happy. """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) + body_data = json.loads(request.data) # lets see what we should create img_name = request.headers.get("X-Image-Meta-Name") img_size = request.headers.get("X-Image-Meta-Size") img_disk_format = request.headers.get("X-Image-Meta-Disk-Format") img_is_public = request.headers.get("X-Image-Meta-Is-Public") img_container_format = request.headers.get("X-Image-Meta-Container-Format") + # try to use body payload if header fields are empty + if img_name is None: + img_name = body_data.get("name") + img_size = 1234 + img_disk_format = body_data.get("disk_format") + img_is_public = True if "public" in body_data.get("visibility") else False + img_container_format = body_data.get("container_format") # try to find ID of already existing image (matched by name) img_id=None for image in self.api.compute.images.values(): - if img_name in image.name: + if str(img_name) in image.name: img_id = image.id - logging.debug("Image name: %s" % img_name) - logging.debug("Image id: %s" % img_id) + LOG.debug("Image name: %s" % img_name) + LOG.debug("Image id: %s" % img_id) # build a response body that looks like a real one resp = dict() f = dict() @@ -175,14 +186,14 @@ class GlanceImageByIdApi(Resource): self.api = api def get(self, id): - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) from emuvim.api.heat.openstack_dummies.nova_dummy_api import NovaListImages nova = NovaListImages(self.api) return nova.get(id) def put(self, id): - logging.debug("API CALL: %s " % str(self.__class__.__name__)) - logging.warning("Endpoint not implemented") + LOG.debug("API CALL: %s " % str(self.__class__.__name__)) + LOG.warning("Endpoint not implemented") return None diff --git a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py index f696442..107d8fd 100755 --- a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py @@ -8,6 +8,9 @@ import logging import json +LOG = logging.getLogger("api.openstack.heat") + + class HeatDummyApi(BaseOpenstackDummy): def __init__(self, in_ip, in_port, compute): super(HeatDummyApi, self).__init__(in_ip, in_port) @@ -21,6 +24,10 @@ class HeatDummyApi(BaseOpenstackDummy): self.api.add_resource(HeatShowStack, "/v1//stacks/", "/v1//stacks//", resource_class_kwargs={'api': self}) + self.api.add_resource(HeatShowStackTemplate, "/v1//stacks///template", + resource_class_kwargs={'api': self}) + self.api.add_resource(HeatShowStackResources, "/v1//stacks///resources", + resource_class_kwargs={'api': self}) self.api.add_resource(HeatUpdateStack, "/v1//stacks/", "/v1//stacks//", resource_class_kwargs={'api': self}) @@ -35,7 +42,7 @@ class HeatDummyApi(BaseOpenstackDummy): def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) if self.app is not None: self.app.before_request(self.dump_playbook) self.app.run(self.ip, self.port, debug=True, use_reloader=False) @@ -47,7 +54,7 @@ class Shutdown(Resource): """ def get(self): - logging.debug(("%s is beeing shut down") % (__name__)) + LOG.debug(("%s is beeing shut down") % (__name__)) func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') @@ -59,7 +66,7 @@ class HeatListAPIVersions(Resource): self.api = api def get(self): - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['versions'] = dict() @@ -91,7 +98,7 @@ class HeatCreateStack(Resource): 500, if any exception occurred while creation. 201, if everything worked out. """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: stack_dict = json.loads(request.data) @@ -100,14 +107,15 @@ class HeatCreateStack(Resource): return [], 409 stack = Stack() stack.stack_name = stack_dict['stack_name'] - reader = HeatParser(self.api.compute) + reader = HeatParser(self.api.compute) if isinstance(stack_dict['template'], str) or isinstance(stack_dict['template'], unicode): stack_dict['template'] = json.loads(stack_dict['template']) if not reader.parse_input(stack_dict['template'], stack, self.api.compute.dc.label): self.api.compute.clean_broken_stack(stack) return 'Could not create stack.', 400 + stack.template = stack_dict['template'] stack.creation_time = str(datetime.now()) stack.status = "CREATE_COMPLETE" @@ -124,7 +132,7 @@ class HeatCreateStack(Resource): return Response(json.dumps(return_dict), status=201, mimetype="application/json") except Exception as ex: - logging.exception("Heat: Create Stack exception.") + LOG.exception("Heat: Create Stack exception.") return ex.message, 500 def get(self, tenant_id): @@ -136,7 +144,7 @@ class HeatCreateStack(Resource): 500, if any exception occurred. 200, if everything worked out. """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: return_stacks = dict() return_stacks['stacks'] = list() @@ -155,7 +163,7 @@ class HeatCreateStack(Resource): return Response(json.dumps(return_stacks), status=200, mimetype="application/json") except Exception as ex: - logging.exception("Heat: List Stack exception.") + LOG.exception("Heat: List Stack exception.") return ex.message, 500 @@ -174,7 +182,7 @@ class HeatShowStack(Resource): 500, if any exception occurred. 200, if everything worked out. """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: stack = None if stack_name_or_id in self.api.compute.stacks: @@ -223,7 +231,73 @@ class HeatShowStack(Resource): return Response(json.dumps(return_stack), status=200, mimetype="application/json") except Exception as ex: - logging.exception("Heat: Show stack exception.") + LOG.exception("Heat: Show stack exception.") + return ex.message, 500 + + +class HeatShowStackTemplate(Resource): + def __init__(self, api): + self.api = api + + def get(self, tenant_id, stack_name_or_id, stack_id=None): + """ + Returns template of given stack. + + :param tenant_id: + :param stack_name_or_id: + :param stack_id: + :return: Returns a json response which contains the stack's template. + """ + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) + try: + stack = None + if stack_name_or_id in self.api.compute.stacks: + stack = self.api.compute.stacks[stack_name_or_id] + else: + for tmp_stack in self.api.compute.stacks.values(): + if tmp_stack.stack_name == stack_name_or_id: + stack = tmp_stack + if stack is None: + return 'Could not resolve Stack - ID', 404 + + return Response(json.dumps(stack.template), status=200, mimetype="application/json") + + except Exception as ex: + LOG.exception("Heat: Show stack template exception.") + return ex.message, 500 + + +class HeatShowStackResources(Resource): + def __init__(self, api): + self.api = api + + def get(self, tenant_id, stack_name_or_id, stack_id=None): + """ + Returns template of given stack. + + :param tenant_id: + :param stack_name_or_id: + :param stack_id: + :return: Returns a json response which contains the stack's template. + """ + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) + try: + stack = None + if stack_name_or_id in self.api.compute.stacks: + stack = self.api.compute.stacks[stack_name_or_id] + else: + for tmp_stack in self.api.compute.stacks.values(): + if tmp_stack.stack_name == stack_name_or_id: + stack = tmp_stack + if stack is None: + return 'Could not resolve Stack - ID', 404 + + response = {"resources": []} + + return Response(json.dumps(response), status=200, mimetype="application/json") + + except Exception as ex: + LOG.exception("Heat: Show stack template exception.") return ex.message, 500 @@ -232,6 +306,14 @@ class HeatUpdateStack(Resource): self.api = api def put(self, tenant_id, stack_name_or_id, stack_id=None): + LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__)) + return self.update_stack(tenant_id, stack_name_or_id, stack_id) + + def patch(self, tenant_id, stack_name_or_id, stack_id=None): + LOG.debug("API CALL: %s PATCH" % str(self.__class__.__name__)) + return self.update_stack(tenant_id, stack_name_or_id, stack_id) + + def update_stack(self, tenant_id, stack_name_or_id, stack_id=None): """ Updates an existing stack with a new heat template. @@ -243,7 +325,6 @@ class HeatUpdateStack(Resource): 500, if any exception occurred while updating. 202, if everything worked out. """ - logging.debug("API CALL: %s PUT" % str(self.__class__.__name__)) try: old_stack = None if stack_name_or_id in self.api.compute.stacks: @@ -276,7 +357,7 @@ class HeatUpdateStack(Resource): return Response(status=202, mimetype="application/json") except Exception as ex: - logging.exception("Heat: Update Stack exception") + LOG.exception("Heat: Update Stack exception") return ex.message, 500 @@ -294,7 +375,7 @@ class HeatDeleteStack(Resource): :return: 500, if any exception occurred while deletion. 204, if everything worked out. """ - logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) try: if stack_name_or_id in self.api.compute.stacks: self.api.compute.delete_stack(stack_name_or_id) @@ -306,5 +387,5 @@ class HeatDeleteStack(Resource): return Response('Deleted Stack: ' + stack_name_or_id, 204) except Exception as ex: - logging.exception("Heat: Delete Stack exception") + LOG.exception("Heat: Delete Stack exception") return ex.message, 500 diff --git a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py index 26987f0..7abf9c4 100755 --- a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py @@ -4,6 +4,8 @@ from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpen import logging import json +LOG = logging.getLogger("api.openstack.keystone") + class KeystoneDummyApi(BaseOpenstackDummy): def __init__(self, in_ip, in_port): @@ -17,7 +19,7 @@ class KeystoneDummyApi(BaseOpenstackDummy): self.api.add_resource(KeystoneGetTokenv3, "/v3/auth/tokens", resource_class_kwargs={'api': self}) def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) if self.app is not None: self.app.before_request(self.dump_playbook) self.app.run(self.ip, self.port, debug=True, use_reloader=False) @@ -29,7 +31,7 @@ class Shutdown(Resource): """ def get(self): - logging.debug(("%s is beeing shut down") % (__name__)) + LOG.debug(("%s is beeing shut down") % (__name__)) func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') @@ -52,7 +54,7 @@ class KeystoneListVersions(Resource): :return: Returns the api versions. :rtype: :class:`flask.response` containing a static json encoded dict. """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['versions'] = dict() @@ -94,7 +96,7 @@ class KeystoneShowAPIv2(Resource): :return: Returns an openstack style response for all entrypoints. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) neutron_port = self.api.port + 4696 heat_port = self.api.port + 3004 @@ -156,7 +158,7 @@ class KeystoneShowAPIv3(Resource): :return: Returns an openstack style response for all entrypoints. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) neutron_port = self.api.port + 4696 heat_port = self.api.port + 3004 @@ -228,7 +230,7 @@ class KeystoneGetToken(Resource): :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: ret = dict() req = json.loads(request.data) @@ -371,7 +373,7 @@ class KeystoneGetTokenv3(Resource): :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: ret = dict() req = json.loads(request.data) diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py index 38a5ad4..ca1ff3d 100755 --- a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py @@ -8,6 +8,9 @@ import uuid import copy +LOG = logging.getLogger("api.openstack.neutron") + + class NeutronDummyApi(BaseOpenstackDummy): def __init__(self, ip, port, compute): super(NeutronDummyApi, self).__init__(ip, port) @@ -50,7 +53,7 @@ class NeutronDummyApi(BaseOpenstackDummy): resource_class_kwargs={'api': self}) def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port)) if self.app is not None: self.app.before_request(self.dump_playbook) self.app.run(self.ip, self.port, debug=True, use_reloader=False) @@ -58,7 +61,7 @@ class NeutronDummyApi(BaseOpenstackDummy): class Shutdown(Resource): def get(self): - logging.debug(("%s is beeing shut down") % (__name__)) + LOG.debug(("%s is beeing shut down") % (__name__)) func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') @@ -73,7 +76,7 @@ class NeutronListAPIVersions(Resource): :return: Returns a json with API versions. :rtype: :class:`flask.response` """ - logging.debug("API CALL: Neutron - List API Versions") + LOG.debug("API CALL: Neutron - List API Versions") resp = dict() resp['versions'] = dict() @@ -100,7 +103,7 @@ class NeutronShowAPIv2Details(Resource): :return: Returns a json with API details. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['resources'] = dict() @@ -151,7 +154,7 @@ class NeutronListNetworks(Resource): :return: Returns a json response, starting with 'networks' as root node. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: if request.args.get('name'): tmp_network = NeutronShowNetwork(self.api) @@ -181,7 +184,7 @@ class NeutronListNetworks(Resource): return Response(json.dumps(network_dict), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: List networks exception.") + LOG.exception("Neutron: List networks exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -198,7 +201,7 @@ class NeutronShowNetwork(Resource): :return: Returns a json response, starting with 'network' as root node and one network description. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) return self.get_network(network_id, False) def get_network(self, network_name_or_id, as_list): @@ -245,7 +248,7 @@ class NeutronCreateNetwork(Resource): * 201, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: network_dict = json.loads(request.data) name = network_dict['network']['name'] @@ -256,7 +259,7 @@ class NeutronCreateNetwork(Resource): net = self.api.compute.create_network(name) return Response(json.dumps({"network": net.create_network_dict()}), status=201, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Create network excepiton.") + LOG.exception("Neutron: Create network excepiton.") return Response(ex.message, status=500, mimetype='application/json') @@ -275,7 +278,7 @@ class NeutronUpdateNetwork(Resource): * 200, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s PUT" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__)) try: if network_id in self.api.compute.nets: net = self.api.compute.nets[network_id] @@ -300,7 +303,7 @@ class NeutronUpdateNetwork(Resource): return Response('Network not found.\n', status=404, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Show networks exception.") + LOG.exception("Neutron: Show networks exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -319,7 +322,7 @@ class NeutronDeleteNetwork(Resource): * 204, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) try: if network_id not in self.api.compute.nets: return Response('Could not find network. (' + network_id + ')\n', @@ -336,7 +339,7 @@ class NeutronDeleteNetwork(Resource): return Response('Network ' + str(network_id) + ' deleted.\n', status=204, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Delete network exception.") + LOG.exception("Neutron: Delete network exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -352,7 +355,7 @@ class NeutronListSubnets(Resource): :return: Returns a json response, starting with 'subnets' as root node. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: if request.args.get('name'): show_subnet = NeutronShowSubnet(self.api) @@ -381,7 +384,7 @@ class NeutronListSubnets(Resource): return Response(json.dumps(subnet_dict), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: List subnets exception.") + LOG.exception("Neutron: List subnets exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -398,7 +401,7 @@ class NeutronShowSubnet(Resource): :return: Returns a json response, starting with 'subnet' as root node and one subnet description. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) return self.get_subnet(subnet_id, False) def get_subnet(self, subnet_name_or_id, as_list): @@ -426,7 +429,7 @@ class NeutronShowSubnet(Resource): return Response('Subnet not found. (' + subnet_name_or_id + ')\n', status=404, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Show subnet exception.") + LOG.exception("Neutron: Show subnet exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -445,7 +448,7 @@ class NeutronCreateSubnet(Resource): * 201, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: subnet_dict = json.loads(request.data) net = self.api.compute.find_network_by_name_or_id(subnet_dict['subnet']['network_id']) @@ -478,7 +481,7 @@ class NeutronCreateSubnet(Resource): return Response(json.dumps({'subnet': net.create_subnet_dict()}), status=201, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Create network excepiton.") + LOG.exception("Neutron: Create network excepiton.") return Response(ex.message, status=500, mimetype='application/json') @@ -497,7 +500,7 @@ class NeutronUpdateSubnet(Resource): * 200, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s PUT" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__)) try: for net in self.api.compute.nets.values(): if net.subnet_id == subnet_id: @@ -529,7 +532,7 @@ class NeutronUpdateSubnet(Resource): return Response('Network not found.\n', status=404, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Show networks exception.") + LOG.exception("Neutron: Show networks exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -548,7 +551,7 @@ class NeutronDeleteSubnet(Resource): * 204, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) try: for net in self.api.compute.nets.values(): if net.subnet_id == subnet_id: @@ -570,7 +573,7 @@ class NeutronDeleteSubnet(Resource): return Response('Could not find subnet.', status=404, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Delete subnet exception.") + LOG.exception("Neutron: Delete subnet exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -586,7 +589,7 @@ class NeutronListPorts(Resource): :return: Returns a json response, starting with 'ports' as root node. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: if request.args.get('name'): show_port = NeutronShowPort(self.api) @@ -614,7 +617,7 @@ class NeutronListPorts(Resource): return Response(json.dumps(port_dict), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: List ports exception.") + LOG.exception("Neutron: List ports exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -631,7 +634,7 @@ class NeutronShowPort(Resource): :return: Returns a json response, starting with 'port' as root node and one network description. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) return self.get_port(port_id, False) def get_port(self, port_name_or_id, as_list): @@ -657,7 +660,7 @@ class NeutronShowPort(Resource): tmp_dict["port"] = tmp_port_dict return Response(json.dumps(tmp_dict), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Show port exception.") + LOG.exception("Neutron: Show port exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -674,7 +677,7 @@ class NeutronCreatePort(Resource): * 201, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: port_dict = json.loads(request.data) net_id = port_dict['port']['network_id'] @@ -721,7 +724,7 @@ class NeutronCreatePort(Resource): return Response(json.dumps({'port': port.create_port_dict(self.api.compute)}), status=201, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Show port exception.") + LOG.exception("Neutron: Show port exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -740,7 +743,7 @@ class NeutronUpdatePort(Resource): * 200, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s PUT" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__)) try: port_dict = json.loads(request.data) port = self.api.compute.find_port_by_name_or_id(port_id) @@ -782,7 +785,7 @@ class NeutronUpdatePort(Resource): return Response(json.dumps({'port': port.create_port_dict(self.api.compute)}), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Update port exception.") + LOG.exception("Neutron: Update port exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -801,7 +804,7 @@ class NeutronDeletePort(Resource): * 204, if everything worked out. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__)) try: port = self.api.compute.find_port_by_name_or_id(port_id) if port is None: @@ -826,7 +829,7 @@ class NeutronDeletePort(Resource): return Response('Port ' + port_id + ' deleted.\n', status=204, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Delete port exception.") + LOG.exception("Neutron: Delete port exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -870,7 +873,7 @@ class NeutronAddFloatingIp(Resource): :return: Returns a floating network description. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: # Fiddle with floating_network ! req = json.loads(request.data) @@ -911,5 +914,5 @@ class NeutronAddFloatingIp(Resource): return Response(json.dumps(response), status=200, mimetype='application/json') except Exception as ex: - logging.exception("Neutron: Create FloatingIP exception %s.", ex) + LOG.exception("Neutron: Create FloatingIP exception %s.", ex) return Response(ex.message, status=500, mimetype='application/json') diff --git a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py index 7703d33..f294617 100755 --- a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py @@ -7,6 +7,9 @@ import uuid from mininet.link import Link +LOG = logging.getLogger("api.openstack.nova") + + class NovaDummyApi(BaseOpenstackDummy): def __init__(self, in_ip, in_port, compute): super(NovaDummyApi, self).__init__(in_ip, in_port) @@ -41,9 +44,11 @@ class NovaDummyApi(BaseOpenstackDummy): resource_class_kwargs={'api': self}) self.api.add_resource(NovaListImageById, "/v2.1//images/", resource_class_kwargs={'api': self}) + self.api.add_resource(NovaLimits, "/v2.1//limits", + resource_class_kwargs={'api': self}) def _start_flask(self): - logging.info("Starting %s endpoint @ http://%s:%d" % ("NovaDummyApi", self.ip, self.port)) + LOG.info("Starting %s endpoint @ http://%s:%d" % ("NovaDummyApi", self.ip, self.port)) # add some flavors for good measure self.compute.add_flavor('m1.tiny', 1, 512, "MB", 1, "GB") self.compute.add_flavor('m1.nano', 1, 64, "MB", 0, "GB") @@ -60,7 +65,7 @@ class Shutdown(Resource): """ def get(self): - logging.debug(("%s is beeing shut doen") % (__name__)) + LOG.debug(("%s is beeing shut doen") % (__name__)) func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') @@ -78,7 +83,7 @@ class NovaVersionsList(Resource): :return: Returns a json with API versions. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = """ { @@ -105,7 +110,7 @@ class NovaVersionsList(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not show list of versions." % __name__) + LOG.exception(u"%s: Could not show list of versions." % __name__) return ex.message, 500 @@ -122,7 +127,7 @@ class NovaVersionShow(Resource): :return: Returns a json with API details. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = """ @@ -159,7 +164,7 @@ class NovaVersionShow(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not show list of versions." % __name__) + LOG.exception(u"%s: Could not show list of versions." % __name__) return ex.message, 500 @@ -176,7 +181,7 @@ class NovaListServersApi(Resource): :return: Returns a json response with a dictionary that contains the server information. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() @@ -195,7 +200,7 @@ class NovaListServersApi(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of servers." % __name__) + LOG.exception(u"%s: Could not retrieve the list of servers." % __name__) return ex.message, 500 def post(self, id): @@ -207,7 +212,7 @@ class NovaListServersApi(Resource): :return: Returns a flask response, with detailed information about the just created server. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: server_dict = json.loads(request.data)['server'] networks = server_dict.get('networks', None) @@ -244,7 +249,7 @@ class NovaListServersApi(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not create the server." % __name__) + LOG.exception(u"%s: Could not create the server." % __name__) return ex.message, 500 @@ -262,7 +267,7 @@ class NovaListServersAndPortsApi(Resource): :return: Returns a json response with a dictionary that contains the server information. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() @@ -291,7 +296,7 @@ class NovaListServersAndPortsApi(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of servers." % __name__) + LOG.exception(u"%s: Could not retrieve the list of servers." % __name__) return ex.message, 500 @@ -309,7 +314,7 @@ class NovaListServersDetailed(Resource): :return: Returns a flask response, with detailed information aboit the servers and their flavor and image. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = {"servers": list()} @@ -353,7 +358,7 @@ class NovaListServersDetailed(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of servers." % __name__) + LOG.exception(u"%s: Could not retrieve the list of servers." % __name__) return ex.message, 500 @@ -370,7 +375,7 @@ class NovaListFlavors(Resource): :return: Returns a flask response with a list of all flavors. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavors'] = list() @@ -389,13 +394,13 @@ class NovaListFlavors(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of servers." % __name__) + LOG.exception(u"%s: Could not retrieve the list of servers." % __name__) return ex.message, 500 def post(self, id): - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) data = json.loads(request.data).get("flavor") - logging.warning("Create Flavor: %s" % str(data)) + LOG.warning("Create Flavor: %s" % str(data)) # add to internal dict f = self.api.compute.add_flavor( data.get("name"), @@ -425,7 +430,7 @@ class NovaListFlavorsDetails(Resource): :return: Returns a flask response with a list of all flavors with additional information. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavors'] = list() @@ -453,13 +458,13 @@ class NovaListFlavorsDetails(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of servers." % __name__) + LOG.exception(u"%s: Could not retrieve the list of servers." % __name__) return ex.message, 500 def post(self, id): - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) data = json.loads(request.data).get("flavor") - logging.warning("Create Flavor: %s" % str(data)) + LOG.warning("Create Flavor: %s" % str(data)) # add to internal dict f = self.api.compute.add_flavor( data.get("name"), @@ -491,7 +496,7 @@ class NovaListFlavorById(Resource): :return: Returns a flask response with detailed information about the flavor. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavor'] = dict() @@ -512,7 +517,7 @@ class NovaListFlavorById(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve flavor with id %s" % (__name__, flavorid)) + LOG.exception(u"%s: Could not retrieve flavor with id %s" % (__name__, flavorid)) return ex.message, 500 @@ -529,7 +534,7 @@ class NovaListImages(Resource): :return: Returns a flask response with a list of available images. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() @@ -547,7 +552,7 @@ class NovaListImages(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of images." % __name__) + LOG.exception(u"%s: Could not retrieve the list of images." % __name__) return ex.message, 500 @@ -564,7 +569,7 @@ class NovaListImagesDetails(Resource): :return: Returns a flask response with a list of images and their metadata. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() @@ -591,7 +596,7 @@ class NovaListImagesDetails(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the list of images." % __name__) + LOG.exception(u"%s: Could not retrieve the list of images." % __name__) return ex.message, 500 @@ -610,7 +615,7 @@ class NovaListImageById(Resource): :return: Returns a flask response with the information about one image. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() i = resp['image'] = dict() @@ -626,7 +631,7 @@ class NovaListImageById(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve image with id %s." % (__name__, imageid)) + LOG.exception(u"%s: Could not retrieve image with id %s." % (__name__, imageid)) return ex.message, 500 @@ -645,7 +650,7 @@ class NovaShowServerDetails(Resource): :return: Returns a flask response with details about the server. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: server = self.api.compute.find_server_by_name_or_id(serverid) if server is None: @@ -688,7 +693,7 @@ class NovaShowServerDetails(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not retrieve the server details." % __name__) + LOG.exception(u"%s: Could not retrieve the server details." % __name__) return ex.message, 500 def delete(self, id, serverid): @@ -702,7 +707,7 @@ class NovaShowServerDetails(Resource): :return: Returns 200 if everything is fine. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s POST" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: server = self.api.compute.find_server_by_name_or_id(serverid) if server is None: @@ -715,7 +720,7 @@ class NovaShowServerDetails(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not create the server." % __name__) + LOG.exception(u"%s: Could not create the server." % __name__) return ex.message, 500 @@ -734,14 +739,14 @@ class NovaInterfaceToServer(Resource): :return: Returns a flask response with information about the attached interface. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: server = self.api.compute.find_server_by_name_or_id(serverid) if server is None: return Response("Server with id or name %s does not exists." % serverid, status=404) if server.emulator_compute is None: - logging.error("The targeted container does not exist.") + LOG.error("The targeted container does not exist.") return Response("The targeted container of %s does not exist." % serverid, status=404) data = json.loads(request.data).get("interfaceAttachment") resp = dict() @@ -798,7 +803,7 @@ class NovaInterfaceToServer(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not add interface to the server." % __name__) + LOG.exception(u"%s: Could not add interface to the server." % __name__) return ex.message, 500 @@ -820,7 +825,7 @@ class NovaShowAndDeleteInterfaceAtServer(Resource): error message. :rtype: :class:`flask.response` """ - logging.debug("API CALL: %s GET" % str(self.__class__.__name__)) + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: server = self.api.compute.find_server_by_name_or_id(serverid) if server is None: @@ -840,5 +845,58 @@ class NovaShowAndDeleteInterfaceAtServer(Resource): return response except Exception as ex: - logging.exception(u"%s: Could not detach interface from the server." % __name__) + LOG.exception(u"%s: Could not detach interface from the server." % __name__) + return ex.message, 500 + + +class NovaLimits(Resource): + def __init__(self, api): + self.api = api + + def get(self, id): + """ + Returns the resource limits of the emulated cloud. + https://developer.openstack.org/api-ref/compute/?expanded=show-rate-and-absolute-limits-detail#limits-limits + + TODO: For now we only return fixed limits, not based on the real deployment. + + :param id: tenant id, used for the 'href' link + :type id: ``str`` + :return: Returns the resource limits. + :rtype: :class:`flask.response` + """ + LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) + try: + resp = { + "limits": { + "absolute": { + "maxImageMeta": 12800, + "maxPersonality": 500, + "maxPersonalitySize": 1024000, + "maxSecurityGroupRules": 2000, + "maxSecurityGroups": 1000, + "maxServerMeta": 12800, + "maxTotalCores": 2000, + "maxTotalFloatingIps": 1000, + "maxTotalInstances": 1000, + "maxTotalKeypairs": 1000, + "maxTotalRAMSize": 5120000, + "maxServerGroups": 1000, + "maxServerGroupMembers": 1000, + "totalCoresUsed": 0, + "totalInstancesUsed": 0, + "totalRAMUsed": 0, + "totalSecurityGroupsUsed": 0, + "totalFloatingIpsUsed": 0, + "totalServerGroupsUsed": 0 + }, + "rate": [] + } + } + response = Response(json.dumps(resp), status=200, mimetype="application/json") + response.headers['Access-Control-Allow-Origin'] = '*' + return response + + except Exception as ex: + LOG.exception(u"%s: Could not retrieve the list of images." % __name__) return ex.message, 500 diff --git a/src/emuvim/api/openstack/resources/stack.py b/src/emuvim/api/openstack/resources/stack.py index a02cbab..45fe3e9 100755 --- a/src/emuvim/api/openstack/resources/stack.py +++ b/src/emuvim/api/openstack/resources/stack.py @@ -11,6 +11,7 @@ class Stack: self.creation_time = None self.update_time = None self.status = None + self.template = None if id is None: self.id = str(uuid.uuid4()) else: diff --git a/src/emuvim/api/rest/compute.py b/src/emuvim/api/rest/compute.py index b657660..28a92c4 100755 --- a/src/emuvim/api/rest/compute.py +++ b/src/emuvim/api/rest/compute.py @@ -31,7 +31,7 @@ from flask import request import json from copy import deepcopy -logging.basicConfig(level=logging.INFO) +logging.basicConfig() CORS_HEADER = {'Access-Control-Allow-Origin': '*'} diff --git a/src/emuvim/api/rest/monitor.py b/src/emuvim/api/rest/monitor.py index 30422c1..bf0f26b 100755 --- a/src/emuvim/api/rest/monitor.py +++ b/src/emuvim/api/rest/monitor.py @@ -37,7 +37,7 @@ from flask_restful import Resource, reqparse from flask import request import json -logging.basicConfig(level=logging.INFO) +logging.basicConfig() CORS_HEADER = {'Access-Control-Allow-Origin': '*'} @@ -326,4 +326,4 @@ class MonitorTerminal(Resource): return str(c), 200, CORS_HEADER except Exception as ex: logging.exception("API error.") - return ex.message, 500, CORS_HEADER \ No newline at end of file + return ex.message, 500, CORS_HEADER diff --git a/src/emuvim/api/rest/network.py b/src/emuvim/api/rest/network.py index 0479ee6..9aab1e6 100755 --- a/src/emuvim/api/rest/network.py +++ b/src/emuvim/api/rest/network.py @@ -38,7 +38,7 @@ from flask import request import json import networkx -logging.basicConfig(level=logging.DEBUG) +logging.basicConfig() CORS_HEADER = {'Access-Control-Allow-Origin': '*'} @@ -149,4 +149,4 @@ class DrawD3jsgraph(Resource): links.append(edge_dict) json = {"nodes":nodes, "links":links} - return json, 200, CORS_HEADER \ No newline at end of file + return json, 200, CORS_HEADER diff --git a/src/emuvim/api/rest/rest_api_endpoint.py b/src/emuvim/api/rest/rest_api_endpoint.py index b2a7b86..b5f29d4 100755 --- a/src/emuvim/api/rest/rest_api_endpoint.py +++ b/src/emuvim/api/rest/rest_api_endpoint.py @@ -46,7 +46,7 @@ from monitor import MonitorInterfaceAction, MonitorFlowAction, MonitorLinkAction import pkg_resources from os import path -logging.basicConfig(level=logging.INFO) +logging.basicConfig() class RestApiEndpoint(object): diff --git a/src/emuvim/dcemulator/monitoring.py b/src/emuvim/dcemulator/monitoring.py index 0d40531..21985cb 100755 --- a/src/emuvim/dcemulator/monitoring.py +++ b/src/emuvim/dcemulator/monitoring.py @@ -40,7 +40,7 @@ import docker import json from copy import deepcopy -logging.basicConfig(level=logging.INFO) +logging.basicConfig() """ class to read openflow stats from the Ryu controller of the DCNetwork