def get_cyclades_stats(request): images = True backend = None if request.body: req = utils.get_request_dict(request) req_stats = utils.get_attribute(req, "stats", required=True, attr_type=dict) # Check backend backend_id = utils.get_attribute(req_stats, "backend", required=False, attr_type=(basestring, int)) if backend_id is not None: try: try: backend_id = int(backend_id) backend = Backend.objects.get(id=backend_id) except (ValueError, TypeError): backend = Backend.objects.get(clustername=backend_id) except Backend.DoesNotExist: raise faults.BadRequest("Invalid backend '%s'" % backend_id) include_images = utils.get_attribute(req_stats, "images", required=False, attr_type=bool) if include_images is not None: images = include_images _stats = stats.get_cyclades_stats(backend=backend, clusters=True, servers=True, resources=True, networks=True, images=images) data = json.dumps(_stats) return http.HttpResponse(data, status=200, content_type='application/json')
def update_server_name(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # buildInProgress (409), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_name %s %s', server_id, req) try: name = req['server']['name'] except (TypeError, KeyError): raise faults.BadRequest("Malformed request") vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_suspended=True) vm.name = name vm.save() return HttpResponse(status=204)
def update_metadata(request, server_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_metadata %s %s', server_id, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) metadata = utils.get_attribute(req, "metadata", required=True, attr_type=dict) for key, val in metadata.items(): if not isinstance(key, (basestring, int)) or\ not isinstance(val, (basestring, int)): raise faults.BadRequest("Malformed Request. Invalid metadata.") meta, created = vm.metadata.get_or_create(meta_key=key) meta.meta_value = val meta.save() vm.save() vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, vm_meta, status=201)
def update_metadata(request, image_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info("update_image_metadata %s %s", image_id, req) with image_backend(request.user_uniq) as backend: image = backend.get_image(image_id) try: metadata = req["metadata"] assert isinstance(metadata, dict) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request.") properties = image["properties"] properties.update(metadata) backend.update_metadata(image_id, dict(properties=properties)) return util.render_metadata(request, properties, status=201)
def update_metadata(request, image_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('update_image_metadata %s %s', image_id, req) with image_backend(request.user_uniq) as backend: image = backend.get_image(image_id) try: metadata = req['metadata'] assert isinstance(metadata, dict) except (KeyError, AssertionError): raise faults.BadRequest('Malformed request.') properties = image['properties'] properties.update(metadata) backend.update_metadata(image_id, dict(properties=properties)) return util.render_metadata(request, properties, status=201)
def update_metadata(request, server_id): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_metadata %s %s', server_id, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) try: metadata = req['metadata'] assert isinstance(metadata, dict) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") for key, val in metadata.items(): meta, created = vm.metadata.get_or_create(meta_key=key) meta.meta_value = val meta.save() vm.save() vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) return util.render_metadata(request, vm_meta, status=201)
def create_metadata_item(request, image_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('create_image_metadata_item %s %s %s', image_id, key, req) try: metadict = req['meta'] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest('Malformed request.') val = metadict[key] with image_backend(request.user_uniq) as backend: image = backend.get_image(image_id) properties = image['properties'] properties[key] = val backend.update_metadata(image_id, dict(properties=properties)) return util.render_meta(request, {key: val}, status=201)
def create_metadata_item(request, server_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info('create_server_metadata_item %s %s %s', server_id, key, req) vm = util.get_vm(server_id, request.user_uniq, non_suspended=True) try: metadict = req['meta'] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") meta, created = VirtualMachineMetadata.objects.get_or_create( meta_key=key, vm=vm) meta.meta_value = metadict[key] meta.save() vm.save() d = {meta.meta_key: meta.meta_value} return util.render_meta(request, d, status=201)
def update_network_name(request, network_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # forbidden (403) # badMediaType(415), # itemNotFound (404), # overLimit (413) req = utils.get_request_dict(request) log.info('update_network_name %s', network_id) try: name = req['network']['name'] except (TypeError, KeyError): raise faults.BadRequest('Malformed request.') net = util.get_network(network_id, request.user_uniq) if net.public: raise faults.Forbidden('Can not rename the public network.') if net.deleted: raise faults.BadRequest("Network has been deleted.") net.name = name net.save() return HttpResponse(status=204)
def allocate_floating_ip(request): """Allocate a floating IP.""" req = utils.get_request_dict(request) floating_ip_dict = api.utils.get_attribute(req, "floatingip", required=True, attr_type=dict) userid = request.user_uniq log.info('allocate_floating_ip user: %s request: %s', userid, req) # the network_pool is a mandatory field network_id = api.utils.get_attribute(floating_ip_dict, "floating_network_id", required=False, attr_type=(basestring, int)) if network_id is None: floating_ip = ips.create_floating_ip(userid) else: try: network_id = int(network_id) except ValueError: raise faults.BadRequest("Invalid networkd ID.") network = util.get_network(network_id, userid, for_update=True, non_deleted=True) address = api.utils.get_attribute(floating_ip_dict, "floating_ip_address", required=False, attr_type=basestring) floating_ip = ips.create_floating_ip(userid, network, address) log.info("User '%s' allocated floating IP '%s'", userid, floating_ip) request.serialization = "json" data = json.dumps({"floatingip": ip_to_dict(floating_ip)}) return HttpResponse(data, status=200)
def create_metadata_item(request, image_id, key): # Normal Response Code: 201 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # itemNotFound (404), # badRequest (400), # buildInProgress (409), # badMediaType(415), # overLimit (413) req = utils.get_request_dict(request) log.info("create_image_metadata_item %s %s %s", image_id, key, req) try: metadict = req["meta"] assert isinstance(metadict, dict) assert len(metadict) == 1 assert key in metadict except (KeyError, AssertionError): raise faults.BadRequest("Malformed request.") val = metadict[key] with image_backend(request.user_uniq) as backend: image = backend.get_image(image_id) properties = image["properties"] properties[key] = val backend.update_metadata(image_id, dict(properties=properties)) return util.render_meta(request, {key: val}, status=201)
def server_action(request, server_id): req = utils.get_request_dict(request) log.debug('server_action %s %s', server_id, req) if len(req) != 1: raise faults.BadRequest("Malformed request") # Do not allow any action on deleted or suspended VMs vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_deleted=True, non_suspended=True) try: key = req.keys()[0] if key not in ARBITRARY_ACTIONS: start_action(vm, key_to_action(key)) val = req[key] assert isinstance(val, dict) return server_actions[key](request, vm, val) except KeyError: raise faults.BadRequest("Unknown action") except AssertionError: raise faults.BadRequest("Invalid argument")
def authenticate(request): try: content_length = get_content_length(request) except faults.LengthRequired: content_length = None public_mode = True if not content_length else False d = defaultdict(dict) if not public_mode: req = utils.get_request_dict(request) uuid = None try: token_id = req['auth']['token']['id'] except KeyError: try: token_id = req['auth']['passwordCredentials']['password'] uuid = req['auth']['passwordCredentials']['username'] except KeyError: raise faults.BadRequest( 'Malformed request: missing credentials') tenant = req['auth'].get('tenantName') if token_id is None: raise faults.BadRequest('Malformed request: missing token') try: user = AstakosUser.objects.get(auth_token=token_id) except AstakosUser.DoesNotExist: raise faults.Unauthorized('Invalid token') validate_user(user) if uuid is not None: if user.uuid != uuid: raise faults.Unauthorized('Invalid credentials') if tenant: if user.uuid != tenant: raise faults.BadRequest('Not conforming tenantName') d["access"]["token"] = { "id": user.auth_token, "expires": utils.isoformat(user.auth_token_expires), "tenant": {"id": user.uuid, "name": user.realname}} d["access"]["user"] = { "id": user.uuid, 'name': user.realname, "roles": [dict(id=str(g['id']), name=g['name']) for g in user.groups.values('id', 'name')], "roles_links": []} d["access"]["serviceCatalog"] = get_endpoints() if request.serialization == 'xml': return xml_response({'d': d}, 'api/access.xml') else: return json_response(d)
def create_server(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # itemNotFound (404), # badRequest (400), # serverCapacityUnavailable (503), # overLimit (413) req = utils.get_request_dict(request) user_id = request.user_uniq log.info('create_server user: %s request: %s', user_id, req) try: server = req['server'] name = server['name'] metadata = server.get('metadata', {}) assert isinstance(metadata, dict) image_id = server['imageRef'] flavor_id = server['flavorRef'] personality = server.get('personality', []) assert isinstance(personality, list) networks = server.get("networks") if networks is not None: assert isinstance(networks, list) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") # Verify that personalities are well-formed util.verify_personality(personality) # Get image information image = util.get_image_dict(image_id, user_id) # Get flavor (ensure it is active) flavor = util.get_flavor(flavor_id, include_deleted=False) if not flavor.allow_create: msg = ("It is not allowed to create a server from flavor with id '%d'," " see 'allow_create' flavor attribute") raise faults.Forbidden(msg % flavor.id) # Generate password password = util.random_password() vm = servers.create(user_id, name, password, flavor, image, metadata=metadata, personality=personality, networks=networks) server = vm_to_dict(vm, detail=True) server['status'] = 'BUILD' server['adminPass'] = password response = render_server(request, server, status=202) return response
def create_server(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # itemNotFound (404), # badRequest (400), # serverCapacityUnavailable (503), # overLimit (413) req = utils.get_request_dict(request) log.info('create_server %s', req) user_id = request.user_uniq try: server = req['server'] name = server['name'] metadata = server.get('metadata', {}) assert isinstance(metadata, dict) image_id = server['imageRef'] flavor_id = server['flavorRef'] personality = server.get('personality', []) assert isinstance(personality, list) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") # Verify that personalities are well-formed util.verify_personality(personality) # Get image information image = util.get_image_dict(image_id, user_id) # Get flavor (ensure it is active) flavor = util.get_flavor(flavor_id, include_deleted=False) # Generate password password = util.random_password() vm = do_create_server(user_id, name, password, flavor, image, metadata=metadata, personality=personality) server = vm_to_dict(vm, detail=True) server['status'] = 'BUILD' server['adminPass'] = password response = render_server(request, server, status=202) return response
def network_action(request, network_id): req = utils.get_request_dict(request) log.debug('network_action %s %s', network_id, req) if len(req) != 1: raise faults.BadRequest('Malformed request.') net = util.get_network(network_id, request.user_uniq) if net.public: raise faults.Forbidden('Can not modify the public network.') if net.deleted: raise faults.BadRequest("Network has been deleted.") try: key = req.keys()[0] val = req[key] assert isinstance(val, dict) return network_actions[key](request, net, req[key]) except KeyError: raise faults.BadRequest('Unknown action.') except AssertionError: raise faults.BadRequest('Invalid argument.')
def update_subnet(request, sub_id): """Update the fields of a subnet Only the name can be updated, everything else returns BadRequest """ dictionary = utils.get_request_dict(request) user_id = request.user_uniq try: subnet = dictionary['subnet'] except KeyError: raise api.faults.BadRequest("Malformed request") if len(subnet) != 1 or "name" not in subnet: raise api.faults.BadRequest("Only the name of a subnet can be updated") name = subnet.get("name", None) subnet_dict = subnet_to_dict(subnets.update_subnet(sub_id, name, user_id)) data = json.dumps({'subnet': subnet_dict}) return HttpResponse(data, status=200)
def demux_server_action(request, server_id): req = utils.get_request_dict(request) log.debug('server_action %s %s', server_id, req) if not isinstance(req, dict) and len(req) != 1: raise faults.BadRequest("Malformed request") # Do not allow any action on deleted or suspended VMs vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_deleted=True, non_suspended=True) action = req.keys()[0] if not isinstance(action, basestring): raise faults.BadRequest("Malformed Request. Invalid action.") if key_to_action(action) not in [x[0] for x in VirtualMachine.ACTIONS]: if action not in ARBITRARY_ACTIONS: raise faults.BadRequest("Action %s not supported" % action) action_args = utils.get_attribute(req, action, required=True, attr_type=dict) return server_actions[action](request, vm, action_args)
def update_server_name(request, server_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badRequest (400), # badMediaType(415), # itemNotFound (404), # buildInProgress (409), # overLimit (413) req = utils.get_request_dict(request) log.info('update_server_name %s %s', server_id, req) req = utils.get_attribute(req, "server", attr_type=dict, required=True) name = utils.get_attribute(req, "name", attr_type=basestring, required=True) vm = util.get_vm(server_id, request.user_uniq, for_update=True, non_suspended=True) servers.rename(vm, new_name=name) return HttpResponse(status=204)
def authenticate(request): try: content_length = get_content_length(request) except faults.LengthRequired: content_length = None public_mode = True if not content_length else False d = defaultdict(dict) if not public_mode: req = utils.get_request_dict(request) uuid = None try: token_id = req['auth']['token']['id'] except KeyError: try: token_id = req['auth']['passwordCredentials']['password'] uuid = req['auth']['passwordCredentials']['username'] except KeyError: raise faults.BadRequest( 'Malformed request: missing credentials') tenant = req['auth'].get('tenantName') if token_id is None: raise faults.BadRequest('Malformed request: missing token') try: user = AstakosUser.objects.get(auth_token=token_id) except AstakosUser.DoesNotExist: raise faults.Unauthorized('Invalid token') validate_user(user) if uuid is not None: if user.uuid != uuid: raise faults.Unauthorized('Invalid credentials') if tenant: if user.uuid != tenant: raise faults.BadRequest('Not conforming tenantName') d["access"]["token"] = { "id": user.auth_token, "expires": utils.isoformat(user.auth_token_expires), "tenant": { "id": user.uuid, "name": user.realname } } d["access"]["user"] = { "id": user.uuid, 'name': user.realname, "roles": [ dict(id=str(g['id']), name=g['name']) for g in user.groups.values('id', 'name') ], "roles_links": [] } d["access"]["serviceCatalog"] = get_endpoints() if request.serialization == 'xml': return xml_response({'d': d}, 'api/access.xml') else: return json_response(d)
def create_subnet(request): """Create a subnet network_id and the desired cidr are mandatory, everything else is optional """ dictionary = utils.get_request_dict(request) user_id = request.user_uniq log.info('create subnet user: %s request: %s', user_id, dictionary) try: subnet = dictionary['subnet'] network_id = subnet['network_id'] cidr = subnet['cidr'] except KeyError: raise api.faults.BadRequest("Malformed request") name = subnet.get('name', None) ipversion = subnet.get('ip_version', 4) allocation_pools = subnet.get('allocation_pools', None) if allocation_pools is not None: allocation_pools = parse_ip_pools(allocation_pools) try: cidr_ip = ipaddr.IPNetwork(cidr) except ValueError: raise api.faults.BadRequest("Malformed CIDR '%s'" % cidr) # If no gateway is specified, send an empty string, because None is used # if the user wants no gateway at all gateway = subnet.get('gateway_ip', "") if gateway is "": gateway = str(cidr_ip.network + 1) dhcp = subnet.get('enable_dhcp', True) slaac = subnet.get('enable_slaac', None) if ipversion == 6: if slaac is not None: dhcp = check_boolean_value(slaac, "enable_slaac") else: dhcp = check_boolean_value(dhcp, "dhcp") else: dhcp = check_boolean_value(dhcp, "dhcp") dns = subnet.get('dns_nameservers', None) hosts = subnet.get('host_routes', None) sub = subnets.create_subnet(network_id=network_id, cidr=cidr, name=name, ipversion=ipversion, gateway=gateway, dhcp=dhcp, slaac=slaac, dns_nameservers=dns, allocation_pools=allocation_pools, host_routes=hosts, user_id=user_id) subnet_dict = subnet_to_dict(sub) data = json.dumps({'subnet': subnet_dict}) return HttpResponse(data, status=201)
def create_network(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # badRequest (400), # forbidden (403) # overLimit (413) req = utils.get_request_dict(request) log.info('create_network %s', req) user_id = request.user_uniq try: d = req['network'] name = d['name'] except KeyError: raise faults.BadRequest("Malformed request") # Get and validate flavor. Flavors are still exposed as 'type' in the # API. flavor = d.get("type", None) if flavor is None: raise faults.BadRequest("Missing request parameter 'type'") elif flavor not in Network.FLAVORS.keys(): raise faults.BadRequest("Invalid network type '%s'" % flavor) elif flavor not in settings.API_ENABLED_NETWORK_FLAVORS: raise faults.Forbidden("Can not create network of type '%s'" % flavor) public = d.get("public", False) if public: raise faults.Forbidden("Can not create a public network.") dhcp = d.get('dhcp', True) # Get and validate network parameters subnet = d.get('cidr', '192.168.1.0/24') subnet6 = d.get('cidr6', None) gateway = d.get('gateway', None) gateway6 = d.get('gateway6', None) # Check that user provided a valid subnet util.validate_network_params(subnet, gateway, subnet6, gateway6) try: mode, link, mac_prefix, tags = util.values_from_flavor(flavor) validate_mac(mac_prefix + "0:00:00:00") network = Network.objects.create( name=name, userid=user_id, subnet=subnet, subnet6=subnet6, gateway=gateway, gateway6=gateway6, dhcp=dhcp, flavor=flavor, mode=mode, link=link, mac_prefix=mac_prefix, tags=tags, action='CREATE', state='ACTIVE') except EmptyPool: log.error("Failed to allocate resources for network of type: %s", flavor) raise faults.ServiceUnavailable("Failed to allocate network resources") # Issue commission to Quotaholder and accept it since at the end of # this transaction the Network object will be created in the DB. # Note: the following call does a commit! quotas.issue_and_accept_commission(network) networkdict = network_to_dict(network, request.user_uniq) response = render_network(request, networkdict, status=202) return response
def authenticate(request): try: content_length = get_content_length(request) except faults.LengthRequired: content_length = None public_mode = True if not content_length else False d = defaultdict(dict) if not public_mode: req = utils.get_request_dict(request) uuid = None try: token_id = req['auth']['token']['id'] except KeyError: try: token_id = req['auth']['passwordCredentials']['password'] uuid = req['auth']['passwordCredentials']['username'] except KeyError: raise faults.BadRequest( 'Malformed request: missing credentials') tenant = req['auth'].get('tenantName') if token_id is None: raise faults.BadRequest('Malformed request: missing token') try: user = AstakosUser.objects.get(auth_token=token_id) except AstakosUser.DoesNotExist: raise faults.Unauthorized('Invalid token') validate_user(user) if uuid is not None: if user.uuid != uuid: raise faults.Unauthorized('Invalid credentials') if tenant: if user.uuid != tenant: raise faults.BadRequest('Not conforming tenantName') d["access"]["token"] = { "id": user.auth_token, "expires": utils.isoformat(user.auth_token_expires), "tenant": {"id": user.uuid, "name": user.realname}} d["access"]["user"] = { "id": user.uuid, 'name': user.realname, "roles": list(user.groups.values("id", "name")), "roles_links": []} d["access"]["serviceCatalog"] = [] append = d["access"]["serviceCatalog"].append for s in Service.objects.all().order_by("id"): endpoints = [] for l in [e.data.values('key', 'value') for e in s.endpoints.all()]: endpoint = dict((d['key'], d['value']) for d in l) endpoint["SNF:uiURL"] = s.component.url endpoint["region"] = "default" if s.name == 'astakos_weblogin': endpoint["SNF:webloginURL"] = endpoint["publicURL"] endpoints.append(endpoint) append({"name": s.name, "type": s.type, "endpoints": endpoints, "endpoints_links": []}) if request.serialization == 'xml': return xml_response({'d': d}, 'api/access.xml') else: return json_response(d)
def create_network(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # badRequest (400), # forbidden (403) # overLimit (413) try: req = utils.get_request_dict(request) log.info('create_network %s', req) user_id = request.user_uniq try: d = req['network'] name = d['name'] except KeyError: raise faults.BadRequest("Malformed request") # Get and validate flavor. Flavors are still exposed as 'type' in the # API. flavor = d.get("type", None) if flavor is None: raise faults.BadRequest("Missing request parameter 'type'") elif flavor not in Network.FLAVORS.keys(): raise faults.BadRequest("Invalid network type '%s'" % flavor) elif flavor not in settings.API_ENABLED_NETWORK_FLAVORS: raise faults.Forbidden("Can not create network of type '%s'" % flavor) public = d.get("public", False) if public: raise faults.Forbidden("Can not create a public network.") dhcp = d.get('dhcp', True) # Get and validate network parameters subnet = d.get('cidr', '192.168.1.0/24') subnet6 = d.get('cidr6', None) gateway = d.get('gateway', None) gateway6 = d.get('gateway6', None) # Check that user provided a valid subnet util.validate_network_params(subnet, gateway, subnet6, gateway6) try: mode, link, mac_prefix, tags = util.values_from_flavor(flavor) validate_mac(mac_prefix + "0:00:00:00") network = Network.objects.create( name=name, userid=user_id, subnet=subnet, subnet6=subnet6, gateway=gateway, gateway6=gateway6, dhcp=dhcp, flavor=flavor, mode=mode, link=link, mac_prefix=mac_prefix, tags=tags, action='CREATE', state='ACTIVE') except EmptyPool: log.error("Failed to allocate resources for network of type: %s", flavor) raise faults.ServiceUnavailable("Failed to allocate network" " resources") # Issue commission to Quotaholder and accept it since at the end of # this transaction the Network object will be created in the DB. # Note: the following call does a commit! quotas.issue_and_accept_commission(network) except: transaction.rollback() raise else: transaction.commit() networkdict = network_to_dict(network, request.user_uniq) response = render_network(request, networkdict, status=202) return response