merge latest code
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.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 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.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 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.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 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.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 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 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 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 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.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 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 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 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 @@
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
+from plstackapi.core.models import Slice
+from plstackapi.core.api.sites import _get_sites
+
+
+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 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
-
-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 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 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 @@
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 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.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 @@
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 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 @@
'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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
'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 @@
# 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 @@
'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 @@
'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 @@
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 @@
# 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 @@
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<pk>[0-9]+)/$', views.SiteDetail.as_view(), name='site-detail'),
+
+ url(r'^plstackapi/roles/$', RoleListCreate.as_view(), name='role-list'),
+ url(r'^plstackapi/roles/(?P<pk>[a-zA-Z0-9]+)/$', RoleRetrieveUpdateDestroy.as_view(), name='role-detail'),
- url(r'^plstackapi/slices/$', views.SliceList.as_view(), name='slice-list'),
- url(r'^plstackapi/slices/(?P<pk>[0-9]+)/$', views.SliceDetail.as_view(), name='slice-detail'),
+ url(r'^plstackapi/users/$', UserListCreate.as_view(), name='user-list'),
+ url(r'^plstackapi/users/(?P<pk>[a-zA-Z0-9]+)/$', UserRetrieveUpdateDestroy.as_view(), name='user-detail'),
- url(r'^plstackapi/slivers/$', views.SliverList.as_view()),
- url(r'^plstackapi/slivers/(?P<pk>[0-9]+)/$', views.SliverDetail.as_view()),
+ url(r'^plstackapi/keys/$', KeyListCreate.as_view(), name='key-list'),
+ url(r'^plstackapi/keys/(?P<pk>[a-zA-Z0-9]+)/$', KeyRetrieveUpdateDestroy.as_view(), name='key-detail'),
- url(r'^plstackapi/nodes/$', views.NodeList.as_view(), name='node-list'),
- url(r'^plstackapi/nodes/(?P<pk>[0-9]+)/$', views.NodeDetail.as_view(), name='node-detail'),
+ url(r'^plstackapi/sites/$', SiteListCreate.as_view(), name='site-list'),
+ url(r'^plstackapi/sites/(?P<pk>[a-zA-Z0-9_]+)/$', SiteRetrieveUpdateDestroy.as_view(), name='site-detail'),
- url(r'^plstackapi/deploymentnetworks/$', views.DeploymentNetworkList.as_view(), name='deploymentnetwork-list'),
- url(r'^plstackapi/deploymentnetworks/(?P<pk>[0-9]+)/$', views.DeploymentNetworkDetail.as_view(), name='deploymentnetwork-detail'),
+ url(r'^plstackapi/site_privileges/$', SitePrivilegeListCreate.as_view(), name='siteprivilege-list'),
+ url(r'^plstackapi/site_privileges/(?P<pk>[a-zA-Z0-9_]+)/$', SitePrivilegeRetrieveUpdateDestroy.as_view(), name='siteprivilege-detail'),
+ url(r'^plstackapi/slices/$', SliceListCreate.as_view(), name='slice-list'),
+ url(r'^plstackapi/slices/(?P<pk>[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<pk>[0-9]+)/$', SliceMembershipRetrieveUpdateDestroy.as_view(), name='slice_membership-detail'),
+
+ url(r'^plstackapi/subnets/$', SubnetListCreate.as_view(), name='subnet-list'),
+ url(r'^plstackapi/subnets/(?P<pk>[0-9]+)/$', SubnetRetrieveUpdateDestroy.as_view(), name='subnet-detail'),
+
+ url(r'^plstackapi/slivers/$', SliverListCreate.as_view(), name='sliver-list'),
+ url(r'^plstackapi/slivers/(?P<pk>[0-9]+)/$', SliverRetrieveUpdateDestroy.as_view(), name='sliver-detail'),
+
+ url(r'^plstackapi/nodes/$', NodeListCreate.as_view(), name='node-list'),
+ url(r'^plstackapi/nodes/(?P<pk>[0-9]+)/$', NodeRetrieveUpdateDestroy.as_view(), name='node-detail'),
+
+ url(r'^plstackapi/deploymentnetworks/$', DeploymentNetworkListCreate.as_view(), name='deploymentnetwork-list'),
+ url(r'^plstackapi/deploymentnetworks/(?P<pk>[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<pk>[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<pk>[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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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)
+
+
+