def get(self, id, serverid): """ Returns detailed information about the specified server. :param id: tenant id, used for the 'href' link :type id: ``str`` :param serverid: Specifies the requested server. :type serverid: ``str`` :return: Returns a flask response with details about the server. :rtype: :class:`flask.response` """ 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) s = server.create_server_dict() s['links'] = [{ 'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id) }] flavor = self.api.compute.flavors[server.flavor] s['flavor'] = { "id": flavor.id, "links": [{ "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id), "rel": "bookmark" }] } image = self.api.compute.images[server.image] s['image'] = { "id": image.id, "links": [{ "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id), "rel": "bookmark" }] } response = Response(json.dumps({'server': s}), 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 server details." % __name__) return ex.message, 500
def get(self, id, serverid): """ Returns detailed information about the specified server. :param id: tenant id, used for the 'href' link :type id: ``str`` :param serverid: Specifies the requested server. :type serverid: ``str`` :return: Returns a flask response with details about the server. :rtype: :class:`flask.response` """ 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) s = server.create_server_dict() s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id)}] flavor = self.api.compute.flavors[server.flavor] s['flavor'] = { "id": flavor.id, "links": [ { "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id), "rel": "bookmark" } ] } image = self.api.compute.images[server.image] s['image'] = { "id": image.id, "links": [ { "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id), "rel": "bookmark" } ] } response = Response(json.dumps( {'server': s}), 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 server details." % __name__) return ex.message, 500
def get(self, id): """ As List Servers, it lists all running servers and their details but furthermore it also states the used flavor and the server image. :param id: tenant id, used for the 'href' link. :type id: ``str`` :return: Returns a flask response, with detailed information aboit the servers and their flavor and image. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = {"servers": list()} for server in self.api.compute.computeUnits.values(): s = server.create_server_dict(self.api.compute) s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id)}] flavor = self.api.compute.flavors[server.flavor] s['flavor'] = { "id": flavor.id, "links": [ { "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id), "rel": "bookmark" } ] } image = self.api.compute.images[server.image] s['image'] = { "id": image.id, "links": [ { "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id), "rel": "bookmark" } ] } resp['servers'].append(s) 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 servers." % __name__) return ex.message, 500
def get(self, id): """ As List Servers, it lists all running servers and their details but furthermore it also states the used flavor and the server image. :param id: tenant id, used for the 'href' link. :type id: ``str`` :return: Returns a flask response, with detailed information aboit the servers and their flavor and image. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = {"servers": list()} for server in self.api.compute.computeUnits.values(): s = server.create_server_dict(self.api.compute) s['links'] = [{ 'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id) }] flavor = self.api.compute.flavors[server.flavor] s['flavor'] = { "id": flavor.id, "links": [{ "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id), "rel": "bookmark" }] } image = self.api.compute.images[server.image] s['image'] = { "id": image.id, "links": [{ "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id), "rel": "bookmark" }] } resp['servers'].append(s) 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 servers." % __name__) return ex.message, 500
def get(self, id, flavorid): """ Returns details about one flavor. :param id: tenant id, used for the 'href' link :type id: ``str`` :param flavorid: Represents the flavor. :type flavorid: ``str`` :return: Returns a flask response with detailed information about the flavor. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavor'] = dict() flavor = self.api.compute.flavors.get(flavorid, None) if flavor is None: for f in self.api.compute.flavors.values(): if f.id == flavorid: flavor = f break resp['flavor']['id'] = flavor.id resp['flavor']['name'] = flavor.name resp['flavor']['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id)}] 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 flavor with id %s" % (__name__, flavorid)) return ex.message, 500
def get(self, id): """ Creates a list of all usable images. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of available images. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() for image in self.api.compute.images.values(): f = dict() f['id'] = image.id f['name'] = str(image.name).replace(":latest", "") f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id)}] resp['images'].append(f) 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
def get(self): """ List API entrypoints. :return: Returns an openstack style response for all entrypoints. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) # neutron_port = self.api.port + 4696 # heat_port = self.api.port + 3004 resp = dict() resp['version'] = { "status": "stable", "media-types": [ { "base": "application/json", "type": "application/vnd.openstack.identity-v3.0+json" } ], "id": "v3.0", "links": [ { "href": "http://%s:%d/v3.0" % (get_host(request), self.api.port), "rel": "self" } ] } return Response(json.dumps(resp), status=200, mimetype='application/json')
def get(self, id): """ Creates a list with all running servers and their detailed information. :param id: Used to create a individual link to quarry further information. :type id: ``str`` :return: Returns a json response with a dictionary that contains the server information. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['servers'] = list() for server in self.api.compute.computeUnits.values(): s = server.create_server_dict(self.api.compute) s['links'] = [{ 'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id) }] resp['servers'].append(s) 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 servers." % __name__) return ex.message, 500
def get(self, id): """ Lists all available flavors. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of all flavors. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavors'] = list() for flavor in self.api.compute.flavors.values(): f = flavor.__dict__.copy() f['id'] = flavor.id f['name'] = flavor.name f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id)}] resp['flavors'].append(f) 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 servers." % __name__) return str(ex), 500
def get(self, id): """ Creates a list with all running servers and their detailed information. :param id: Used to create a individual link to quarry further information. :type id: ``str`` :return: Returns a json response with a dictionary that contains the server information. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['servers'] = list() for server in self.api.compute.computeUnits.values(): s = server.create_server_dict(self.api.compute) s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request), self.api.port, id, server.id)}] resp['servers'].append(s) 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 servers." % __name__) return ex.message, 500
def get(self, id): """ Creates a list of all usable images. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of available images. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() for image in self.api.compute.images.values(): f = dict() f['id'] = image.id f['name'] = str(image.name).replace(":latest", "") f['links'] = [{ 'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id) }] resp['images'].append(f) 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
def get(self): """ List API versions. :return: Returns the api versions. :rtype: :class:`flask.response` containing a static json encoded dict. """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['versions'] = dict() version = [{ "id": "v2.0", "links": [ { "href": "http://%s:%d/v2.0" % (get_host(request), self.api.port), "rel": "self" } ], "media-types": [ { "base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json" } ], "status": "stable", "updated": "2014-04-17T00:00:00Z" }] resp['versions']['values'] = version return Response(json.dumps(resp), status=200, mimetype='application/json')
def post(self): """ This one is a real fake! It does not really create anything and the mentioned image 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. """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: body_data = json.loads(request.data) except: body_data = dict() # 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 str(img_name) in image.name: img_id = image.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() f['id'] = img_id f['name'] = img_name f['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1" f['container_format'] = img_container_format f['disk_format'] = img_disk_format f['size'] = img_size f['created_at'] = "2016-03-15T15:09:07.000000" f['deleted'] = False f['deleted_at'] = None f['is_public'] = img_is_public f['min_disk'] = 1 f['min_ram'] = 128 f['owner'] = "3dad48f09e2a447a9bf852bcd93548c1" f['properties'] = {} f['protected'] = False f['status'] = "active" f['updated_at'] = "2016-03-15T15:09:07.000000" f['virtual_size'] = 1 resp['image'] = f # build actual response with headers and everything r = Response(json.dumps(resp), status=201, mimetype="application/json") r.headers.add("Location", "http://%s:%d/v1/images/%s" % (get_host(request), self.api.port, img_id)) return r
def post(self, tenant_id): """ Create and deploy a new stack. :param tenant_id: :return: 409, if the stack name was already used. 400, if the heat template could not be parsed properly. 500, if any exception occurred while creation. 201, if everything worked out. """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: stack_dict = json.loads(request.data) for stack in self.api.compute.stacks.values(): if stack.stack_name == stack_dict['stack_name']: return [], 409 stack = Stack() stack.stack_name = stack_dict['stack_name'] 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" return_dict = { "stack": { "id": stack.id, "links": [{ "href": "http://%s:%s/v1/%s/stacks/%s" % (get_host(request), self.api.port, tenant_id, stack.id), "rel": "self" }] } } self.api.compute.add_stack(stack) self.api.compute.deploy_stack(stack.id) return Response(json.dumps(return_dict), status=201, mimetype="application/json") except Exception as ex: LOG.exception("Heat: Create Stack exception.") return ex.message, 500
def post(self, tenant_id): """ Create and deploy a new stack. :param tenant_id: :return: 409, if the stack name was already used. 400, if the heat template could not be parsed properly. 500, if any exception occurred while creation. 201, if everything worked out. """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: stack_dict = json.loads(request.data) for stack in self.api.compute.stacks.values(): if stack.stack_name == stack_dict['stack_name']: return [], 409 stack = Stack() stack.stack_name = stack_dict['stack_name'] 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" return_dict = {"stack": {"id": stack.id, "links": [ { "href": "http://%s:%s/v1/%s/stacks/%s" % (get_host(request), self.api.port, tenant_id, stack.id), "rel": "self" }]}} self.api.compute.add_stack(stack) self.api.compute.deploy_stack(stack.id) return Response(json.dumps(return_dict), status=201, mimetype="application/json") except Exception as ex: LOG.exception("Heat: Create Stack exception.") return ex.message, 500
def get(self, id): """ Returns API details. :param id: :type id: ``str`` :return: Returns a json with API details. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = """ { "version": { "id": "v2.1", "links": [ { "href": "http://%s:%d/v2.1/", "rel": "self" }, { "href": "http://docs.openstack.org/", "rel": "describedby", "type": "text/html" } ], "media-types": [ { "base": "application/json", "type": "application/vnd.openstack.compute+json;version=2.1" } ], "status": "CURRENT", "version": "2.38", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } } """ % (get_host(request), self.api.port) response = Response(resp, status=200, mimetype="application/json") response.headers['Access-Control-Allow-Origin'] = '*' return response except Exception as ex: LOG.exception(u"%s: Could not show list of versions." % __name__) return ex.message, 500
def get(self): LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) resp = dict() resp['versions'] = dict() resp['versions'] = [{ "status": "CURRENT", "id": "v1.0", "links": [ { "href": "http://%s:%d/v2.0" % (get_host(request), self.api.port), "rel": "self" } ] }] return Response(json.dumps(resp), status=200, mimetype="application/json")
def post(self, id): LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) data = json.loads(request.data).get("flavor") LOG.warning("Create Flavor: %s" % str(data)) # add to internal dict f = self.api.compute.add_flavor( data.get("name"), data.get("vcpus"), data.get("ram"), "MB", data.get("disk"), "GB") # create response based on incoming data data["id"] = f.id data["links"] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, f.id)}] resp = {"flavor": data} return Response(json.dumps(resp), status=200, mimetype="application/json")
def get(self, id): """ Lists all flavors with additional information like ram and disk space. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of all flavors with additional information. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavors'] = list() for flavor in self.api.compute.flavors.values(): # use the class dict. it should work fine # but use a copy so we don't modifiy the original f = flavor.__dict__.copy() # add additional expected stuff stay openstack compatible f['links'] = [{ 'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id) }] f['OS-FLV-DISABLED:disabled'] = False f['OS-FLV-EXT-DATA:ephemeral'] = 0 f['os-flavor-access:is_public'] = True f['ram'] = flavor.memory f['vcpus'] = flavor.cpu f['swap'] = 0 f['disk'] = flavor.storage f['rxtx_factor'] = 1.0 resp['flavors'].append(f) 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 servers." % __name__) return ex.message, 500
def get(self, id): """ As List Images but with additional metadata. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of images and their metadata. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() for image in self.api.compute.images.values(): # use the class dict. it should work fine # but use a copy so we don't modifiy the original f = image.__dict__.copy() # add additional expected stuff stay openstack compatible f['name'] = str(image.name).replace(":latest", "") f['links'] = [{ 'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id) }] f['metadata'] = { "architecture": "x86_64", "auto_disk_config": "True", "kernel_id": "nokernel", "ramdisk_id": "nokernel" } resp['images'].append(f) 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
def get(self, id): """ Lists all flavors with additional information like ram and disk space. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of all flavors with additional information. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['flavors'] = list() for flavor in self.api.compute.flavors.values(): # use the class dict. it should work fine # but use a copy so we don't modifiy the original f = flavor.__dict__.copy() # add additional expected stuff stay openstack compatible f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request), self.api.port, id, flavor.id)}] f['OS-FLV-DISABLED:disabled'] = False f['OS-FLV-EXT-DATA:ephemeral'] = 0 f['os-flavor-access:is_public'] = True f['ram'] = flavor.memory f['vcpus'] = flavor.cpu f['swap'] = 0 f['disk'] = flavor.storage f['rxtx_factor'] = 1.0 resp['flavors'].append(f) 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 servers." % __name__) return ex.message, 500
def get(self, id): """ As List Images but with additional metadata. :param id: tenant id, used for the 'href' link :type id: ``str`` :return: Returns a flask response with a list of images and their metadata. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = dict() resp['images'] = list() for image in self.api.compute.images.values(): # use the class dict. it should work fine # but use a copy so we don't modifiy the original f = image.__dict__.copy() # add additional expected stuff stay openstack compatible f['name'] = str(image.name).replace(":latest", "") f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request), self.api.port, id, image.id)}] f['metadata'] = { "architecture": "x86_64", "auto_disk_config": "True", "kernel_id": "nokernel", "ramdisk_id": "nokernel" } resp['images'].append(f) 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
def get(self): """ Lists API versions. :return: Returns a json with API versions. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__)) try: resp = """ { "versions": [ { "id": "v2.1", "links": [ { "href": "http://%s:%d/v2.1/", "rel": "self" } ], "status": "CURRENT", "version": "2.38", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } ] } """ % (get_host(request), self.api.port) response = Response(resp, status=200, mimetype="application/json") response.headers['Access-Control-Allow-Origin'] = '*' return response except Exception as ex: LOG.exception(u"%s: Could not show list of versions." % __name__) return ex.message, 500
def post(self): """ List API entrypoints. This is hardcoded. For a working "authentication" use these ENVVARS: * OS_AUTH_URL=http://<ip>:<port>/v2.0 * OS_IDENTITY_API_VERSION=2.0 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57 * OS_REGION_NAME=RegionOne * OS_USERNAME=bla * OS_PASSWORD=bla :return: Returns an openstack style response for all entrypoints. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: ret = dict() req = json.loads(request.data) ret['access'] = dict() ret['access']['token'] = dict() token = ret['access']['token'] token['issued_at'] = "2014-01-30T15:30:58.819Z" token['expires'] = "2999-01-30T15:30:58.819Z" token['id'] = req['auth'].get( 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id') token['tenant'] = dict() token['tenant']['description'] = None token['tenant']['enabled'] = True token['tenant']['id'] = req['auth'].get( 'tenantId', 'fc394f2ab2df4114bde39905f800dc57') token['tenant']['name'] = "tenantName" ret['access']['user'] = dict() user = ret['access']['user'] user['username'] = req.get('username', "username") user['name'] = "tenantName" user['roles_links'] = list() user['id'] = token['tenant'].get( 'id', "fc394f2ab2df4114bde39905f800dc57") user['roles'] = [{'name': 'Member'}] ret['access']['region_name'] = "RegionOne" ret['access']['serviceCatalog'] = [{ "endpoints": [ { "adminURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']), "region": "RegionOne", "internalURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']), "id": "2dad48f09e2a447a9bf852bcd93548ef", "publicURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']) } ], "endpoints_links": [], "type": "compute", "name": "nova" }, { "endpoints": [ { "adminURL": "http://%s:%s/v2.0" % (get_host(request), self.api.port), "region": "RegionOne", "internalURL": "http://%s:%s/v2.0" % (get_host(request), self.api.port), "id": "2dad48f09e2a447a9bf852bcd93543fc", "publicURL": "http://%s:%s/v2" % (get_host(request), self.api.port) } ], "endpoints_links": [], "type": "identity", "name": "keystone" }, { "endpoints": [ { "adminURL": "http://%s:%s" % (get_host(request), self.api.port + 4696), "region": "RegionOne", "internalURL": "http://%s:%s" % (get_host(request), self.api.port + 4696), "id": "2dad48f09e2a447a9bf852bcd93548cf", "publicURL": "http://%s:%s" % (get_host(request), self.api.port + 4696) } ], "endpoints_links": [], "type": "network", "name": "neutron" }, { "endpoints": [ { "adminURL": "http://%s:%s" % (get_host(request), self.api.port + 4242), "region": "RegionOne", "internalURL": "http://%s:%s" % (get_host(request), self.api.port + 4242), "id": "2dad48f09e2a447a9bf852bcd93548cf", "publicURL": "http://%s:%s" % (get_host(request), self.api.port + 4242) } ], "endpoints_links": [], "type": "image", "name": "glance" }, { "endpoints": [ { "adminURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']), "region": "RegionOne", "internalURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']), "id": "2dad48f09e2a447a9bf852bcd93548bf", "publicURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']) } ], "endpoints_links": [], "type": "orchestration", "name": "heat" } ] ret['access']["metadata"] = { "is_admin": 0, "roles": [ "7598ac3c634d4c3da4b9126a5f67ca2b" ] }, ret['access']['trust'] = { "id": "394998fa61f14736b1f0c1f322882949", "trustee_user_id": "269348fdd9374b8885da1418e0730af1", "trustor_user_id": "3ec3164f750146be97f21559ee4d9c51", "impersonation": False } return Response(json.dumps(ret), status=200, mimetype='application/json') except Exception as ex: logging.exception("Keystone: Get token failed.") return ex.message, 500
def get(self, tenant_id, stack_name_or_id, stack_id=None): """ Calculates detailed information about the requested stack. :param tenant_id: :param stack_name_or_id: :param stack_id: :return: Returns a json response which contains information like the stack id, name, status, creation time. 500, if any exception occurred. 200, if everything worked out. """ 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_stack = { "stack": { "capabilities": [], "creation_time": stack.creation_time, "description": "desc of " + stack.stack_name, "disable_rollback": True, "id": stack.id, "links": [{ "href": "http://%s:%s/v1/%s/stacks/%s" % (get_host(request), self.api.port, tenant_id, stack.id), "rel": "self" }], "notification_topics": [], "outputs": [], "parameters": { "OS::project_id": "3ab5b02f-a01f-4f95-afa1-e254afc4a435", # add real project id "OS::stack_id": stack.id, "OS::stack_name": stack.stack_name }, "stack_name": stack.stack_name, "stack_owner": "The owner of the stack.", # add stack owner "stack_status": stack.status, "stack_status_reason": "The reason for the current status of the stack.", # add status reason "template_description": "The description of the stack template.", "stack_user_project_id": "The project UUID of the stack user.", "timeout_mins": "", "updated_time": "", "parent": "", "tags": "" } } return Response(json.dumps(return_stack), status=200, mimetype="application/json") except Exception as ex: LOG.exception("Heat: Show stack exception.") return ex.message, 500
def get(self, tenant_id, stack_name_or_id, stack_id=None): """ Calculates detailed information about the requested stack. :param tenant_id: :param stack_name_or_id: :param stack_id: :return: Returns a json response which contains information like the stack id, name, status, creation time. 500, if any exception occurred. 200, if everything worked out. """ 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_stack = { "stack": { "capabilities": [], "creation_time": stack.creation_time, "description": "desc of " + stack.stack_name, "disable_rollback": True, "id": stack.id, "links": [ { "href": "http://%s:%s/v1/%s/stacks/%s" % (get_host(request), self.api.port, tenant_id, stack.id), "rel": "self" } ], "notification_topics": [], "outputs": [], "parameters": { "OS::project_id": "3ab5b02f-a01f-4f95-afa1-e254afc4a435", # add real project id "OS::stack_id": stack.id, "OS::stack_name": stack.stack_name }, "stack_name": stack.stack_name, "stack_owner": "The owner of the stack.", # add stack owner "stack_status": stack.status, # add status reason "stack_status_reason": "The reason for the current status of the stack.", "template_description": "The description of the stack template.", "stack_user_project_id": "The project UUID of the stack user.", "timeout_mins": "", "updated_time": "", "parent": "", "tags": "" } } return Response(json.dumps(return_stack), status=200, mimetype="application/json") except Exception as ex: LOG.exception("Heat: Show stack exception.") return ex.message, 500
def post(self): """ This one is a real fake! It does not really create anything and the mentioned image 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. """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: body_data = json.loads(request.data) except: body_data = dict() # 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 str(img_name) in image.name: img_id = image.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() f['id'] = img_id f['name'] = img_name f['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1" f['container_format'] = img_container_format f['disk_format'] = img_disk_format f['size'] = img_size f['created_at'] = "2016-03-15T15:09:07.000000" f['deleted'] = False f['deleted_at'] = None f['is_public'] = img_is_public f['min_disk'] = 1 f['min_ram'] = 128 f['owner'] = "3dad48f09e2a447a9bf852bcd93548c1" f['properties'] = {} f['protected'] = False f['status'] = "active" f['updated_at'] = "2016-03-15T15:09:07.000000" f['virtual_size'] = 1 resp['image'] = f # build actual response with headers and everything r = Response(json.dumps(resp), status=201, mimetype="application/json") r.headers.add( "Location", "http://%s:%d/v1/images/%s" % (get_host(request), self.api.port, img_id)) return r
def post(self): """ List API entrypoints. This is hardcoded. For a working "authentication" use these ENVVARS: * OS_AUTH_URL=http://<ip>:<port>/v3 * OS_IDENTITY_API_VERSION=2.0 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57 * OS_REGION_NAME=RegionOne * OS_USERNAME=bla * OS_PASSWORD=bla :return: Returns an openstack style response for all entrypoints. :rtype: :class:`flask.response` """ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__)) try: ret = dict() req = json.loads(request.data) ret['token'] = dict() token = ret['token'] token['issued_at'] = "2014-01-30T15:30:58.819Z" token['expires_at'] = "2999-01-30T15:30:58.819Z" token['methods'] = ["password"] token['extras'] = dict() token['user'] = dict() user = token['user'] user['id'] = req['auth'].get( 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id') user['name'] = "tenantName" user['password_expires_at'] = None user['domain'] = {"id": "default", "name": "Default"} token['audit_ids'] = ["ZzZwkUflQfygX7pdYDBCQQ"] # project token['project'] = { "domain": { "id": "default", "name": "Default" }, "id": "8538a3f13f9541b28c2620eb19065e45", "name": "tenantName" } # catalog token['catalog'] = [{ "endpoints": [ { "url": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']), "region": "RegionOne", "interface": "public", "id": "2dad48f09e2a447a9bf852bcd93548ef" } ], "id": "2dad48f09e2a447a9bf852bcd93548ef", "type": "compute", "name": "nova" }, { "endpoints": [ { "url": "http://%s:%s/v2.0" % (get_host(request), self.api.port), "region": "RegionOne", "interface": "public", "id": "2dad48f09e2a447a9bf852bcd93543fc" } ], "id": "2dad48f09e2a447a9bf852bcd93543fc", "type": "identity", "name": "keystone" }, { "endpoints": [ { "url": "http://%s:%s" % (get_host(request), self.api.port + 4696), "region": "RegionOne", "interface": "public", "id": "2dad48f09e2a447a9bf852bcd93548cf" } ], "id": "2dad48f09e2a447a9bf852bcd93548cf", "type": "network", "name": "neutron" }, { "endpoints": [ { "url": "http://%s:%s" % (get_host(request), self.api.port + 4242), "region": "RegionOne", "interface": "public", "id": "2dad48f09e2a447a9bf852bcd93548cf" } ], "id": "2dad48f09e2a447a9bf852bcd93548cf", "type": "image", "name": "glance" }, { "endpoints": [ { "url": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']), "region": "RegionOne", "interface": "public", "id": "2dad48f09e2a447a9bf852bcd93548bf" } ], "id": "2dad48f09e2a447a9bf852bcd93548bf", "type": "orchestration", "name": "heat" } ] return Response(json.dumps(ret), status=201, mimetype='application/json') except Exception as ex: logging.exception("Keystone: Get token failed.") return ex.message, 500