From 29c287ffea52cb16872f8037348eda2fd008c9dd Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Thu, 11 Apr 2013 21:07:16 -0400 Subject: [PATCH] merge latest code --- plstackapi/core/api/deployment_networks.py | 16 +- plstackapi/core/api/flavors.py | 12 +- plstackapi/core/api/images.py | 12 +- plstackapi/core/api/keys.py | 34 +-- plstackapi/core/api/nodes.py | 34 +++ plstackapi/core/api/roles.py | 19 +- plstackapi/core/api/site_privileges.py | 69 ++++++ plstackapi/core/api/sites.py | 19 +- plstackapi/core/api/slice_memberships.py | 69 ++++++ plstackapi/core/api/slices.py | 63 ++--- plstackapi/core/api/slivers.py | 74 ++++++ plstackapi/core/api/subnets.py | 61 +++++ plstackapi/core/api/users.py | 39 ++-- plstackapi/core/api_root.py | 2 + plstackapi/core/fixtures/initial_data.json | 2 +- plstackapi/core/models.py | 234 ------------------- plstackapi/core/models/role.py | 5 - plstackapi/core/models/site.py | 14 -- plstackapi/core/models/slice.py | 42 ---- plstackapi/core/models/sliver.py | 17 +- plstackapi/core/models/subnet.py | 23 -- plstackapi/core/serializers.py | 75 ++++-- plstackapi/core/urls.py | 59 ++++- plstackapi/core/views.py | 58 ----- plstackapi/core/views/deployment_networks.py | 4 +- plstackapi/core/views/flavors.py | 2 +- plstackapi/core/views/images.py | 2 +- plstackapi/core/views/keys.py | 4 +- plstackapi/core/views/nodes.py | 55 +++++ plstackapi/core/views/roles.py | 4 +- plstackapi/core/views/site_privileges.py | 66 ++++++ plstackapi/core/views/slice_memberships.py | 66 ++++++ plstackapi/core/views/slices.py | 4 +- plstackapi/core/views/slivers.py | 66 ++++++ plstackapi/core/views/subnets.py | 66 ++++++ plstackapi/openstack/driver.py | 3 +- 36 files changed, 869 insertions(+), 525 deletions(-) create mode 100644 plstackapi/core/api/nodes.py create mode 100644 plstackapi/core/api/site_privileges.py create mode 100644 plstackapi/core/api/slice_memberships.py create mode 100644 plstackapi/core/api/slivers.py create mode 100644 plstackapi/core/api/subnets.py delete mode 100644 plstackapi/core/models.py delete mode 100644 plstackapi/core/views.py create mode 100644 plstackapi/core/views/nodes.py create mode 100644 plstackapi/core/views/site_privileges.py create mode 100644 plstackapi/core/views/slice_memberships.py create mode 100644 plstackapi/core/views/slivers.py create mode 100644 plstackapi/core/views/subnets.py diff --git a/plstackapi/core/api/deployment_networks.py b/plstackapi/core/api/deployment_networks.py index 812ca15..80b4ff3 100644 --- a/plstackapi/core/api/deployment_networks.py +++ b/plstackapi/core/api/deployment_networks.py @@ -2,7 +2,17 @@ from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import DeploymentNetwork - + +def _get_deployment_networks(filter): + if isinstance(filter, int): + deployment_networks = DeploymentNetwork.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + deployment_networks = DeploymentNetwork.objects.filter(name=filter) + elif isinstance(filer, dict): + deployment_networks = DeploymentNetwork.objects.filter(**filter) + else: + deployment_networks = [] + return deployment_networks def add_deployment_network(auth, name): auth_check(auth) @@ -12,14 +22,14 @@ def add_deployment_network(auth, name): def delete_deployment_network(auth, filter={}): auth_check(auth) - deployments = DeploymentNetwork.objects.filter(**filter) + deployments = _get_deployment_networks(filter) for deployment in deployments: deployment.delete() return 1 def get_deployment_networks(auth, filter={}): auth_check(auth) - deployments = DeploymentNetwork.objects.filter(**filter) + deployments = _get_deployment_networks(filter) return deployments diff --git a/plstackapi/core/api/flavors.py b/plstackapi/core/api/flavors.py index a2d0b23..ee55f73 100644 --- a/plstackapi/core/api/flavors.py +++ b/plstackapi/core/api/flavors.py @@ -3,6 +3,16 @@ from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import Flavor +def _get_flavors(filter): + if isinstance(filter, int): + flavors = Flavor.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + flavors = Flavor.objects.filter(name=filter) + elif isinstance(filer, dict): + flavors = Flavor.objects.filter(**filter) + else: + flavors = [] + return flavors def add_flavor(auth, fields={}): """not implemented""" @@ -14,7 +24,7 @@ def delete_flavor(auth, filter={}): def get_flavors(auth, filter={}): auth_check(auth) - flavors = Flavor.objects.filter(**filter) + flavors = _get_flavors(filter) return flavors diff --git a/plstackapi/core/api/images.py b/plstackapi/core/api/images.py index b773b0b..0b14043 100644 --- a/plstackapi/core/api/images.py +++ b/plstackapi/core/api/images.py @@ -3,6 +3,16 @@ from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import Image +def _get_images(filter): + if isinstance(filter, int): + images = image.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + images = image.objects.filter(name=filter) + elif isinstance(filer, dict): + images = image.objects.filter(**filter) + else: + images = [] + return images def add_image(auth, fields={}): """not implemented""" @@ -14,7 +24,7 @@ def delete_image(auth, filter={}): def get_images(auth, filter={}): auth_check(auth) - images = Image.objects.filter(**filter) + images = _get_images(filter) return images diff --git a/plstackapi/core/api/keys.py b/plstackapi/core/api/keys.py index b255e98..2c90140 100644 --- a/plstackapi/core/api/keys.py +++ b/plstackapi/core/api/keys.py @@ -2,24 +2,24 @@ from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import Key, User - -def lookup_user(fields): - user = None - if 'user' in fields: - if isinstance(fields['user'], int): - users = User.objects.filter(id=fields['user']) - else: - users = User.objects.filter(email=fields['user']) - if users: - user = users[0] - if not user: - raise Exception, "No such user: %s" % fields['user'] - return user +from plstackapi.core.api.users import _get_users + + +def _get_keys(filter): + if isinstance(filter, int): + keys = Key.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + keys = Key.objects.filter(name=filter) + elif isinstance(filer, dict): + keys = Key.objects.filter(**filter) + else: + keys = [] + return keys def add_key(auth, fields): driver = OpenStackDriver(client = auth_check(auth)) - user = lookup_user(fields) - if user: fields['user'] = user + users = _get_users(fields.get('user')) + if users: fields['user'] = users[0] key = Key(**fields) nova_fields = {'name': key.name, 'key': key.key} @@ -32,7 +32,7 @@ def update_key(auth, id, **fields): def delete_key(auth, filter={}): driver = OpenStackDriver(client = auth_check(auth)) - keys = Key.objects.filter(**filter) + keys = _get_keys(filter) for key in keys: driver.delete_keypair(name=key.name) key.delete() @@ -40,7 +40,7 @@ def delete_key(auth, filter={}): def get_keys(auth, filter={}): client = auth_check(auth) - keys = Key.objects.filter(**filter) + keys = _get_keys(filter) return keys diff --git a/plstackapi/core/api/nodes.py b/plstackapi/core/api/nodes.py new file mode 100644 index 0000000..47934ba --- /dev/null +++ b/plstackapi/core/api/nodes.py @@ -0,0 +1,34 @@ +from plstackapi.openstack.client import OpenStackClient +from plstackapi.openstack.driver import OpenStackDriver +from plstackapi.core.api.auth import auth_check +from plstackapi.core.models import Node + +def _get_nodes(filter): + if isinstance(filter, int): + nodes = Node.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + nodes = Node.objects.filter(name=filter) + elif isinstance(filer, dict): + nodes = Node.objects.filter(**filter) + else: + nodes = [] + return nodes + +def add_node(auth, fields={}): + """not implemented""" + return + +def delete_node(auth, filter={}): + """not implemented""" + return 1 + +def update_node(auth, id, fields={}): + return + +def get_nodes(auth, filter={}): + auth_check(auth) + nodes = _get_nodes(filter) + return nodes + + + diff --git a/plstackapi/core/api/roles.py b/plstackapi/core/api/roles.py index 844fb4f..6c61e25 100644 --- a/plstackapi/core/api/roles.py +++ b/plstackapi/core/api/roles.py @@ -1,9 +1,21 @@ +from types import StringTypes from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import Role +def _get_roles(filter): + if isinstance(filter, int): + roles = Role.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + roles = Role.objects.filter(role_type=filter) + elif isinstance(filter, dict): + roles = Role.objects.filter(**filter) + else: + roles = [] + return roles + def add_role(auth, name): driver = OpenStackDriver(client = auth_check(auth)) keystone_role = driver.create_role(name=name) @@ -13,7 +25,7 @@ def add_role(auth, name): def delete_role(auth, filter={}): driver = OpenStackDriver(client = auth_check(auth)) - roles = Role.objects.filter(**filter) + roles = _get_roles(filter) for role in roles: driver.delete_role({'id': role.role_id}) role.delete() @@ -21,8 +33,5 @@ def delete_role(auth, filter={}): def get_roles(auth, filter={}): client = auth_check(auth) - roles = Role.objects.filter(**filter) - return roles + return _get_roles(filter) - - diff --git a/plstackapi/core/api/site_privileges.py b/plstackapi/core/api/site_privileges.py new file mode 100644 index 0000000..4c4158e --- /dev/null +++ b/plstackapi/core/api/site_privileges.py @@ -0,0 +1,69 @@ +import re +from plstackapi.openstack.client import OpenStackClient +from plstackapi.openstack.driver import OpenStackDriver +from plstackapi.core.api.auth import auth_check +from plstackapi.core.models import SitePrivilege, Site, Role, User +from plstackapi.core.api.users import _get_users +from plstackapi.core.api.sites import _get_sites +from plstackapi.core.api.roles import _get_roles + + +def _get_site_privileges(filter): + if isinstance(filter, int): + site_privileges = SitePrivilege.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + site_privileges = SitePrivilege.objects.filter(name=filter) + elif isinstance(filer, dict): + site_privileges = SitePrivilege.objects.filter(**filter) + else: + site_privileges = [] + return site_privileges + +def add_site_privilege(auth, fields): + driver = OpenStackDriver(client = auth_check(auth)) + users = _get_user(fields.get('user')) + sites = _get_slice(fields.get('site')) + roles = _get_role(fields.get('role')) + + if users: fields['user'] = users[0] + if slices: fields['site'] = sites[0] + if roles: fields['role'] = roles[0] + + site_privilege = SitePrivilege(**fields) + + # update nova role + driver.add_user_role(site_privilege.user.user_id, + site_privilege.site.tenant_id, + site_privilege.role.name) + + site_privilege.save() + return site_privilege + +def update_site_privilege(auth, id, **fields): + return + +def delete_site_privilege(auth, filter={}): + driver = OpenStackDriver(client = auth_check(auth)) + site_privileges = _get_site_privileges(filter) + for site_privilege in site_privileges: + driver.delete_user_role(user_id=site_privilege.user.id, + tenant_id = site_privilege.site.tenant_id, + role_name = site_privilege.role.name) + site_privilege.delete() + return 1 + +def get_site_privileges(auth, filter={}): + client = auth_check(auth) + users = _get_users(filter.get('user')) + sites = _get_slices(filter.get('site')) + roles = _get_roles(filter.get('role')) + + if users: filter['user'] = users[0] + if sites: filter['site'] = sites[0] + if roles: filter['role'] = roles[0] + + site_privileges = _get_site_privileges(filter) + return site_privileges + + + diff --git a/plstackapi/core/api/sites.py b/plstackapi/core/api/sites.py index 0d07605..540f815 100644 --- a/plstackapi/core/api/sites.py +++ b/plstackapi/core/api/sites.py @@ -2,7 +2,18 @@ from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import Site - + + +def _get_sites(filter): + if isinstance(filter, int): + sites = Site.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + sites = Site.objects.filter(name=filter) + elif isinstance(filer, dict): + sites = Site.objects.filter(**filter) + else: + sites = [] + return sites def add_site(auth, fields): driver = OpenStackDriver(client = auth_check(auth)) @@ -17,7 +28,7 @@ def add_site(auth, fields): def update_site(auth, id, **fields): driver = OpenStackDriver(client = auth_check(auth)) - sites = Site.objects.filter(id=id) + sites = _get_sites(id) if not sites: return @@ -33,7 +44,7 @@ def update_site(auth, id, **fields): def delete_site(auth, filter={}): driver = OpenStackDriver(client = auth_check(auth)) - sites = Site.objects.filter(**filter) + sites = _get_sites(id) for site in sites: driver.delete_tenant(id=site.tenant_id) site.delete() @@ -41,7 +52,7 @@ def delete_site(auth, filter={}): def get_sites(auth, filter={}): client = auth_check(auth) - sites = Site.objects.filter(**filter) + sites = _get_sites(id) return sites diff --git a/plstackapi/core/api/slice_memberships.py b/plstackapi/core/api/slice_memberships.py new file mode 100644 index 0000000..9193632 --- /dev/null +++ b/plstackapi/core/api/slice_memberships.py @@ -0,0 +1,69 @@ +import re +from plstackapi.openstack.client import OpenStackClient +from plstackapi.openstack.driver import OpenStackDriver +from plstackapi.core.api.auth import auth_check +from plstackapi.core.models import SliceMembership, Slice, Role, User +from plstackapi.core.api.users import _get_users +from plstackapi.core.api.slices import _get_slices +from plstackapi.core.api.roles import _get_roles + +def _get_slice_memberships(filter): + if isinstance(filter, int): + slice_memberships = SitePrivilege.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + slice_memberships = SitePrivilege.objects.filter(name=filter) + elif isinstance(filer, dict): + slice_memberships = SitePrivilege.objects.filter(**filter) + else: + slice_memberships = [] + return slice_memberships + + +def add_slice_membership(auth, fields): + driver = OpenStackDriver(client = auth_check(auth)) + users = _get_users(fields.get('user')) + slices = _get_slices(fields.get('slice')) + roles = _get_roles(fields.get('role')) + + if users: fields['user'] = users[0] + if slices: fields['slice'] = slices[0] + if roles: fields['role'] = roles[0] + + slice_membership = SliceMembership(**fields) + + # update nova role + driver.add_user_role(slice_membership.user.user_id, + slice_membership.slice.tenant_id, + slice_membership.role.name) + + slice_membership.save() + return slice_membership + +def update_slice_membership(auth, id, **fields): + return + +def delete_slice_membership(auth, filter={}): + driver = OpenStackDriver(client = auth_check(auth)) + slice_memberships = _get_slice_memberships(filter) + for slice_membership in slice_memberships: + driver.delete_user_role(user_id=slice_membership.user.id, + tenant_id = slice_membership.slice.tenant_id, + role_name = slice_membership.role.name) + slice_membership.delete() + return 1 + +def get_slice_memberships(auth, filter={}): + client = auth_check(auth) + users = _get_users(fields.get('user')) + slices = _get_slices(fields.get('slice')) + roles = _get_roles(fields.get('role')) + + if users: fields['user'] = users[0] + if slices: fields['slice'] = slices[0] + if roles: fields['role'] = roles[0] + + slice_memberships = _get_slice_memberships(filter) + return slice_memberships + + + diff --git a/plstackapi/core/api/slices.py b/plstackapi/core/api/slices.py index 3f50050..731fa75 100644 --- a/plstackapi/core/api/slices.py +++ b/plstackapi/core/api/slices.py @@ -2,43 +2,26 @@ import re from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check -from plstackapi.core.models import Slice, Site - -def validate_name(name): - # N.B.: Responsibility of the caller to ensure that login_base - # portion of the slice name corresponds to a valid site, if - # desired. - - # 1. Lowercase. - # 2. Begins with login_base (letters or numbers). - # 3. Then single underscore after login_base. - # 4. Then letters, numbers, or underscores. - good_name = r'^[a-z0-9]+_[a-zA-Z0-9_]+$' - if not name or \ - not re.match(good_name, name): - raise Exception, "Invalid slice name: %s" % name +from plstackapi.core.models import Slice +from plstackapi.core.api.sites import _get_sites -def lookup_site(fields): - site = None - if 'name' in fields: - validate_name(fields['name']) - login_base = fields['name'][:fields['name'].find('_')] - sites = Site.objects.filter(login_base=login_base) - if sites: - site = sites[0] - elif 'site' in fields: - if isinstance(fields['site'], int): - sites = Site.objects.filter(id=fields['site']) - else: - sites = Site.objects.filter(login_base=fields['site']) - if sites: - site = sites[0] - return site +def _get_slices(filter): + if isinstance(filter, int): + slices = Slice.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + slices = Slice.objects.filter(name=filter) + elif isinstance(filer, dict): + slices = Slice.objects.filter(**filter) + else: + slices = [] + return slices + + def add_slice(auth, fields): driver = OpenStackDriver(client = auth_check(auth)) - site = lookup_site(fields) - if site: fields['site'] = site + sites = _get_sites(fields.get('site')) + if sites: fields['site'] = sites[0] slice = Slice(**fields) # create tenant nova_fields = {'tenant_name': slice.name, @@ -60,7 +43,7 @@ def add_slice(auth, fields): def update_slice(auth, id, **fields): driver = OpenStackDriver(client = auth_check(auth)) - slices = Slice.objects.filter(id=id) + slices = _get_slices(id) if not slices: return @@ -76,15 +59,15 @@ def update_slice(auth, id, **fields): driver.update_tenant(slice.tenant_id, **nova_fields) # update db record - site = lookup_site(fields) - if site: fields['site'] = site + sites = _get_sites(fields.get('site')) + if sites: fields['site'] = sites[0] slice.update(**fields) return slice def delete_slice(auth, filter={}): driver = OpenStackDriver(client = auth_check(auth)) - slices = Slice.objects.filter(**filter) + slices = _get_slices(id) for slice in slices: driver.delete_slice(id=slice.tenant_id) slice.delete() @@ -93,9 +76,9 @@ def delete_slice(auth, filter={}): def get_slices(auth, filter={}): client = auth_check(auth) if 'site' in filter: - site = lookup_site(filter) - if site: filter['site'] = site - slices = Slice.objects.filter(**filter) + sites = _get_sites(filter.get('site')) + if sites: filter['site'] = sites[0] + slices = _get_slices(filter) return slices diff --git a/plstackapi/core/api/slivers.py b/plstackapi/core/api/slivers.py new file mode 100644 index 0000000..0bdaa5d --- /dev/null +++ b/plstackapi/core/api/slivers.py @@ -0,0 +1,74 @@ +import re +from plstackapi.openstack.client import OpenStackClient +from plstackapi.openstack.driver import OpenStackDriver +from plstackapi.core.api.auth import auth_check +from plstackapi.core.models import Sliver, Slice +from plstackapi.core.api.flavors import _get_flavors +from plstackapi.core.api.images import _get_images +from plstackapi.core.api.keys import _get_keys +from plstackapi.core.api.slices import _get_slices +from plstackapi.core.api.deployment_networks import _get_deployment_networks +from plstackapi.core.api.nodes import _get_nodes + + +def _get_slivers(filter): + if isinstance(filter, int): + slivers = Sliver.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + slivers = Sliver.objects.filter(name=filter) + elif isinstance(filer, dict): + slivers = Sliver.objects.filter(**filter) + else: + slivers = [] + return slivers + +def add_sliver(auth, fields): + driver = OpenStackDriver(client = auth_check(auth)) + + flavors = _get_flavor(fields.get('flavor')) + if flavors: fields['flavor'] = flavors[0] + images = _get_images(fields.get('image')) + if images: fields['image'] = images[0] + keys = _get_keys(fields.get('get')) + if keys: fields['key'] = keys[0] + slices = _get_slices(fields.get('slice')) + if slices: fields['slice'] = slices[0] + deployment_networks = _get_deployment_networks(field.get('deployment_network')) + if deployment_networks: fields['deployment_network'] = deployment_networks[0] + nodes = _get_nodes(fields.get('node')) + if nodes: fields['node'] = nodess[0] + + sliver = Sliver(**fields) + # create quantum sliver + sliver = driver.spawn_instance(name=sliver.name, + key_name = sliver.key.name, + flavor=sliver.flavor.name, + image = sliver.image.name, + hostname = sliver.node.hostname ) + + sliver.instance_id=sliver.id + + sliver.save() + return sliver + +def update_sliver(auth, sliver, **fields): + return + +def delete_sliver(auth, filter={}): + driver = OpenStackDriver(client = auth_check(auth)) + slivers = _get_slivers(filter) + for sliver in slivers: + driver.destroy_instance(sliver.sliver_id) + sliver.delete() + return 1 + +def get_slivers(auth, filter={}): + client = auth_check(auth) + if 'slice' in filter: + slices = _get_slices(filter.get('slice')) + if slices: filter['slice'] = slices[0] + slivers = _get_slivers(filter) + return slivers + + + diff --git a/plstackapi/core/api/subnets.py b/plstackapi/core/api/subnets.py new file mode 100644 index 0000000..ad53da0 --- /dev/null +++ b/plstackapi/core/api/subnets.py @@ -0,0 +1,61 @@ +import re +from plstackapi.openstack.client import OpenStackClient +from plstackapi.openstack.driver import OpenStackDriver +from plstackapi.core.api.auth import auth_check +from plstackapi.core.models import Subnet +from plstackapi.core.api.slices import _get_slices + +def _get_subnets(filter): + if isinstance(filter, int): + subnets = Subnet.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + subnets = Subnet.objects.filter(name=filter) + elif isinstance(filer, dict): + subnets = Subnet.objects.filter(**filter) + else: + subnets = [] + return subnets + +def add_subnet(auth, fields): + driver = OpenStackDriver(client = auth_check(auth)) + slices = _get_slice(fields.get('slice')) + if slices: fields['slice'] = slices[0] + subnet = Subnet(**fields) + # create quantum subnet + subnet = driver.create_subnet(network_name=subnet.name, + cidr_ip = subnet.cidr, + ip_version=subnet.ip_version, + start = subnet.start, + end = subnet.end, + dns_nameservers = ['8.8.8.8', '8.8.4.4']) + + subnet.subnet_id=subnet.id + + # add subnet as interface to slice's router + driver.add_router_interface(subnet.slice.router_id, subnet.subnet_id) + + subnet.save() + return subnet + +def update_subnet(auth, subnet, **fields): + return + +def delete_subnet(auth, filter={}): + driver = OpenStackDriver(client = auth_check(auth)) + subnets = Subnet.objects.filter(**filter) + for subnet in subnets: + driver.delete_router_interface(subnet.slice.router_id, subnet.subnet_id) + driver.delete_subnet(subnet.subnet_id) + subnet.delete() + return 1 + +def get_subnets(auth, filter={}): + client = auth_check(auth) + if 'slice' in filter: + slice = _get_slice(filter.get('slice')) + if slice: filter['slice'] = slice + subnets = Subnet.objects.filter(**filter) + return subnets + + + diff --git a/plstackapi/core/api/users.py b/plstackapi/core/api/users.py index 18a68c7..d543782 100644 --- a/plstackapi/core/api/users.py +++ b/plstackapi/core/api/users.py @@ -2,31 +2,30 @@ from plstackapi.openstack.client import OpenStackClient from plstackapi.openstack.driver import OpenStackDriver from plstackapi.core.api.auth import auth_check from plstackapi.core.models import User, Site - -def lookup_site(fields): - site = None - if 'site' in fields: - if isinstance(fields['site'], int): - sites = Site.objects.filter(id=fields['site']) - else: - sites = Site.objects.filter(login_base=fields['site']) - if sites: - site = sites[0] - if not site: - raise Exception, "No such site: %s" % fields['site'] - return site +from plstackapi.core.api.sites import _get_sites + +def _get_users(filter): + if isinstance(filter, int): + users = User.objects.filter(id=filter) + elif isinstance(filter, StringTypes): + users = User.objects.filter(role_type=filter) + elif isinstance(filer, dict): + users = User.objects.filter(**filter) + else: + users = [] + return users def add_user(auth, fields): driver = OpenStackDriver(client = auth_check(auth)) - site = lookup_site(fields) - if site: fields['site'] = site + sites = _get_sites(fields.get('site')) + if sites: fields['site'] = sites[0] user = User(**fields) nova_fields = {'name': user.email[:user.email.find('@')], 'email': user.email, 'password': fields.get('password'), 'enabled': user.enabled} nova_user = driver.create_user(**nova_fields) - #driver.add_user_role(user.id, user.site.tenant_id, 'user') + #driver.add_user_user(user.id, user.site.tenant_id, 'user') user.user_id=nova_user.id user.save() return user @@ -47,14 +46,14 @@ def update_user(auth, id, **fields): if 'enabled' in fields: nova_fields['enabled'] = fields['enabled'] driver.update_user(user.user_id, **nova_fields) - site = lookup_site(fields) - if site: fields['site'] = site + sites = _get_sites(fields.get('site')) + if sites: fields['site'] = sites[0] user.update(**fields) return user def delete_user(auth, filter={}): driver = OpenStackDriver(client = auth_check(auth)) - users = User.objects.filter(**filter) + users = _get_users(filter) for user in users: driver.delete_user(id=user.user_id) user.delete() @@ -62,7 +61,7 @@ def delete_user(auth, filter={}): def get_users(auth, filter={}): client = auth_check(auth) - users = User.objects.filter(**filter) + users = _get_users(filter) return users diff --git a/plstackapi/core/api_root.py b/plstackapi/core/api_root.py index 3859188..583e7c4 100644 --- a/plstackapi/core/api_root.py +++ b/plstackapi/core/api_root.py @@ -12,6 +12,8 @@ def api_root(request, format=None): 'sites': reverse('site-list', request=request, format=format), 'deploymentNetworks': reverse('deploymentnetwork-list', request=request, format=format), 'slices': reverse('slice-list', request=request, format=format), + 'subnets': reverse('subnet-list', request=request, format=format), + 'slivers': reverse('sliver-list', request=request, format=format), 'images': reverse('image-list', request=request, format=format), 'flavors': reverse('flavor-list', request=request, format=format), }) diff --git a/plstackapi/core/fixtures/initial_data.json b/plstackapi/core/fixtures/initial_data.json index 62d943b..47f5175 100644 --- a/plstackapi/core/fixtures/initial_data.json +++ b/plstackapi/core/fixtures/initial_data.json @@ -1 +1 @@ -[{"pk": 1, "model": "plstackapi.planetstack.deploymentnetwork", "fields": {"updated": "2013-03-20T01:18:31.247Z", "name": "VICCI", "created": "2013-03-20T01:18:31.247Z"}}, {"pk": 2, "model": "plstackapi.planetstack.deploymentnetwork", "fields": {"updated": "2013-03-20T01:19:00.063Z", "name": "VINI", "created": "2013-03-20T01:19:00.063Z"}}, {"pk": 3, "model": "plstackapi.planetstack.deploymentnetwork", "fields": {"updated": "2013-03-20T01:19:15.143Z", "name": "GENI", "created": "2013-03-20T01:19:15.143Z"}}, {"pk": 4, "model": "plstackapi.planetstack.deploymentnetwork", "fields": {"updated": "2013-03-20T01:19:40.098Z", "name": "PlanetLab Classic", "created": "2013-03-20T01:19:25.672Z"}}] +[{"pk": 1, "model": "core.deploymentnetwork", "fields": {"updated": "2013-04-03T22:57:09.331Z", "name": "VICCI", "created": "2013-04-03T22:57:09.331Z"}}, {"pk": 2, "model": "core.deploymentnetwork", "fields": {"updated": "2013-04-03T22:57:15.013Z", "name": "VINI", "created": "2013-04-03T22:57:15.013Z"}}, {"pk": 3, "model": "core.deploymentnetwork", "fields": {"updated": "2013-04-03T22:57:23.015Z", "name": "PlanetLab Classic", "created": "2013-04-03T22:57:23.015Z"}}, {"pk": 4, "model": "core.deploymentnetwork", "fields": {"updated": "2013-04-03T22:57:29.569Z", "name": "GENI", "created": "2013-04-03T22:57:29.569Z"}}, {"pk": 1, "model": "core.site", "fields": {"updated": "2013-04-05T15:21:04.135Z", "name": "Princeton University", "created": "2013-04-03T23:00:10.085Z", "tenant_id": "", "enabled": true, "longitude": -74.6524, "site_url": "http://princeton.edu/", "login_base": "princeton", "latitude": 40.3502, "is_public": true, "deployments": [3, 4], "abbreviated_name": ""}}, {"pk": 2, "model": "core.site", "fields": {"updated": "2013-04-05T15:42:36.517Z", "name": "Stanford University", "created": "2013-04-03T23:03:51.742Z", "tenant_id": "", "enabled": true, "longitude": -122.172, "site_url": "http://www.stanford.edu/", "login_base": "stanford", "latitude": 37.4294, "is_public": true, "deployments": [], "abbreviated_name": ""}}, {"pk": 3, "model": "core.site", "fields": {"updated": "2013-04-05T15:42:17.263Z", "name": "Georgia Institute of Technology", "created": "2013-04-03T23:05:51.984Z", "tenant_id": "", "enabled": true, "longitude": -84.3976, "site_url": "http://www.gatech.edu/", "login_base": "gt", "latitude": 33.7772, "is_public": true, "deployments": [], "abbreviated_name": ""}}, {"pk": 4, "model": "core.site", "fields": {"updated": "2013-04-05T15:39:27.501Z", "name": "University of Washington", "created": "2013-04-03T23:09:52.337Z", "tenant_id": "", "enabled": true, "longitude": -122.313, "site_url": "https://www.washington.edu/", "login_base": "uw", "latitude": 47.6531, "is_public": true, "deployments": [], "abbreviated_name": ""}}, {"pk": 5, "model": "core.site", "fields": {"updated": "2013-04-05T15:38:56.889Z", "name": "ETH Zuerich - Computer Science", "created": "2013-04-03T23:14:11.072Z", "tenant_id": "", "enabled": true, "longitude": 8.54513, "site_url": "http://www.inf.ethz.ch/", "login_base": "ethzcs", "latitude": 47.3794, "is_public": true, "deployments": [], "abbreviated_name": ""}}, {"pk": 6, "model": "core.site", "fields": {"updated": "2013-04-05T15:38:15.960Z", "name": "Max Planck Institute for Software Systems", "created": "2013-04-03T23:19:38.789Z", "tenant_id": "", "enabled": true, "longitude": 6.589, "site_url": "http://www.mpi-sws.mpg.de/", "login_base": "mpisws", "latitude": 49.14, "is_public": true, "deployments": [], "abbreviated_name": ""}}, {"pk": 7, "model": "core.site", "fields": {"updated": "2013-04-05T15:37:32.185Z", "name": "University of Tokyo", "created": "2013-04-03T23:20:49.815Z", "tenant_id": "", "enabled": true, "longitude": 139.5, "site_url": "http://www.planet-lab-jp.org/", "login_base": "utokyo", "latitude": 35.75, "is_public": true, "deployments": [], "abbreviated_name": ""}}] \ No newline at end of file diff --git a/plstackapi/core/models.py b/plstackapi/core/models.py deleted file mode 100644 index d68d801..0000000 --- a/plstackapi/core/models.py +++ /dev/null @@ -1,234 +0,0 @@ -import os -import datetime -from django.db import models -from plstackapi.openstack.driver import OpenStackDriver - -# Create your models here. -# Test push - -class PlCoreBase(models.Model): - - created = models.DateTimeField(auto_now_add=True) - updated = models.DateTimeField(auto_now=True) - - class Meta: - abstract = True - - def save(self): - if not self.id: - self.created = datetime.date.today() - self.updated = datetime.datetime.today() - super(PlCoreBase, self).save() - -class Role(PlCoreBase): - - ROLE_CHOICES = (('admin', 'Admin'), ('pi', 'Principle Investigator'), ('user','User')) - role_id = models.CharField(max_length=256, unique=True) - role_type = models.CharField(max_length=80, unique=True, choices=ROLE_CHOICES) - - def __unicode__(self): return u'%s' % (self.role_type) - - def save(self): - if not self.id: - self.created = datetime.date.today() - self.updated = datetime.datetime.today() - super(Role, self).save() - -class Site(PlCoreBase): - tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id") - name = models.CharField(max_length=200, help_text="Name for this Site") - site_url = models.URLField(null=True, blank=True, max_length=512, help_text="Site's Home URL Page") - enabled = models.BooleanField(default=True, help_text="Status for this Site") - longitude = models.FloatField(null=True, blank=True) - latitude = models.FloatField(null=True, blank=True) - login_base = models.CharField(max_length=50, unique=True, help_text="Prefix for Slices associated with this Site") - is_public = models.BooleanField(default=True, help_text="Indicates the visibility of this site to other members") - abbreviated_name = models.CharField(max_length=80) - - def __unicode__(self): return u'%s' % (self.name) - - -class User(PlCoreBase): - user_id = models.CharField(max_length=256, unique=True) - firstname = models.CharField(help_text="person's given name", max_length=200) - lastname = models.CharField(help_text="person's surname", max_length=200) - email = models.EmailField(help_text="e-mail address") - phone = models.CharField(null=True, blank=True, help_text="phone number contact", max_length=100) - user_url = models.URLField(null=True, blank=True) - is_admin = models.BooleanField(default=False) - enabled = models.BooleanField(default=True, help_text="Status for this User") - site = models.ForeignKey(Site, related_name='users', verbose_name="Site this user will be homed too") - - def __unicode__(self): return u'%s' % (self.email) - -class SitePrivilege(PlCoreBase): - - user = models.ForeignKey('User', related_name='site_privileges') - site = models.ForeignKey('Site', related_name='site_privileges') - role = models.ForeignKey('Role') - - def __unicode__(self): return u'%s %s %s' % (self.site, self.user, self.role) - - def save(self, *args, **kwds): - driver = OpenStackDriver() - driver.add_user_role(user_id=user.user_id, - tenant_id=site.tenant_id, - role_name=role.name) - super(SitePrivilege, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.delete_user_role(user_id=user.user_id, - tenant_id=site.tenant_id, - role_name=role.name) - super(SitePrivilege, self).delete(*args, **kwds) - - -class DeploymentNetwork(PlCoreBase): - name = models.CharField(max_length=200, unique=True, help_text="Name of the Deployment Network") - - def __unicode__(self): return u'%s' % (self.name) - -class SiteDeploymentNetwork(PlCoreBase): - class Meta: - unique_together = ['site', 'deploymentNetwork'] - - site = models.ForeignKey(Site, related_name='deployment_networks') - deploymentNetwork = models.ForeignKey(DeploymentNetwork, related_name='sites') - name = models.CharField(default="Blah", max_length=100) - - - def __unicode__(self): return u'%s::%s' % (self.site, self.deploymentNetwork) - - -class Slice(PlCoreBase): - tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id") - name = models.CharField(help_text="The Name of the Slice", max_length=80) - enabled = models.BooleanField(default=True, help_text="Status for this Slice") - SLICE_CHOICES = (('plc', 'PLC'), ('delegated', 'Delegated'), ('controller','Controller'), ('none','None')) - instantiation = models.CharField(help_text="The instantiation type of the slice", max_length=80, choices=SLICE_CHOICES) - omf_friendly = models.BooleanField(default=False) - description=models.TextField(blank=True,help_text="High level description of the slice and expected activities", max_length=1024) - slice_url = models.URLField(blank=True, max_length=512) - site = models.ForeignKey(Site, related_name='slices', help_text="The Site this Node belongs too") - network_id = models.CharField(max_length=256, help_text="Quantum network") - router_id = models.CharField(max_length=256, help_text="Quantum router id") - - def __unicode__(self): return u'%s' % (self.name) - - -class SliceMembership(PlCoreBase): - user = models.ForeignKey('User', related_name='slice_memberships') - slice = models.ForeignKey('Slice', related_name='slice_memberships') - role = models.ForeignKey('Role') - - def __unicode__(self): return u'%s %s %s' % (self.slice, self.user, self.role) - - def save(self, *args, **kwds): - driver = OpenStackDriver() - driver.add_user_role(user_id=user.user_id, - tenant_id=slice.tenant_id, - role_name=role.name) - super(SliceMembership, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.delete_user_role(user_id=user.user_id, - tenant_id=slice.tenant_id, - role_name=role.name) - super(SliceMembership, self).delete(*args, **kwds) - -class SubNet(PlCoreBase): - subnet_id = models.CharField(max_length=256, unique=True) - cidr = models.CharField(max_length=20) - ip_version = models.IntegerField() - start = models.IPAddressField() - end = models.IPAddressField() - slice = models.ForeignKey(Slice, related_name='subnets') - - def __unicode__(self): return u'%s' % (self.name) - - def save(self, *args, **kwargs): - driver = OpenStackDriver() - if not self.id: - subnet = driver.create_subnet(network_name=self.slice.name, - cidr_ip = self.cidr, - ip_version=self.ip_version, - start = self.start, - end = self.end) - - self.subnet_id = subnet.id - - # add subnet as interface to slice router - driver.add_router_interface(self.slice.router_id, subnet.id) - - super(SubNet, self).save(*args, **kwargs) - - - def delete(self, *args, **kwargs): - # delete quantum network - driver = OpenStackDriver() - driver.delete_subnet(self.subnet_id) - driver.delete_router_interface(self.slice.router_id, self.subnet.id) - super(SubNet, self).delete(*args, **kwargs) - -class Node(PlCoreBase): - name = models.CharField(max_length=200, unique=True, help_text="Name of the Node") - siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork, help_text="The Site and Deployment Network this Node belongs too.") - - def __unicode__(self): return u'%s' % (self.name) - -class Image(PlCoreBase): - image_id = models.CharField(max_length=256, unique=True) - name = models.CharField(max_length=256, unique=True) - disk_format = models.CharField(max_length=256) - container_format = models.CharField(max_length=256) - - def __unicode__(self): return u'%s' % (self.name) - - -class Flavor(PlCoreBase): - flavor_id = models.IntegerField(unique=True) - name = models.CharField(max_length=256, unique=True) - memory_mb = models.IntegerField() - disk_gb = models.IntegerField() - vcpus = models.IntegerField() - - def __unicode__(self): return u'%s' % (self.name) - -class Key(PlCoreBase): - name = models.CharField(max_length=256, unique=True) - key = models.CharField(max_length=512) - type = models.CharField(max_length=256) - blacklisted = models.BooleanField(default=False) - user = models.ForeignKey(User, related_name='keys') - - def __unicode__(self): return u'%s' % (self.name) - -class Sliver(PlCoreBase): - instance_id = models.CharField(max_length=200, help_text="Nova instance id") - name = models.CharField(max_length=200, help_text="Sliver name") - flavor = models.ForeignKey(Flavor) - image = models.ForeignKey(Image) - key = models.ForeignKey(Key) - slice = models.ForeignKey(Slice, related_name='slivers') - siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork) - node = models.ForeignKey(Node) - - def __unicode__(self): return u'%s::%s' % (self.slice, self.siteDeploymentNetwork) - - def save(self, *args, **kwds): - driver = OpenStackDriver() - instance = driver.spawn_instances(name=self.name, - keyname=self.name, - hostnames=self.node.name, - flavor=self.flavor.name, - image=self.image.name) - self.instance_id = instance.id - super(Sliver, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.destroy_instance(name=self.name, id=self.instance_id) - super(Sliver, self).delete(*args, **kwds) - diff --git a/plstackapi/core/models/role.py b/plstackapi/core/models/role.py index 7b3268c..12743ef 100644 --- a/plstackapi/core/models/role.py +++ b/plstackapi/core/models/role.py @@ -13,8 +13,3 @@ class Role(PlCoreBase): def __unicode__(self): return u'%s' % (self.role_type) - def save(self): - if not self.id: - self.created = datetime.date.today() - self.updated = datetime.datetime.today() - super(Role, self).save() diff --git a/plstackapi/core/models/site.py b/plstackapi/core/models/site.py index 5ec04c4..a2903f9 100644 --- a/plstackapi/core/models/site.py +++ b/plstackapi/core/models/site.py @@ -32,18 +32,4 @@ class SitePrivilege(PlCoreBase): def __unicode__(self): return u'%s %s %s' % (self.site, self.user, self.role) - def save(self, *args, **kwds): - driver = OpenStackDriver() - driver.add_user_role(user_id=user.user_id, - tenant_id=site.tenant_id, - role_name=role.name) - super(SitePrivilege, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.delete_user_role(user_id=user.user_id, - tenant_id=site.tenant_id, - role_name=role.name) - super(SitePrivilege, self).delete(*args, **kwds) - diff --git a/plstackapi/core/models/slice.py b/plstackapi/core/models/slice.py index 24c44a6..63941c7 100644 --- a/plstackapi/core/models/slice.py +++ b/plstackapi/core/models/slice.py @@ -25,35 +25,6 @@ class Slice(PlCoreBase): def __unicode__(self): return u'%s' % (self.name) - def save(self, *args, **kwds): - # sync keystone tenant - driver = OpenStackDriver() - - if not self.id: - tenant = driver.create_tenant(tenant_name=self.name, - description=self.description, - enabled=self.enabled) - self.tenant_id = tenant.id - - # create a network - network = driver.create_network(name=self.name) - self.network_id = network['id'] - # create router - router = driver.create_router(name=self.name) - self.router_id = router['id'] - -/bin/sh: 1: command not found - # update record - self.driver.update_tenant(self.tenant_id, name=self.name, - description=self.description, enabled=self.enabled) - super(Slice, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - # delete keystone tenant - driver = OpenStackDriver() - driver.delete_tenant(self.tenant_id) - super(Slice, self).delete(*args, **kwds) - class SliceMembership(PlCoreBase): user = models.ForeignKey('User', related_name='slice_memberships') slice = models.ForeignKey('Slice', related_name='slice_memberships') @@ -61,16 +32,3 @@ class SliceMembership(PlCoreBase): def __unicode__(self): return u'%s %s %s' % (self.slice, self.user, self.role) - def save(self, *args, **kwds): - driver = OpenStackDriver() - driver.add_user_role(user_id=user.user_id, - tenant_id=slice.tenant_id, - role_name=role.name) - super(SliceMembership, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.delete_user_role(user_id=user.user_id, - tenant_id=slice.tenant_id, - role_name=role.name) - super(SliceMembership, self).delete(*args, **kwds) diff --git a/plstackapi/core/models/sliver.py b/plstackapi/core/models/sliver.py index 6f7aabe..9d5857e 100644 --- a/plstackapi/core/models/sliver.py +++ b/plstackapi/core/models/sliver.py @@ -22,20 +22,5 @@ class Sliver(PlCoreBase): site = models.ForeignKey(Site, related_name='sliver_site') deploymentNetwork = models.ForeignKey(DeploymentNetwork, related_name='sliver_deploymentNetwork') - def __unicode__(self): return u'%s::%s' % (self.slice, self.siteDeploymentNetwork) - - def save(self, *args, **kwds): - driver = OpenStackDriver() - instance = driver.spawn_instances(name=self.name, - keyname=self.name, - hostnames=self.node.name, - flavor=self.flavor.name, - image=self.image.name) - self.instance_id = instance.id - super(Sliver, self).save(*args, **kwds) - - def delete(self, *args, **kwds): - driver = OpenStackDriver() - driver.destroy_instance(name=self.name, id=self.instance_id) - super(Sliver, self).delete(*args, **kwds) + def __unicode__(self): return u'%s::%s' % (self.slice, self.deploymentNetwork) diff --git a/plstackapi/core/models/subnet.py b/plstackapi/core/models/subnet.py index 291ffe8..70f8176 100644 --- a/plstackapi/core/models/subnet.py +++ b/plstackapi/core/models/subnet.py @@ -16,26 +16,3 @@ class Subnet(PlCoreBase): def __unicode__(self): return u'%s' % (self.name) - def save(self, *args, **kwargs): - driver = OpenStackDriver() - if not self.id: - subnet = driver.create_subnet(network_name=self.slice.name, - cidr_ip = self.cidr, - ip_version=self.ip_version, - start = self.start, - end = self.end) - - self.subnet_id = subnet.id - - # add subnet as interface to slice router - driver.add_router_interface(self.slice.router_id, subnet.id) - - super(Subnet, self).save(*args, **kwargs) - - - def delete(self, *args, **kwargs): - # delete quantum network - driver = OpenStackDriver() - driver.delete_subnet(self.subnet_id) - driver.delete_router_interface(self.slice.router_id, self.subnet.id) - super(Subnet, self).delete(*args, **kwargs) diff --git a/plstackapi/core/serializers.py b/plstackapi/core/serializers.py index 9a1d118..f6fbe8c 100644 --- a/plstackapi/core/serializers.py +++ b/plstackapi/core/serializers.py @@ -72,6 +72,31 @@ class SliceSerializer(serializers.HyperlinkedModelSerializer): 'updated', 'created') +class SliceMembershipSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.Field() + slice = serializers.HyperlinkedRelatedField(view_name='slice-detail') + user = serializers.HyperlinkedRelatedField(view_name='user-detail') + role = serializers.HyperlinkedRelatedField(view_name='role-detail') + class Meta: + model = SitePrivilege + fields = ('id', + 'user', + 'slice', + 'role') + +class SubnetSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.Field() + slice = serializers.HyperlinkedRelatedField(view_name='slice-detail') + class Meta: + model = Subnet + fields = ('id', + 'subnet_id', + 'cidr', + 'ip_version', + 'start', + 'end', + 'slice') + class SiteSerializer(serializers.HyperlinkedModelSerializer): #Experimenting with whether to use ids, hyperlinks, or nested includes @@ -81,7 +106,7 @@ class SiteSerializer(serializers.HyperlinkedModelSerializer): # HyperlinkedModelSerializer doesn't include the id by default id = serializers.Field() slices = serializers.HyperlinkedRelatedField(many=True, read_only=True,view_name='slice-detail') - deployment_networks = serializers.HyperlinkedRelatedField(many=True, read_only=True,view_name='sitedeploymentnetwork-detail') + deployment_networks = serializers.HyperlinkedRelatedField(many=True, read_only=True,view_name='deploymentnetwork-detail') class Meta: model = Site @@ -101,11 +126,23 @@ class SiteSerializer(serializers.HyperlinkedModelSerializer): 'updated', 'created') +class SitePrivilegeSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.Field() + site = serializers.HyperlinkedRelatedField(view_name='site-detail') + user = serializers.HyperlinkedRelatedField(view_name='user-detail') + role = serializers.HyperlinkedRelatedField(view_name='role-detail') + class Meta: + model = SitePrivilege + fields = ('id', + 'user', + 'site', + 'role') + class DeploymentNetworkSerializer(serializers.HyperlinkedModelSerializer): # HyperlinkedModelSerializer doesn't include the id by default id = serializers.Field() - sites = serializers.HyperlinkedRelatedField(view_name='sitedeploymentnetwork-detail') + sites = serializers.HyperlinkedRelatedField(view_name='deploymentnetwork-detail') class Meta: model = DeploymentNetwork fields = ('id', @@ -113,30 +150,30 @@ class DeploymentNetworkSerializer(serializers.HyperlinkedModelSerializer): 'sites' ) -class SiteDeploymentNetworkSerializer(serializers.HyperlinkedModelSerializer): - # HyperlinkedModelSerializer doesn't include the id by default - id = serializers.Field() - site = serializers.HyperlinkedRelatedField(view_name='site-detail') - deploymentNetwork = serializers.HyperlinkedRelatedField(view_name='deploymentnetwork-detail') - - class Meta: - model = SiteDeploymentNetwork - fields = ('id', - 'url', - 'site', - 'deploymentNetwork') - class SliverSerializer(serializers.HyperlinkedModelSerializer): # HyperlinkedModelSerializer doesn't include the id by default id = serializers.Field() - slice = serializers.RelatedField(read_only=True) + flavor = serializers.HyperlinkedRelatedField(view_name='flavor-detail') + image = serializers.HyperlinkedRelatedField(view_name='image-detail') + key = serializers.HyperlinkedRelatedField(view_name='key-detail') + slice = serializers.HyperlinkedRelatedField(view_name='slice-detail') + deployment_network = serializers.HyperlinkedRelatedField(view_name='deployment_network-detail') + node = serializers.HyperlinkedRelatedField(view_name='node-detail') + + #slice = serializers.PrimaryKeyRelatedField(read_only=True) class Meta: model = Sliver fields = ('id', + 'instance_id', + 'name' + 'flavor', + 'image', + 'key' 'slice', - 'name') + 'deployment_network', + 'noode') class NodeSerializer(serializers.HyperlinkedModelSerializer): # HyperlinkedModelSerializer doesn't include the id by default @@ -174,11 +211,13 @@ serializerLookUp = { User: UserSerializer, Key: KeySerializer, Site: SiteSerializer, + SitePrivilege: SitePrivilegeSerializer, Slice: SliceSerializer, + SliceMembership: SliceMembershipSerializer, + Subnet: SubnetSerializer, Node: NodeSerializer, Sliver: SliverSerializer, DeploymentNetwork: DeploymentNetworkSerializer, - SiteDeploymentNetwork: SiteDeploymentNetworkSerializer, Image: ImageSerializer, Flavor: FlavorSerializer, None: None, diff --git a/plstackapi/core/urls.py b/plstackapi/core/urls.py index e4bf5c3..9493a06 100644 --- a/plstackapi/core/urls.py +++ b/plstackapi/core/urls.py @@ -2,9 +2,21 @@ from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: from django.contrib import admin -from plstackapi.core import views -from plstackapi.core.views import api_root +from plstackapi.core.views.roles import RoleListCreate, RoleRetrieveUpdateDestroy +from plstackapi.core.views.sites import SiteListCreate, SiteRetrieveUpdateDestroy +from plstackapi.core.views.site_privileges import SitePrivilegeListCreate, SitePrivilegeRetrieveUpdateDestroy +from plstackapi.core.views.users import UserListCreate, UserRetrieveUpdateDestroy +from plstackapi.core.views.slices import SliceListCreate, SliceRetrieveUpdateDestroy +from plstackapi.core.views.slice_memberships import SliceMembershipListCreate, SliceMembershipRetrieveUpdateDestroy +from plstackapi.core.views.subnets import SubnetListCreate, SubnetRetrieveUpdateDestroy +from plstackapi.core.views.slivers import SliverListCreate, SliverRetrieveUpdateDestroy +from plstackapi.core.views.keys import KeyListCreate, KeyRetrieveUpdateDestroy +from plstackapi.core.views.deployment_networks import DeploymentNetworkListCreate, DeploymentNetworkRetrieveUpdateDestroy +from plstackapi.core.views.images import ImageListCreate, ImageRetrieveUpdateDestroy +from plstackapi.core.views.flavors import FlavorListCreate, FlavorRetrieveUpdateDestroy +from plstackapi.core.views.nodes import NodeListCreate, NodeRetrieveUpdateDestroy from plstackapi.core.models import Site +from plstackapi.core.api_root import api_root from rest_framework import generics admin.autodiscover() @@ -21,22 +33,45 @@ urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^plstackapi/$', api_root), - url(r'^plstackapi/sites/$', views.SiteList.as_view(), name='site-list'), - url(r'^plstackapi/sites/(?P[0-9]+)/$', views.SiteDetail.as_view(), name='site-detail'), + + url(r'^plstackapi/roles/$', RoleListCreate.as_view(), name='role-list'), + url(r'^plstackapi/roles/(?P[a-zA-Z0-9]+)/$', RoleRetrieveUpdateDestroy.as_view(), name='role-detail'), + + url(r'^plstackapi/users/$', UserListCreate.as_view(), name='user-list'), + url(r'^plstackapi/users/(?P[a-zA-Z0-9]+)/$', UserRetrieveUpdateDestroy.as_view(), name='user-detail'), - url(r'^plstackapi/slices/$', views.SliceList.as_view(), name='slice-list'), - url(r'^plstackapi/slices/(?P[0-9]+)/$', views.SliceDetail.as_view(), name='slice-detail'), + url(r'^plstackapi/keys/$', KeyListCreate.as_view(), name='key-list'), + url(r'^plstackapi/keys/(?P[a-zA-Z0-9]+)/$', KeyRetrieveUpdateDestroy.as_view(), name='key-detail'), - url(r'^plstackapi/slivers/$', views.SliverList.as_view()), - url(r'^plstackapi/slivers/(?P[0-9]+)/$', views.SliverDetail.as_view()), + url(r'^plstackapi/sites/$', SiteListCreate.as_view(), name='site-list'), + url(r'^plstackapi/sites/(?P[a-zA-Z0-9_]+)/$', SiteRetrieveUpdateDestroy.as_view(), name='site-detail'), - url(r'^plstackapi/nodes/$', views.NodeList.as_view(), name='node-list'), - url(r'^plstackapi/nodes/(?P[0-9]+)/$', views.NodeDetail.as_view(), name='node-detail'), + url(r'^plstackapi/site_privileges/$', SitePrivilegeListCreate.as_view(), name='siteprivilege-list'), + url(r'^plstackapi/site_privileges/(?P[a-zA-Z0-9_]+)/$', SitePrivilegeRetrieveUpdateDestroy.as_view(), name='siteprivilege-detail'), - url(r'^plstackapi/deploymentnetworks/$', views.DeploymentNetworkList.as_view(), name='deploymentnetwork-list'), - url(r'^plstackapi/deploymentnetworks/(?P[0-9]+)/$', views.DeploymentNetworkDetail.as_view(), name='deploymentnetwork-detail'), + url(r'^plstackapi/slices/$', SliceListCreate.as_view(), name='slice-list'), + url(r'^plstackapi/slices/(?P[0-9]+)/$', SliceRetrieveUpdateDestroy.as_view(), name='slice-detail'), + + url(r'^plstackapi/slice_memberships/$', SliceMembershipListCreate.as_view(), name='slice_membership-list'), + url(r'^plstackapi/slice_memberships/(?P[0-9]+)/$', SliceMembershipRetrieveUpdateDestroy.as_view(), name='slice_membership-detail'), + + url(r'^plstackapi/subnets/$', SubnetListCreate.as_view(), name='subnet-list'), + url(r'^plstackapi/subnets/(?P[0-9]+)/$', SubnetRetrieveUpdateDestroy.as_view(), name='subnet-detail'), + + url(r'^plstackapi/slivers/$', SliverListCreate.as_view(), name='sliver-list'), + url(r'^plstackapi/slivers/(?P[0-9]+)/$', SliverRetrieveUpdateDestroy.as_view(), name='sliver-detail'), + + url(r'^plstackapi/nodes/$', NodeListCreate.as_view(), name='node-list'), + url(r'^plstackapi/nodes/(?P[0-9]+)/$', NodeRetrieveUpdateDestroy.as_view(), name='node-detail'), + + url(r'^plstackapi/deploymentnetworks/$', DeploymentNetworkListCreate.as_view(), name='deploymentnetwork-list'), + url(r'^plstackapi/deploymentnetworks/(?P[a-zA-Z0-9]+)/$', DeploymentNetworkRetrieveUpdateDestroy.as_view(), name='deploymentnetwork-detail'), + url(r'^plstackapi/images/$', ImageListCreate.as_view(), name='image-list'), + url(r'^plstackapi/images/(?P[a-zA-Z0-9_]+)/$', ImageRetrieveUpdateDestroy.as_view(), name='image-detail'), + url(r'^plstackapi/flavors/$', FlavorListCreate.as_view(), name='flavor-list'), + url(r'^plstackapi/flavors/(?P[a-zA-Z0-9_]+)/$', FlavorRetrieveUpdateDestroy.as_view(), name='flavor-detail'), #Adding in rest_framework urls url(r'^plstackapi/', include('rest_framework.urls', namespace='rest_framework')), diff --git a/plstackapi/core/views.py b/plstackapi/core/views.py deleted file mode 100644 index c2730bb..0000000 --- a/plstackapi/core/views.py +++ /dev/null @@ -1,58 +0,0 @@ -# Create your views here. - -from plstackapi.core.models import Site -from serializers import * -from rest_framework import generics -from rest_framework.decorators import api_view -from rest_framework.response import Response -from rest_framework.reverse import reverse -from rest_framework import renderers - -@api_view(['GET']) -def api_root(request, format=None): - return Response({ - 'nodes': reverse('node-list', request=request, format=format), - 'sites': reverse('site-list', request=request, format=format), - 'deploymentNetworks': reverse('deploymentnetwork-list', request=request, format=format), - 'slices': reverse('slice-list', request=request, format=format) - }) - -class SiteList(generics.ListCreateAPIView): - model=Site - serializer_class = SiteSerializer - -class SiteDetail(generics.RetrieveUpdateDestroyAPIView): - model = Site - serializer_class = SiteSerializer - -class SliceList(generics.ListCreateAPIView): - model=Slice - serializer_class = SliceSerializer - -class SliceDetail(generics.RetrieveUpdateDestroyAPIView): - model = Slice - serializer_class = SliceSerializer - -class NodeList(generics.ListCreateAPIView): - model=Node - serializer_class = NodeSerializer - -class NodeDetail(generics.RetrieveUpdateDestroyAPIView): - model = Node - serializer_class = NodeSerializer - -class SliverList(generics.ListCreateAPIView): - model=Sliver - serializer_class = SliverSerializer - -class SliverDetail(generics.RetrieveUpdateDestroyAPIView): - model = Sliver - serializer_class = SliverSerializer - -class DeploymentNetworkList(generics.ListCreateAPIView): - model=DeploymentNetwork - serializer_class = DeploymentNetworkSerializer - -class DeploymentNetworkDetail(generics.RetrieveUpdateDestroyAPIView): - model = DeploymentNetwork - serializer_class = DeploymentNetworkSerializer diff --git a/plstackapi/core/views/deployment_networks.py b/plstackapi/core/views/deployment_networks.py index 60e8030..60e8b14 100644 --- a/plstackapi/core/views/deployment_networks.py +++ b/plstackapi/core/views/deployment_networks.py @@ -37,7 +37,7 @@ class DeploymentNetworkRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - deployment_networks = get_deployment_networks(data['auth'], {'name': pk}) + deployment_networks = get_deployment_networks(data['auth'], pk) if not deployment_networks: return Response(status=status.HTTP_404_NOT_FOUND) serializer = DeploymentNetworkSerializer(deployment_networks[0]) @@ -51,7 +51,7 @@ class DeploymentNetworkRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - delete_deployment_network(data['auth'], {'name': pk}) + delete_deployment_network(data['auth'], pk) return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/plstackapi/core/views/flavors.py b/plstackapi/core/views/flavors.py index ef48499..0e06c8e 100644 --- a/plstackapi/core/views/flavors.py +++ b/plstackapi/core/views/flavors.py @@ -36,7 +36,7 @@ class FlavorRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - flavors = get_flavors(data['auth'], {'id': pk}) + flavors = get_flavors(data['auth'], pk) if not flavors: return Response(status=status.HTTP_404_NOT_FOUND) serializer = FlavorSerializer(flavors[0]) diff --git a/plstackapi/core/views/images.py b/plstackapi/core/views/images.py index f48cb71..4a548ac 100644 --- a/plstackapi/core/views/images.py +++ b/plstackapi/core/views/images.py @@ -36,7 +36,7 @@ class ImageRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - images = get_images(data['auth'], {'id': pk}) + images = get_images(data['auth'], pk) if not images: return Response(status=status.HTTP_404_NOT_FOUND) serializer = ImageSerializer(images[0]) diff --git a/plstackapi/core/views/keys.py b/plstackapi/core/views/keys.py index 6b52b8e..80a378d 100644 --- a/plstackapi/core/views/keys.py +++ b/plstackapi/core/views/keys.py @@ -37,7 +37,7 @@ class KeyRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - keys = get_keys(data['auth'], {'id': pk}) + keys = get_keys(data['auth'], pk) if not keys: return Response(status=status.HTTP_404_NOT_FOUND) serializer = KeySerializer(keys[0]) @@ -59,7 +59,7 @@ class KeyRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - delete_key(data['auth'], {'id': pk}) + delete_key(data['auth'], pk) return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/plstackapi/core/views/nodes.py b/plstackapi/core/views/nodes.py new file mode 100644 index 0000000..baa9f17 --- /dev/null +++ b/plstackapi/core/views/nodes.py @@ -0,0 +1,55 @@ +from django.http import Http404 +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + +from plstackapi.core.api.nodes import add_node, delete_node, get_nodes, update_node +from plstackapi.core.serializers import NodeSerializer +from plstackapi.util.request import parse_request + + +class NodeListCreate(APIView): + """ + List all nodes or create a new node. + """ + + def post(self, request, format = None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'node' in data: + """Not Implemented""" + return Response(status=status.HTTP_404_NOT_FOUND) + else: + nodes = get_nodes(data['auth']) + serializer = NodeSerializer(nodes, many=True) + return Response(serializer.data) + + +class NodeRetrieveUpdateDestroy(APIView): + """ + Retrieve, update or delete an node + """ + + def post(self, request, pk, format=None): + """Retrieve an node """ + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + nodes = get_nodes(data['auth'], pk) + if not nodes: + return Response(status=status.HTTP_404_NOT_FOUND) + serializer = NodeSerializer(nodes[0]) + return Response(serializer.data) + + def put(self, request, pk, format=None): + """update node not implemnted""" + return Response(status=status.HTTP_404_NOT_FOUND) + + def delete(self, request, pk, format=None): + """delete node not implemnted""" + return Response(status=status.HTTP_404_NOT_FOUND) + + + + diff --git a/plstackapi/core/views/roles.py b/plstackapi/core/views/roles.py index 05eb77e..74fe789 100644 --- a/plstackapi/core/views/roles.py +++ b/plstackapi/core/views/roles.py @@ -37,7 +37,7 @@ class RoleRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - roles = get_roles(data['auth'], {'role_id': pk}) + roles = get_roles(data['auth'], pk) if not roles: return Response(status=status.HTTP_404_NOT_FOUND) serializer = RoleSerializer(roles[0]) @@ -51,7 +51,7 @@ class RoleRetrieveUpdateDestroy(APIView): data = parse_request(request.DATA) if 'auth' not in data: return Response(status=status.HTTP_400_BAD_REQUEST) - delete_role(data['auth'], {'role_id': pk}) + delete_role(data['auth'], pk) return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/plstackapi/core/views/site_privileges.py b/plstackapi/core/views/site_privileges.py new file mode 100644 index 0000000..b104fa7 --- /dev/null +++ b/plstackapi/core/views/site_privileges.py @@ -0,0 +1,66 @@ +from django.http import Http404 +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + +from plstackapi.core.api.site_privileges import add_site_privilege, delete_site_privilege, get_site_privileges, update_site_privilege +from plstackapi.core.serializers import SitePrivilegeSerializer +from plstackapi.util.request import parse_request + + +class SitePrivilegeListCreate(APIView): + """ + List all site_privileges or create a new site_privilege. + """ + + def post(self, request, format = None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'site_privilege' in data: + site_privilege = add_site_privilege(data['auth'], data['site_privilege']) + serializer = SitePrivilegeSerializer(site_privilege) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + site_privileges = get_site_privileges(data['auth']) + serializer = SitePrivilegeSerializer(site_privileges, many=True) + return Response(serializer.data) + + +class SitePrivilegeRetrieveUpdateDestroy(APIView): + """ + Retrieve, update or delete a site_privilege + """ + + def post(self, request, pk, format=None): + """Retrieve a site_privilege""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + site_privileges = get_site_privileges(data['auth'], pk) + if not site_privileges: + return Response(status=status.HTTP_404_NOT_FOUND) + serializer = SitePrivilegeSerializer(site_privileges[0]) + return Response(serializer.data) + + def put(self, request, pk, format=None): + """update a site_privilege""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'site_privilege' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + + site_privilege = update_site_privilege(pk, data['site_privilege']) + serializer = SitePrivilegeSerializer(site_privilege) + return Response(serializer.data) + + def delete(self, request, pk, format=None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + delete_site_privilege(data['auth'], pk) + return Response(status=status.HTTP_204_NO_CONTENT) + + + diff --git a/plstackapi/core/views/slice_memberships.py b/plstackapi/core/views/slice_memberships.py new file mode 100644 index 0000000..a4f6848 --- /dev/null +++ b/plstackapi/core/views/slice_memberships.py @@ -0,0 +1,66 @@ +from django.http import Http404 +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + +from plstackapi.core.api.slice_memberships import add_slice_membership, delete_slice_membership, get_slice_memberships, update_slice_membership +from plstackapi.core.serializers import SliceMembershipSerializer +from plstackapi.util.request import parse_request + + +class SliceMembershipListCreate(APIView): + """ + List all slice_memberships or create a new slice_membership. + """ + + def post(self, request, format = None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'slice_membership' in data: + slice_membership = add_slice_membership(data['auth'], data['slice_membership']) + serializer = SliceMembershipSerializer(slice_membership) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + slice_memberships = get_slice_memberships(data['auth']) + serializer = SliceMembershipSerializer(slice_memberships, many=True) + return Response(serializer.data) + + +class SliceMembershipRetrieveUpdateDestroy(APIView): + """ + Retrieve, update or delete a slice_membership + """ + + def post(self, request, pk, format=None): + """Retrieve a slice_membership""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + slice_memberships = get_slice_memberships(data['auth'], pk) + if not slice_memberships: + return Response(status=status.HTTP_404_NOT_FOUND) + serializer = SliceMembershipSerializer(slice_memberships[0]) + return Response(serializer.data) + + def put(self, request, pk, format=None): + """update a slice_membership""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'slice_membership' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + + slice_membership = update_slice_membership(pk, data['slice_membership']) + serializer = SliceMembershipSerializer(slice_membership) + return Response(serializer.data) + + def delete(self, request, pk, format=None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + delete_slice_membership(data['auth'], pk) + return Response(status=status.HTTP_204_NO_CONTENT) + + + diff --git a/plstackapi/core/views/slices.py b/plstackapi/core/views/slices.py index 6015f4d..01415bb 100644 --- a/plstackapi/core/views/slices.py +++ b/plstackapi/core/views/slices.py @@ -40,7 +40,7 @@ class SliceRetrieveUpdateDestroy(APIView): slices = get_slices(data['auth'], {'id': pk}) if not slices: return Response(status=status.HTTP_404_NOT_FOUND) - serializer = UserSerializer(slices[0]) + serializer = SliceSerializer(slices[0]) return Response(serializer.data) def put(self, request, pk, format=None): @@ -52,7 +52,7 @@ class SliceRetrieveUpdateDestroy(APIView): return Response(status=status.HTTP_400_BAD_REQUEST) slice = update_slice(pk, data['slice']) - serializer = UserSerializer(slice) + serializer = SliceSerializer(slice) return Response(serializer.data) def delete(self, request, pk, format=None): diff --git a/plstackapi/core/views/slivers.py b/plstackapi/core/views/slivers.py new file mode 100644 index 0000000..4063419 --- /dev/null +++ b/plstackapi/core/views/slivers.py @@ -0,0 +1,66 @@ +from django.http import Http404 +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + +from plstackapi.core.api.slivers import add_sliver, delete_sliver, get_slivers, update_sliver +from plstackapi.core.serializers import SliverSerializer +from plstackapi.util.request import parse_request + + +class SliverListCreate(APIView): + """ + List all slivers or create a new sliver. + """ + + def post(self, request, format = None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'sliver' in data: + sliver = add_sliver(data['auth'], data['sliver']) + serializer = SliverSerializer(sliver) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + slivers = get_slivers(data['auth']) + serializer = SliverSerializer(slivers, many=True) + return Response(serializer.data) + + +class SliverRetrieveUpdateDestroy(APIView): + """ + Retrieve, update or delete a sliver + """ + + def post(self, request, pk, format=None): + """Retrieve a sliver""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + slivers = get_slivers(data['auth'], {'id': pk}) + if not slivers: + return Response(status=status.HTTP_404_NOT_FOUND) + serializer = SliverSerializer(slivers[0]) + return Response(serializer.data) + + def put(self, request, pk, format=None): + """update a sliver""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'sliver' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + + sliver = update_sliver(pk, data['sliver']) + serializer = SliverSerializer(sliver) + return Response(serializer.data) + + def delete(self, request, pk, format=None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + delete_sliver(data['auth'], {'id': pk}) + return Response(status=status.HTTP_204_NO_CONTENT) + + + diff --git a/plstackapi/core/views/subnets.py b/plstackapi/core/views/subnets.py new file mode 100644 index 0000000..d96d048 --- /dev/null +++ b/plstackapi/core/views/subnets.py @@ -0,0 +1,66 @@ +from django.http import Http404 +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status + +from plstackapi.core.api.subnets import add_subnet, delete_subnet, get_subnets, update_subnet +from plstackapi.core.serializers import SubnetSerializer +from plstackapi.util.request import parse_request + + +class SubnetListCreate(APIView): + """ + List all subnets or create a new subnet. + """ + + def post(self, request, format = None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'subnet' in data: + subnet = add_subnet(data['auth'], data['subnet']) + serializer = SubnetSerializer(subnet) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + subnets = get_subnets(data['auth']) + serializer = SubnetSerializer(subnets, many=True) + return Response(serializer.data) + + +class SubnetRetrieveUpdateDestroy(APIView): + """ + Retrieve, update or delete a subnet + """ + + def post(self, request, pk, format=None): + """Retrieve a subnet""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + subnets = get_subnets(data['auth'], {'id': pk}) + if not subnets: + return Response(status=status.HTTP_404_NOT_FOUND) + serializer = SubnetSerializer(subnets[0]) + return Response(serializer.data) + + def put(self, request, pk, format=None): + """update a subnet""" + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + elif 'subnet' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + + subnet = update_subnet(pk, data['subnet']) + serializer = SubnetSerializer(subnet) + return Response(serializer.data) + + def delete(self, request, pk, format=None): + data = parse_request(request.DATA) + if 'auth' not in data: + return Response(status=status.HTTP_400_BAD_REQUEST) + delete_subnet(data['auth'], {'id': pk}) + return Response(status=status.HTTP_204_NO_CONTENT) + + + diff --git a/plstackapi/openstack/driver.py b/plstackapi/openstack/driver.py index 8b475de..8817990 100644 --- a/plstackapi/openstack/driver.py +++ b/plstackapi/openstack/driver.py @@ -195,7 +195,8 @@ class OpenStackDriver: image_id = images[0]['id'] hints = {} if hostname: - hints['force_hosts']= hostname + #hints['force_hosts']= hostname + hints['availability-zone'] = 'nova:%s' % hostname server = self.shell.nova.servers.create( name=name, key_name = key_name, -- 2.43.0