Commit e04bb068 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis
Browse files

cyclades: Assign new resources to a project

Add optional parameter `project' in API calls that create VMs, networks,
and floating IPs. If missing, user's base project is assumed (same uuid
as the user).
parent 3d2045de
...@@ -453,6 +453,7 @@ imageRef Image id ✔ ✔ ...@@ -453,6 +453,7 @@ imageRef Image id ✔ ✔
flavorRef Resources flavor ✔ ✔ flavorRef Resources flavor ✔ ✔
personality Personality contents ✔ ✔ personality Personality contents ✔ ✔
metadata Custom metadata ✔ ✔ metadata Custom metadata ✔ ✔
project Project assignment ✔ **✘**
=========== ==================== ======== ========== =========== ==================== ======== ==========
* **name** can be any string * **name** can be any string
...@@ -463,6 +464,10 @@ metadata Custom metadata ✔ ✔ ...@@ -463,6 +464,10 @@ metadata Custom metadata ✔ ✔
* **metadata** are ``key``:``value`` pairs of custom server-specific metadata. * **metadata** are ``key``:``value`` pairs of custom server-specific metadata.
There are no semantic limitations. There are no semantic limitations.
* **project** (optional) is the project where the VM is to be assigned. If not
given, user's base project is assumed (identified with the same uuid as the
user).
* **personality** (optional) is a list of personality injections. A personality * **personality** (optional) is a list of personality injections. A personality
injection is a way to add a file into a virtual server while creating it. injection is a way to add a file into a virtual server while creating it.
Each change modifies/creates a file on the virtual server. The injected data Each change modifies/creates a file on the virtual server. The injected data
...@@ -2937,6 +2942,7 @@ cidr6 IPv6 CDIR **✘** null ...@@ -2937,6 +2942,7 @@ cidr6 IPv6 CDIR **✘** null
gateway IPv4 gateway address **✘** null gateway IPv4 gateway address **✘** null
gateway6 IPv6 gateway address **✘** null gateway6 IPv6 gateway address **✘** null
public If a public network **✘** False public If a public network **✘** False
project Project assignment **✘** base project
================== ======================= ======== ======= ================== ======================= ======== =======
* **name** is a string * **name** is a string
...@@ -2951,6 +2957,10 @@ public If a public network **✘** False ...@@ -2951,6 +2957,10 @@ public If a public network **✘** False
* **public** should better not be used. If True, a 403 error is returned. * **public** should better not be used. If True, a 403 error is returned.
* **project** (optional) is the project where the network is to be assigned.
If not given, user's base project is assumed (identified with the same uuid
as the user).
*Example Create Network Request Body: JSON* *Example Create Network Request Body: JSON*
.. code-block:: javascript .. code-block:: javascript
......
...@@ -144,6 +144,7 @@ def allocate_floating_ip(request): ...@@ -144,6 +144,7 @@ def allocate_floating_ip(request):
log.info('allocate_floating_ip %s', req) log.info('allocate_floating_ip %s', req)
userid = request.user_uniq userid = request.user_uniq
project = floating_ip_dict.get("project", None)
# the network_pool is a mandatory field # the network_pool is a mandatory field
network_id = api.utils.get_attribute(floating_ip_dict, network_id = api.utils.get_attribute(floating_ip_dict,
...@@ -151,7 +152,7 @@ def allocate_floating_ip(request): ...@@ -151,7 +152,7 @@ def allocate_floating_ip(request):
required=False, required=False,
attr_type=(basestring, int)) attr_type=(basestring, int))
if network_id is None: if network_id is None:
floating_ip = ips.create_floating_ip(userid) floating_ip = ips.create_floating_ip(userid, project=project)
else: else:
try: try:
network_id = int(network_id) network_id = int(network_id)
...@@ -164,7 +165,8 @@ def allocate_floating_ip(request): ...@@ -164,7 +165,8 @@ def allocate_floating_ip(request):
"floating_ip_address", "floating_ip_address",
required=False, required=False,
attr_type=basestring) attr_type=basestring)
floating_ip = ips.create_floating_ip(userid, network, address) floating_ip = ips.create_floating_ip(userid, network, address,
project=project)
log.info("User '%s' allocated floating IP '%s'", userid, floating_ip) log.info("User '%s' allocated floating IP '%s'", userid, floating_ip)
request.serialization = "json" request.serialization = "json"
......
...@@ -128,8 +128,9 @@ def create_network(request): ...@@ -128,8 +128,9 @@ def create_network(request):
if name is None: if name is None:
name = "" name = ""
project = network_dict.get('project', None)
network = networks.create(userid=userid, name=name, flavor=flavor, network = networks.create(userid=userid, name=name, flavor=flavor,
public=False) public=False, project=project)
networkdict = network_to_dict(network, detail=True) networkdict = network_to_dict(network, detail=True)
response = render_network(request, networkdict, status=201) response = render_network(request, networkdict, status=201)
......
...@@ -385,6 +385,7 @@ def create_server(request): ...@@ -385,6 +385,7 @@ def create_server(request):
networks = server.get("networks") networks = server.get("networks")
if networks is not None: if networks is not None:
assert isinstance(networks, list) assert isinstance(networks, list)
project = server.get("project")
except (KeyError, AssertionError): except (KeyError, AssertionError):
raise faults.BadRequest("Malformed request") raise faults.BadRequest("Malformed request")
...@@ -403,7 +404,7 @@ def create_server(request): ...@@ -403,7 +404,7 @@ def create_server(request):
vm = servers.create(user_id, name, password, flavor, image, vm = servers.create(user_id, name, password, flavor, image,
metadata=metadata, personality=personality, metadata=metadata, personality=personality,
networks=networks) project=project, networks=networks)
server = vm_to_dict(vm, detail=True) server = vm_to_dict(vm, detail=True)
server['status'] = 'BUILD' server['status'] = 'BUILD'
......
...@@ -143,7 +143,7 @@ def allocate_public_ip(userid, floating_ip=False, backend=None, networks=None): ...@@ -143,7 +143,7 @@ def allocate_public_ip(userid, floating_ip=False, backend=None, networks=None):
@transaction.commit_on_success @transaction.commit_on_success
def create_floating_ip(userid, network=None, address=None): def create_floating_ip(userid, network=None, address=None, project=None):
if network is None: if network is None:
floating_ip = allocate_public_ip(userid, floating_ip=True) floating_ip = allocate_public_ip(userid, floating_ip=True)
else: else:
...@@ -159,6 +159,10 @@ def create_floating_ip(userid, network=None, address=None): ...@@ -159,6 +159,10 @@ def create_floating_ip(userid, network=None, address=None):
floating_ip = allocate_ip(network, userid, address=address, floating_ip = allocate_ip(network, userid, address=address,
floating_ip=True) floating_ip=True)
if project is None:
project = userid
floating_ip.project = project
floating_ip.save()
# Issue commission (quotas) # Issue commission (quotas)
quotas.issue_and_accept_commission(floating_ip) quotas.issue_and_accept_commission(floating_ip)
transaction.commit() transaction.commit()
......
...@@ -66,7 +66,8 @@ def network_command(action): ...@@ -66,7 +66,8 @@ def network_command(action):
@transaction.commit_on_success @transaction.commit_on_success
def create(userid, name, flavor, link=None, mac_prefix=None, mode=None, def create(userid, name, flavor, link=None, mac_prefix=None, mode=None,
floating_ip_pool=False, tags=None, public=False, drained=False): floating_ip_pool=False, tags=None, public=False, drained=False,
project=None):
if flavor is None: if flavor is None:
raise faults.BadRequest("Missing request parameter 'type'") raise faults.BadRequest("Missing request parameter 'type'")
elif flavor not in Network.FLAVORS.keys(): elif flavor not in Network.FLAVORS.keys():
...@@ -101,9 +102,13 @@ def create(userid, name, flavor, link=None, mac_prefix=None, mode=None, ...@@ -101,9 +102,13 @@ def create(userid, name, flavor, link=None, mac_prefix=None, mode=None,
msg = "Link '%s' is already used." % link msg = "Link '%s' is already used." % link
raise faults.BadRequest(msg) raise faults.BadRequest(msg)
if project is None:
project = userid
network = Network.objects.create( network = Network.objects.create(
name=name, name=name,
userid=userid, userid=userid,
project=project,
flavor=flavor, flavor=flavor,
mode=mode, mode=mode,
link=link, link=link,
......
...@@ -165,7 +165,7 @@ def server_command(action, action_fields=None): ...@@ -165,7 +165,7 @@ def server_command(action, action_fields=None):
@transaction.commit_on_success @transaction.commit_on_success
def create(userid, name, password, flavor, image, metadata={}, def create(userid, name, password, flavor, image, metadata={},
personality=[], networks=None, use_backend=None): personality=[], networks=None, use_backend=None, project=None):
if use_backend is None: if use_backend is None:
# Allocate server to a Ganeti backend # Allocate server to a Ganeti backend
use_backend = allocate_new_server(userid, flavor) use_backend = allocate_new_server(userid, flavor)
...@@ -188,11 +188,15 @@ def create(userid, name, password, flavor, image, metadata={}, ...@@ -188,11 +188,15 @@ def create(userid, name, password, flavor, image, metadata={},
else: else:
flavor.disk_provider = None flavor.disk_provider = None
if project is None:
project = userid
# We must save the VM instance now, so that it gets a valid # We must save the VM instance now, so that it gets a valid
# vm.backend_vm_id. # vm.backend_vm_id.
vm = VirtualMachine.objects.create(name=name, vm = VirtualMachine.objects.create(name=name,
backend=use_backend, backend=use_backend,
userid=userid, userid=userid,
project=project,
imageid=image["id"], imageid=image["id"],
flavor=flavor, flavor=flavor,
operstate="BUILD") operstate="BUILD")
......
...@@ -46,7 +46,6 @@ log = logging.getLogger(__name__) ...@@ -46,7 +46,6 @@ log = logging.getLogger(__name__)
QUOTABLE_RESOURCES = [VirtualMachine, Network, IPAddress] QUOTABLE_RESOURCES = [VirtualMachine, Network, IPAddress]
DEFAULT_SOURCE = 'system'
RESOURCES = [ RESOURCES = [
"cyclades.vm", "cyclades.vm",
"cyclades.total_cpu", "cyclades.total_cpu",
...@@ -108,7 +107,7 @@ def issue_commission(resource, action, name="", force=False, auto_accept=False, ...@@ -108,7 +107,7 @@ def issue_commission(resource, action, name="", force=False, auto_accept=False,
return None return None
user = resource.userid user = resource.userid
source = DEFAULT_SOURCE source = resource.project
qh = Quotaholder.get() qh = Quotaholder.get()
if True: # placeholder if True: # placeholder
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment