Merge pick up, tweaked role/site/plcore_base or os_manager path when OpenStack not present
diff --git a/plstackapi/planetstack/__init__.py b/planetstack/__init__.py
similarity index 100%
rename from plstackapi/planetstack/__init__.py
rename to planetstack/__init__.py
diff --git a/plstackapi/core/__init__.py b/planetstack/core/__init__.py
similarity index 100%
rename from plstackapi/core/__init__.py
rename to planetstack/core/__init__.py
diff --git a/plstackapi/core/admin.py b/planetstack/core/admin.py
similarity index 91%
rename from plstackapi/core/admin.py
rename to planetstack/core/admin.py
index 422ff4b..c9bba2c 100644
--- a/plstackapi/core/admin.py
+++ b/planetstack/core/admin.py
@@ -1,6 +1,6 @@
-from plstackapi.core.models import Site
-from plstackapi.core.models import *
-from plstackapi.openstack.manager import OpenStackManager
+from core.models import Site
+from core.models import *
+from openstack.manager import OpenStackManager
 
 from django.contrib import admin
 from django.contrib.auth.models import Group
@@ -39,12 +39,16 @@
     model = Site
     extra = 0
 
+class UserInline(admin.TabularInline):
+    model = User
+    extra = 0
+
 class SliceInline(admin.TabularInline):
     model = Slice
     extra = 0
 
 class UserInline(admin.TabularInline):
-    model = PLUser
+    model = User
     extra = 0
 
 class RoleInline(admin.TabularInline):
@@ -129,7 +133,8 @@
                 continue
             # give inline object access to driver and caller
             auth = request.session.get('auth', {})
-            auth['tenant'] = request.user.site.login_base
+            if request.user.site:
+                auth['tenant'] = request.user.site.login_base
             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
             yield inline.get_formset(request, obj)
 
@@ -141,7 +146,7 @@
     ]
     list_display = ('name', 'login_base','site_url', 'enabled')
     filter_horizontal = ('deployments',)
-    inlines = [NodeInline,]
+    inlines = [NodeInline, UserInline]
     search_fields = ['name']
 
     def queryset(self, request):
@@ -162,7 +167,7 @@
                 continue
             # give inline object access to driver and caller
             auth = request.session.get('auth', {})
-            auth['tenant'] = request.user.site.login_base
+            #auth['tenant'] = request.user.site.login_base
             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
             yield inline.get_formset(request, obj)
 
@@ -189,30 +194,30 @@
     def save_model(self, request, obj, form, change):
         # update openstack connection to use this site/tenant   
         auth = request.session.get('auth', {})
-        auth['tenant'] = obj.site.login_base
+        #auth['tenant'] = obj.site.login_base
         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
         obj.save()
 
     def delete_model(self, request, obj):
         # update openstack connection to use this site/tenant   
         auth = request.session.get('auth', {})
-        auth['tenant'] = obj.site.login_base
+        #auth['tenant'] = obj.site.login_base
         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
         obj.delete()
 
 class KeyAdmin(OSModelAdmin):
     fieldsets = [
-        ('Key', {'fields': ['key', 'type', 'blacklisted', 'user']})
+        ('Key', {'fields': ['key', 'type', 'blacklisted']})
     ]
-    list_display = ['key', 'type', 'blacklisted', 'user']
+    list_display = ['key', 'type', 'blacklisted']
 
-    def queryset(self, request):
+    #def queryset(self, request):
         # admins can see all keys. Users can only see their own key.
-        if request.user.is_admin:
-            qs = super(KeyAdmin, self).queryset(request) 
-        else:
-            qs = Key.objects.filter(user=request.user)
-        return qs 
+        #if request.user.is_admin:
+        #    qs = super(KeyAdmin, self).queryset(request) 
+        #else:
+        #    qs = Key.objects.filter(user=request.user)
+        #return qs 
         
 class SliceAdmin(OSModelAdmin):
     fields = ['name', 'site', 'serviceClass', 'description', 'slice_url']
@@ -360,8 +365,8 @@
     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
 
     class Meta:
-        model = PLUser
-        fields = ('email', 'firstname', 'lastname', 'phone', 'site')
+        model = User
+        fields = ('email', 'firstname', 'lastname', 'phone', 'key', 'site')
 
     def clean_password2(self):
         # Check that the two password entries match
@@ -389,7 +394,7 @@
     password = ReadOnlyPasswordHashField()
 
     class Meta:
-        model = PLUser
+        model = User
 
     def clean_password(self):
         # Regardless of what the user provides, return the initial value.
@@ -398,7 +403,7 @@
         return self.initial["password"]
 
 
-class PLUserAdmin(UserAdmin, OSModelAdmin):
+class UserAdmin(UserAdmin, OSModelAdmin):
     class Meta:
         app_label = "core"
 
@@ -413,13 +418,13 @@
     list_filter = ('site',)
     fieldsets = (
         (None, {'fields': ('email', 'password')}),
-        ('Personal info', {'fields': ('firstname','lastname','phone', 'is_admin', 'site')}),
+        ('Personal info', {'fields': ('firstname','lastname','phone', 'is_admin', 'site', 'key')}),
         #('Important dates', {'fields': ('last_login',)}),
     )
     add_fieldsets = (
         (None, {
             'classes': ('wide',),
-            'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'is_admin', 'password1', 'password2')}
+            'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'is_admin', 'key','password1', 'password2')}
         ),
     )
     search_fields = ('email',)
@@ -434,18 +439,20 @@
 user_logged_in.connect(cache_credentials)
 
 # Now register the new UserAdmin...
-admin.site.register(PLUser, PLUserAdmin)
+admin.site.register(User, UserAdmin)
 # ... and, since we're not using Django's builtin permissions,
 # unregister the Group model from admin.
 admin.site.unregister(Group)
 
 admin.site.register(Site, SiteAdmin)
-admin.site.register(SitePrivilege, SitePrivilegeAdmin)
+#admin.site.register(SitePrivilege, SitePrivilegeAdmin)
 admin.site.register(Slice, SliceAdmin)
-admin.site.register(SliceMembership, SliceMembershipAdmin)
-admin.site.register(Node, NodeAdmin)
+#admin.site.register(SliceMembership, SliceMembershipAdmin)
+#admin.site.register(Subnet, SubnetAdmin)
+admin.site.register(Image, ImageAdmin)
+#admin.site.register(Node, NodeAdmin)
 admin.site.register(Sliver, SliverAdmin)
 admin.site.register(Key, KeyAdmin)
-admin.site.register(Role, RoleAdmin)
+#admin.site.register(Role, RoleAdmin)
 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
 
diff --git a/plstackapi/core/api/__init__.py b/planetstack/core/api/__init__.py
similarity index 100%
rename from plstackapi/core/api/__init__.py
rename to planetstack/core/api/__init__.py
diff --git a/planetstack/core/api/auth.py b/planetstack/core/api/auth.py
new file mode 100644
index 0000000..8796f14
--- /dev/null
+++ b/planetstack/core/api/auth.py
@@ -0,0 +1,8 @@
+from openstack.client import OpenStackClient
+
+def auth_check(username, password, tenant):
+    client = OpenStackClient(username=username,
+                             password=password,
+                             tenant=tenant)
+    client.authenticate()
+    return client
diff --git a/plstackapi/core/api/deployment_networks.py b/planetstack/core/api/deployment_networks.py
similarity index 96%
rename from plstackapi/core/api/deployment_networks.py
rename to planetstack/core/api/deployment_networks.py
index 3db7285..fcd2145 100644
--- a/plstackapi/core/api/deployment_networks.py
+++ b/planetstack/core/api/deployment_networks.py
@@ -1,6 +1,6 @@
 from types import StringTypes
+from core.models import DeploymentNetwork
 from django.contrib.auth import authenticate
-from plstackapi.core.models import DeploymentNetwork
 
 def _get_deployment_networks(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/images.py b/planetstack/core/api/images.py
similarity index 95%
rename from plstackapi/core/api/images.py
rename to planetstack/core/api/images.py
index ec18c11..933216f 100644
--- a/plstackapi/core/api/images.py
+++ b/planetstack/core/api/images.py
@@ -1,6 +1,6 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.core.models import Image
+from core.models import Image
  
 def _get_images(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/keys.py b/planetstack/core/api/keys.py
similarity index 91%
rename from plstackapi/core/api/keys.py
rename to planetstack/core/api/keys.py
index 66af59e..3528cd3 100644
--- a/plstackapi/core/api/keys.py
+++ b/planetstack/core/api/keys.py
@@ -1,8 +1,8 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import Key
-from plstackapi.core.api.users import _get_users
+from openstack.manager import OpenStackManager
+from core.models import Key
+from core.api.users import _get_users
 
 
 def _get_keys(filter):
diff --git a/plstackapi/core/api/nodes.py b/planetstack/core/api/nodes.py
similarity index 95%
rename from plstackapi/core/api/nodes.py
rename to planetstack/core/api/nodes.py
index e5332eb..4f7ceeb 100644
--- a/plstackapi/core/api/nodes.py
+++ b/planetstack/core/api/nodes.py
@@ -1,6 +1,6 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.core.models import Node
+from core.models import Node
  
 def _get_nodes(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/roles.py b/planetstack/core/api/roles.py
similarity index 92%
rename from plstackapi/core/api/roles.py
rename to planetstack/core/api/roles.py
index bf74222..4ea05c9 100644
--- a/plstackapi/core/api/roles.py
+++ b/planetstack/core/api/roles.py
@@ -1,7 +1,7 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import Role
+from openstack.manager import OpenStackManager
+from core.models import Role
  
 
 def _get_roles(filter):
diff --git a/plstackapi/core/api/site_privileges.py b/planetstack/core/api/site_privileges.py
similarity index 89%
rename from plstackapi/core/api/site_privileges.py
rename to planetstack/core/api/site_privileges.py
index d425728..6d79701 100644
--- a/plstackapi/core/api/site_privileges.py
+++ b/planetstack/core/api/site_privileges.py
@@ -1,11 +1,11 @@
 from types import StringTypes
 import re
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import SitePrivilege
-from plstackapi.core.api.users import _get_users
-from plstackapi.core.api.sites import _get_sites
-from plstackapi.core.api.roles import _get_roles
+from openstack.manager import OpenStackManager
+from core.models import SitePrivilege
+from core.api.users import _get_users
+from core.api.sites import _get_sites
+from core.api.roles import _get_roles
 
 
 def _get_site_privileges(filter):
diff --git a/plstackapi/core/api/sites.py b/planetstack/core/api/sites.py
similarity index 94%
rename from plstackapi/core/api/sites.py
rename to planetstack/core/api/sites.py
index d93df0e..123f139 100644
--- a/plstackapi/core/api/sites.py
+++ b/planetstack/core/api/sites.py
@@ -1,8 +1,7 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager    
-from plstackapi.core.models import Site
-
+from openstack.manager import OpenStackManager    
+from core.models import Site
 
 def _get_sites(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/slice_memberships.py b/planetstack/core/api/slice_memberships.py
similarity index 89%
rename from plstackapi/core/api/slice_memberships.py
rename to planetstack/core/api/slice_memberships.py
index ae6baa4..3e25ae7 100644
--- a/plstackapi/core/api/slice_memberships.py
+++ b/planetstack/core/api/slice_memberships.py
@@ -1,10 +1,10 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import SliceMembership
-from plstackapi.core.api.users import _get_users
-from plstackapi.core.api.slices import _get_slices
-from plstackapi.core.api.roles import _get_roles
+from openstack.manager import OpenStackManager
+from core.models import SliceMembership
+from core.api.users import _get_users
+from core.api.slices import _get_slices
+from core.api.roles import _get_roles
 
 def _get_slice_memberships(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/slices.py b/planetstack/core/api/slices.py
similarity index 93%
rename from plstackapi/core/api/slices.py
rename to planetstack/core/api/slices.py
index f55249a..c9e94a2 100644
--- a/plstackapi/core/api/slices.py
+++ b/planetstack/core/api/slices.py
@@ -1,9 +1,9 @@
 import re
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import Slice
-from plstackapi.core.api.sites import _get_sites
+from openstack.manager import OpenStackManager
+from core.models import Slice
+from core.api.sites import _get_sites
 
 def _get_slices(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/plstackapi/core/api/slivers.py b/planetstack/core/api/slivers.py
similarity index 84%
rename from plstackapi/core/api/slivers.py
rename to planetstack/core/api/slivers.py
index f832dae..16a7e0b 100644
--- a/plstackapi/core/api/slivers.py
+++ b/planetstack/core/api/slivers.py
@@ -1,13 +1,12 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager
-from plstackapi.core.models import Sliver, Slice
-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
- 
+from openstack.manager import OpenStackManager
+from core.models import Sliver, Slice
+from core.api.images import _get_images
+from core.api.keys import _get_keys
+from core.api.slices import _get_slices
+from core.api.deployment_networks import _get_deployment_networks
+from core.api.nodes import _get_nodes
 
 def _get_slivers(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
diff --git a/planetstack/core/api/subnets.py b/planetstack/core/api/subnets.py
new file mode 100644
index 0000000..d618eda
--- /dev/null
+++ b/planetstack/core/api/subnets.py
@@ -0,0 +1,74 @@
+import commands
+from types import StringTypes
+from openstack.client import OpenStackClient
+from openstack.driver import OpenStackDriver
+from core.api.auth import auth_check
+from core.models import Subnet
+from core.api.slices import _get_slices
+
+
+def _get_subnets(filter):
+    if isinstance(filter, StringTypes) and filter.isdigit():
+        filter = int(filter)
+    if isinstance(filter, int):
+        subnets = Subnet.objects.filter(id=filter)
+    elif isinstance(filter, StringTypes):
+        # the name is the subnet's slice's name
+        slices = _get_slices(filter)
+        slice = None
+        if slices: slice=slices[0]
+        subnets = Subnet.objects.filter(slice=slice)
+    elif isinstance(filter, dict):
+        subnets = Subnet.objects.filter(**filter)
+    else:
+        subnets = []
+    return subnets
+
+def add_subnet(auth, fields):
+    driver = OpenStackDriver(client = auth_check(auth))
+    slices = _get_slices(fields.get('slice')) 
+    if slices: fields['slice'] = slices[0]     
+    subnet = Subnet(**fields)
+    # create quantum subnet
+    quantum_subnet = driver.create_subnet(name= subnet.slice.name,
+                                          network_id=subnet.slice.network_id,
+                                          cidr_ip = subnet.cidr,
+                                          ip_version=subnet.ip_version,
+                                          start = subnet.start,
+                                          end = subnet.end)
+    subnet.subnet_id=quantum_subnet['id']
+    ## set dns servers
+    #driver.update_subnet(subnet.id, {'dns_nameservers': ['8.8.8.8', '8.8.4.4']})
+
+    # add subnet as interface to slice's router
+    try: driver.add_router_interface(subnet.slice.router_id, subnet.subnet_id)
+    except: pass         
+    #add_route = 'route add -net %s dev br-ex gw 10.100.0.5' % self.cidr
+    commands.getstatusoutput(add_route)    
+    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()
+        #del_route = 'route del -net %s' % subnet.cidr
+    commands.getstatusoutput(del_route)
+    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/planetstack/core/api/users.py
similarity index 84%
rename from plstackapi/core/api/users.py
rename to planetstack/core/api/users.py
index c190562..08e851c 100644
--- a/plstackapi/core/api/users.py
+++ b/planetstack/core/api/users.py
@@ -1,18 +1,18 @@
 from types import StringTypes
 from django.contrib.auth import authenticate
-from plstackapi.openstack.manager import OpenStackManager    
-from plstackapi.core.models import PLUser, Site
-from plstackapi.core.api.sites import _get_sites
+from openstack.manager import OpenStackManager    
+from core.models import User, Site
+from core.api.sites import _get_sites
 
 def _get_users(filter):
     if isinstance(filter, StringTypes) and filter.isdigit():
         filter = int(filter)
     if isinstance(filter, int):
-        users = PLUser.objects.filter(id=filter)
+        users = User.objects.filter(id=filter)
     elif isinstance(filter, StringTypes):
-        users = PLUser.objects.filter(email=filter)
+        users = User.objects.filter(email=filter)
     elif isinstance(filter, dict):
-        users = PLUser.objects.filter(**filter)
+        users = User.objects.filter(**filter)
     else:
         users = []
     return users 
@@ -24,7 +24,7 @@
 
     sites = _get_sites(fields.get('site')) 
     if sites: fields['site'] = sites[0]     
-    user = PLUser(**fields)
+    user = User(**fields)
     user.os_manager = OpenStackManager(auth=auth, caller = user)
     user.save()
     return user
@@ -34,7 +34,7 @@
                         password=auth.get('password'))
     auth['tenant'] = user.site.login_base
 
-    users = PLUser.objects.filter(id=id)
+    users = User.objects.filter(id=id)
     if not users:
         return
 
@@ -47,8 +47,6 @@
         nova_fields['password'] = fields['password']
     if 'enabled' in fields:
         nova_fields['enabled'] = fields['enabled']
-
-    
     sites = _get_sites(fields.get('site'))
     if sites: fields['site'] = sites[0]
     user.os_manager = OpenStackManager(auth=auth, caller = user)
diff --git a/plstackapi/core/api_root.py b/planetstack/core/api_root.py
similarity index 100%
rename from plstackapi/core/api_root.py
rename to planetstack/core/api_root.py
diff --git a/plstackapi/core/fixtures/__init__.py b/planetstack/core/fixtures/__init__.py
similarity index 100%
rename from plstackapi/core/fixtures/__init__.py
rename to planetstack/core/fixtures/__init__.py
diff --git a/plstackapi/core/fixtures/initial_data.json b/planetstack/core/fixtures/initial_data.json
similarity index 100%
rename from plstackapi/core/fixtures/initial_data.json
rename to planetstack/core/fixtures/initial_data.json
diff --git a/planetstack/core/models/__init__.py b/planetstack/core/models/__init__.py
new file mode 100644
index 0000000..4d9387b
--- /dev/null
+++ b/planetstack/core/models/__init__.py
@@ -0,0 +1,14 @@
+from .plcorebase import PlCoreBase
+from .deploymentnetwork import DeploymentNetwork
+from .site import Site
+from .site import SitePrivilege
+from .image import Image
+from .key import Key
+from .user import User
+from .role import Role
+from .node import Node
+from .slice import Slice
+from .slice import SliceMembership
+from .sliver import Sliver
+from .subnet import Subnet
+
diff --git a/plstackapi/core/models/deploymentnetwork.py b/planetstack/core/models/deploymentnetwork.py
similarity index 84%
rename from plstackapi/core/models/deploymentnetwork.py
rename to planetstack/core/models/deploymentnetwork.py
index 740be33..4068ee9 100644
--- a/plstackapi/core/models/deploymentnetwork.py
+++ b/planetstack/core/models/deploymentnetwork.py
@@ -1,6 +1,6 @@
 import os
 from django.db import models
-from plstackapi.core.models import PlCoreBase
+from core.models import PlCoreBase
 
 # Create your models here.
 
diff --git a/plstackapi/core/models/image.py b/planetstack/core/models/image.py
similarity index 88%
rename from plstackapi/core/models/image.py
rename to planetstack/core/models/image.py
index 930b7df..b4803e2 100644
--- a/plstackapi/core/models/image.py
+++ b/planetstack/core/models/image.py
@@ -1,6 +1,6 @@
 import os
 from django.db import models
-from plstackapi.core.models import PlCoreBase
+from core.models import PlCoreBase
 
 # Create your models here.
 
diff --git a/planetstack/core/models/key.py b/planetstack/core/models/key.py
new file mode 100644
index 0000000..7a8b322
--- /dev/null
+++ b/planetstack/core/models/key.py
@@ -0,0 +1,29 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+from openstack.manager import OpenStackManager
+
+
+# Create your models here.
+
+class Key(PlCoreBase):
+    name = models.CharField(max_length=256)
+    nkey_id = models.CharField(null=True, blank=True, max_length=256, unique=True)
+    key = models.CharField(max_length=512)
+    type = models.CharField(max_length=256)
+    blacklisted = models.BooleanField(default=False)
+
+    def __unicode__(self):  return u'%s' % (self.key)
+
+    def save(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_key(self)
+        super(Key, self).save(*args, **kwds)
+
+    def delete(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_key(self)
+        super(Key, self).delete(*args, **kwds) 
+    
diff --git a/plstackapi/core/models/node.py b/planetstack/core/models/node.py
similarity index 72%
rename from plstackapi/core/models/node.py
rename to planetstack/core/models/node.py
index a4252b1..a249628 100644
--- a/plstackapi/core/models/node.py
+++ b/planetstack/core/models/node.py
@@ -1,8 +1,8 @@
 import os
 from django.db import models
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import Site
-from plstackapi.core.models import DeploymentNetwork
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import DeploymentNetwork
 
 # Create your models here.
 
diff --git a/plstackapi/core/models/plcorebase.py b/planetstack/core/models/plcorebase.py
similarity index 99%
rename from plstackapi/core/models/plcorebase.py
rename to planetstack/core/models/plcorebase.py
index eac3114..ed7c3ff 100644
--- a/plstackapi/core/models/plcorebase.py
+++ b/planetstack/core/models/plcorebase.py
@@ -16,30 +16,30 @@
         self.__initial = self._dict
 
     @property
-    def diff(self):

-        d1 = self.__initial

-        d2 = self._dict

-        diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]]

-        return dict(diffs)

-

-    @property

-    def has_changed(self):

-        return bool(self.diff)

-

-    @property

-    def changed_fields(self):

-        return self.diff.keys()

-

-    def get_field_diff(self, field_name):

-        return self.diff.get(field_name, None)

-

-    def save(self, *args, **kwargs):

-        super(PlCoreBase, self).save(*args, **kwargs)

+    def diff(self):
+        d1 = self.__initial
+        d2 = self._dict
+        diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]]
+        return dict(diffs)
+
+    @property
+    def has_changed(self):
+        return bool(self.diff)
+
+    @property
+    def changed_fields(self):
+        return self.diff.keys()
+
+    def get_field_diff(self, field_name):
+        return self.diff.get(field_name, None)
+
+    def save(self, *args, **kwargs):
+        super(PlCoreBase, self).save(*args, **kwargs)
         self.__initial = self._dict
 
     @property
-    def _dict(self):

-        return model_to_dict(self, fields=[field.name for field in

+    def _dict(self):
+        return model_to_dict(self, fields=[field.name for field in
                              self._meta.fields])
 
 
diff --git a/planetstack/core/models/role.py b/planetstack/core/models/role.py
new file mode 100644
index 0000000..e7d31b9
--- /dev/null
+++ b/planetstack/core/models/role.py
@@ -0,0 +1,27 @@
+import os
+import datetime
+from django.db import models
+from core.models import PlCoreBase
+from openstack.manager import OpenStackManager
+
+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)
+
+    def __unicode__(self):  return u'%s' % (self.role_type)
+
+
+    def save(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_role(self)
+        super(Role, self).save(*args, **kwds)
+    
+    def delete(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_role(self)   
+        super(Role, self).delete(*args, **kwds)
+            
diff --git a/plstackapi/core/models/site.py b/planetstack/core/models/site.py
similarity index 63%
rename from plstackapi/core/models/site.py
rename to planetstack/core/models/site.py
index cba70f4..11e6a28 100644
--- a/plstackapi/core/models/site.py
+++ b/planetstack/core/models/site.py
@@ -1,8 +1,8 @@
 import os
 from django.db import models
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import DeploymentNetwork
-
+from core.models import PlCoreBase
+from core.models import DeploymentNetwork
+from openstack.manager import OpenStackManager
 
 class Site(PlCoreBase):
 
@@ -21,29 +21,37 @@
     def __unicode__(self):  return u'%s' % (self.name)
 
     def save(self, *args, **kwds):
-        self.os_manager.save_site(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_site(self)
         super(Site, self).save(*args, **kwds)               
 
 
     def delete(self, *args, **kwds):
-        self.os_manager.delete_site(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_site(self)
         super(Site, self).delete(*args, **kwds)         
         
 
 class SitePrivilege(PlCoreBase):
 
-    user = models.ForeignKey('PLUser', related_name='site_privileges')
+    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):
-        self.os_manager.driver.add_user_role(self.user.user_id, self.site.tenant_id, self.role.role_type)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.driver.add_user_role(self.user.kuser_id, self.site.tenant_id, self.role.role_type)
         super(SitePrivilege, self).save(*args, **kwds)
 
     def delete(self, *args, **kwds):
-        self.os_manager.driver.delete_user_role(self.user.user_id, self.site.tenant_id, self.role.role_type)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.driver.delete_user_role(self.user.kuser_id, self.site.tenant_id, self.role.role_type)
         super(SitePrivilege, self).delete(*args, **kwds)
 
 
diff --git a/plstackapi/core/models/slice.py b/planetstack/core/models/slice.py
similarity index 65%
rename from plstackapi/core/models/slice.py
rename to planetstack/core/models/slice.py
index f29d93a..a4eb3a4 100644
--- a/plstackapi/core/models/slice.py
+++ b/planetstack/core/models/slice.py
@@ -1,10 +1,12 @@
 import os
 from django.db import models
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import Site
-from plstackapi.core.models import PLUser
-from plstackapi.core.models import Role
-from plstackapi.core.models import DeploymentNetwork
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import User
+from core.models import Role
+from core.models import DeploymentNetwork
+from openstack.manager import OpenStackManager
+
 # Create your models here.
 
 class Slice(PlCoreBase):
@@ -26,24 +28,32 @@
     def __unicode__(self):  return u'%s' % (self.name)
 
     def save(self, *args, **kwds):
-        self.os_manager.save_slice(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_slice(self)
         super(Slice, self).save(*args, **kwds)
 
     def delete(self, *args, **kwds):
-        self.os_manager.delete_slice(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_slice(self)
         super(Slice, self).delete(*args, **kwds)    
 
 class SliceMembership(PlCoreBase):
-    user = models.ForeignKey('PLUser', related_name='slice_memberships')
+    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):
-        self.os_manager.driver.add_user_role(self.user.user_id, self.slice.tenant_id, self.role.role_type)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.driver.add_user_role(self.user.kuser_id, self.slice.tenant_id, self.role.role_type)
         super(SliceMembership, self).save(*args, **kwds)
 
     def delete(self, *args, **kwds):
-        self.os_manager.driver.delete_user_role(self.user.user_id, self.slice.tenant_id, self.role.role_type)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.driver.delete_user_role(self.user.kuser_id, self.slice.tenant_id, self.role.role_type)
         super(SliceMembership, self).delete(*args, **kwds)
diff --git a/plstackapi/core/models/sliver.py b/planetstack/core/models/sliver.py
similarity index 66%
rename from plstackapi/core/models/sliver.py
rename to planetstack/core/models/sliver.py
index 7a2fbed..8ebcbd4 100644
--- a/plstackapi/core/models/sliver.py
+++ b/planetstack/core/models/sliver.py
@@ -1,13 +1,14 @@
 import os
 from django.db import models
 from django.core import exceptions
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import Image
-from plstackapi.core.models import Key
-from plstackapi.core.models import Slice
-from plstackapi.core.models import Node
-from plstackapi.core.models import Site
-from plstackapi.core.models import DeploymentNetwork
+from core.models import PlCoreBase
+from core.models import Image
+from core.models import Key
+from core.models import Slice
+from core.models import Node
+from core.models import Site
+from core.models import DeploymentNetwork
+from openstack.manager import OpenStackManager
 
 # Create your models here.
 class Sliver(PlCoreBase):
@@ -23,14 +24,18 @@
     numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=0)
 
 
-    def __unicode__(self):  return u'%s::%s::%s' % (self.deploymentNetwork, self.slice, self.node.name)
+    def __unicode__(self):  return u'%s' % (self.instance_name)
 
     def save(self, *args, **kwds):
         if not self.name:
             self.name = self.slice.name
-        self.os_manager.save_sliver(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_sliver(self)
         super(Sliver, self).save(*args, **kwds)
 
     def delete(self, *args, **kwds):
-        self.os_manager.delete_sliver(self)
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_sliver(self)
         super(Sliver, self).delete(*args, **kwds)
diff --git a/planetstack/core/models/subnet.py b/planetstack/core/models/subnet.py
new file mode 100644
index 0000000..37175ec
--- /dev/null
+++ b/planetstack/core/models/subnet.py
@@ -0,0 +1,30 @@
+import os
+import commands    
+from django.db import models
+from core.models import PlCoreBase
+from core.models import Slice
+from openstack.manager import OpenStackManager
+
+# Create your models here.
+
+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='subnet')
+
+    def __unicode__(self):  return u'%s' % (self.slice.name)
+
+    def save(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_subnet(self)
+        super(Subnet, self).save(*args, **kwds)
+
+    def delete(self, *args, **kwds):
+        if not hasattr(self, 'os_manager'):
+            setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_subnet(self)
+        super(Subnet, self).delete(*args, **kwds)
diff --git a/plstackapi/core/models/pluser.py b/planetstack/core/models/user.py
similarity index 81%
rename from plstackapi/core/models/pluser.py
rename to planetstack/core/models/user.py
index 8d09310..38c0d89 100644
--- a/plstackapi/core/models/pluser.py
+++ b/planetstack/core/models/user.py
@@ -2,14 +2,14 @@
 import datetime
 from collections import defaultdict
 from django.db import models
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import Site
-from plstackapi.openstack.manager import OpenStackManager
-from django.contrib.auth.models import User, AbstractBaseUser, UserManager, BaseUserManager
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import Key
+from openstack.manager import OpenStackManager
+from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
 
 # Create your models here.
-
-class PLUserManager(BaseUserManager):
+class UserManager(BaseUserManager):
     def create_user(self, email, firstname, lastname, password=None):
         """
         Creates and saves a User with the given email, date of
@@ -19,7 +19,7 @@
             raise ValueError('Users must have an email address')
 
         user = self.model(
-            email=PLUserManager.normalize_email(email),
+            email=UserManager.normalize_email(email),
             firstname=firstname,
             lastname=lastname,
             password=password
@@ -44,7 +44,7 @@
         return user
 
 
-class PLUser(AbstractBaseUser):
+class User(AbstractBaseUser):
 
     class Meta:
         app_label = "core"
@@ -56,19 +56,20 @@
         db_index=True,
     )
 
-    user_id = models.CharField(null=True, blank=True, help_text="keystone user id", max_length=200) 
+    kuser_id = models.CharField(null=True, blank=True, help_text="keystone user id", max_length=200) 
     firstname = models.CharField(help_text="person's given name", max_length=200)
     lastname = models.CharField(help_text="person's surname", max_length=200)
 
     phone = models.CharField(null=True, blank=True, help_text="phone number contact", max_length=100)
     user_url = models.URLField(null=True, blank=True)
     site = models.ForeignKey(Site, related_name='users', verbose_name="Site this user will be homed too", null=True)
+    key = models.ForeignKey(Key, related_name='user', null=True, blank=True)
 
     is_active = models.BooleanField(default=True)
-    is_admin = models.BooleanField(default=False)
+    is_admin = models.BooleanField(default=True)
     is_staff = models.BooleanField(default=True)
 
-    objects = PLUserManager()
+    objects = UserManager()
 
     USERNAME_FIELD = 'email'
     REQUIRED_FIELDS = ['firstname', 'lastname']
@@ -110,15 +111,15 @@
     def save(self, *args, **kwds):
         if not hasattr(self, 'os_manager'):
             setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.save_user(self)
 
-        self.os_manager.save_user(self)
         if not self.id:
             self.set_password(self.password)    
-        super(PLUser, self).save(*args, **kwds)   
+        super(User, self).save(*args, **kwds)   
 
     def delete(self, *args, **kwds):
         if not hasattr(self, 'os_manager'):
             setattr(self, 'os_manager', OpenStackManager())
+            self.os_manager.delete_user(self)
 
-        self.os_manager.delete_user(self)
-        super(PLUser, self).delete(*args, **kwds)    
+        super(User, self).delete(*args, **kwds)    
diff --git a/plstackapi/core/serializers.py b/planetstack/core/serializers.py
similarity index 97%
rename from plstackapi/core/serializers.py
rename to planetstack/core/serializers.py
index b6d430a..7c5dca9 100644
--- a/plstackapi/core/serializers.py
+++ b/planetstack/core/serializers.py
@@ -1,6 +1,6 @@
 from django.forms import widgets
 from rest_framework import serializers
-from plstackapi.core.models import *
+from core.models import *
 
 
 class RoleSerializer(serializers.HyperlinkedModelSerializer):
@@ -20,9 +20,10 @@
     slice_memberships = serializers.HyperlinkedRelatedField(view_name='slice-membership-detail')
     site_privileges = serializers.HyperlinkedRelatedField(view_name='site-privilege-detail')
     class Meta:
-        model = PLUser
+        model = User
         fields = ('id',
                   'user_id', 
+                  'kuser_id', 
                   'firstname', 
                   'lastname',
                   'email', 
@@ -179,7 +180,7 @@
 
 serializerLookUp = { 
                  Role: RoleSerializer,
-                 PLUser: UserSerializer,
+                 User: UserSerializer,
                  Key: KeySerializer,
                  Site: SiteSerializer,
                  SitePrivilege: SitePrivilegeSerializer,
diff --git a/plstackapi/core/views/__init__.py b/planetstack/core/views/__init__.py
similarity index 100%
rename from plstackapi/core/views/__init__.py
rename to planetstack/core/views/__init__.py
diff --git a/plstackapi/core/views/deployment_networks.py b/planetstack/core/views/deployment_networks.py
similarity index 89%
rename from plstackapi/core/views/deployment_networks.py
rename to planetstack/core/views/deployment_networks.py
index 1508b0c..63220a4 100644
--- a/plstackapi/core/views/deployment_networks.py
+++ b/planetstack/core/views/deployment_networks.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.deployment_networks import add_deployment_network, delete_deployment_network, get_deployment_networks
-from plstackapi.core.serializers import DeploymentNetworkSerializer
-from plstackapi.util.request import parse_request
+from core.api.deployment_networks import add_deployment_network, delete_deployment_network, get_deployment_networks
+from core.serializers import DeploymentNetworkSerializer
+from util.request import parse_request
 
 
 class DeploymentNetworkListCreate(APIView):
diff --git a/plstackapi/core/views/images.py b/planetstack/core/views/images.py
similarity index 89%
rename from plstackapi/core/views/images.py
rename to planetstack/core/views/images.py
index 4a548ac..7e0ab59 100644
--- a/plstackapi/core/views/images.py
+++ b/planetstack/core/views/images.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.images import add_image, delete_image, get_images
-from plstackapi.core.serializers import ImageSerializer
-from plstackapi.util.request import parse_request
+from core.api.images import add_image, delete_image, get_images
+from core.serializers import ImageSerializer
+from util.request import parse_request
 
 
 class ImageListCreate(APIView):
diff --git a/plstackapi/core/views/keys.py b/planetstack/core/views/keys.py
similarity index 91%
rename from plstackapi/core/views/keys.py
rename to planetstack/core/views/keys.py
index 80a378d..a5d0995 100644
--- a/plstackapi/core/views/keys.py
+++ b/planetstack/core/views/keys.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.keys import add_key, delete_key, get_keys, update_key
-from plstackapi.core.serializers import KeySerializer
-from plstackapi.util.request import parse_request
+from core.api.keys import add_key, delete_key, get_keys, update_key
+from core.serializers import KeySerializer
+from util.request import parse_request
 
 
 class KeyListCreate(APIView):
diff --git a/plstackapi/core/views/nodes.py b/planetstack/core/views/nodes.py
similarity index 89%
rename from plstackapi/core/views/nodes.py
rename to planetstack/core/views/nodes.py
index baa9f17..0f1977e 100644
--- a/plstackapi/core/views/nodes.py
+++ b/planetstack/core/views/nodes.py
@@ -3,9 +3,9 @@
 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
+from core.api.nodes import add_node, delete_node, get_nodes, update_node
+from core.serializers import NodeSerializer
+from util.request import parse_request
 
 
 class NodeListCreate(APIView):
diff --git a/plstackapi/core/views/roles.py b/planetstack/core/views/roles.py
similarity index 91%
rename from plstackapi/core/views/roles.py
rename to planetstack/core/views/roles.py
index b8c279c..37bb149 100644
--- a/plstackapi/core/views/roles.py
+++ b/planetstack/core/views/roles.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.roles import add_role, delete_role, get_roles
-from plstackapi.core.serializers import RoleSerializer
-from plstackapi.util.request import parse_request
+from core.api.roles import add_role, delete_role, get_roles
+from core.serializers import RoleSerializer
+from util.request import parse_request
 
 
 class RoleListCreate(APIView):
diff --git a/plstackapi/core/views/site_privileges.py b/planetstack/core/views/site_privileges.py
similarity index 90%
rename from plstackapi/core/views/site_privileges.py
rename to planetstack/core/views/site_privileges.py
index b104fa7..37fc371 100644
--- a/plstackapi/core/views/site_privileges.py
+++ b/planetstack/core/views/site_privileges.py
@@ -3,9 +3,9 @@
 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
+from core.api.site_privileges import add_site_privilege, delete_site_privilege, get_site_privileges, update_site_privilege
+from core.serializers import SitePrivilegeSerializer
+from util.request import parse_request
 
 
 class SitePrivilegeListCreate(APIView):
diff --git a/plstackapi/core/views/sites.py b/planetstack/core/views/sites.py
similarity index 92%
rename from plstackapi/core/views/sites.py
rename to planetstack/core/views/sites.py
index 700547c..6449b67 100644
--- a/plstackapi/core/views/sites.py
+++ b/planetstack/core/views/sites.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.sites import add_site, delete_site, get_sites
-from plstackapi.core.serializers import SiteSerializer
-from plstackapi.util.request import parse_request
+from core.api.sites import add_site, delete_site, get_sites
+from core.serializers import SiteSerializer
+from util.request import parse_request
 
 
 class SiteListCreate(APIView):
diff --git a/plstackapi/core/views/slice_memberships.py b/planetstack/core/views/slice_memberships.py
similarity index 90%
rename from plstackapi/core/views/slice_memberships.py
rename to planetstack/core/views/slice_memberships.py
index a4f6848..4bb581c 100644
--- a/plstackapi/core/views/slice_memberships.py
+++ b/planetstack/core/views/slice_memberships.py
@@ -3,9 +3,9 @@
 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
+from core.api.slice_memberships import add_slice_membership, delete_slice_membership, get_slice_memberships, update_slice_membership
+from core.serializers import SliceMembershipSerializer
+from util.request import parse_request
 
 
 class SliceMembershipListCreate(APIView):
diff --git a/plstackapi/core/views/slices.py b/planetstack/core/views/slices.py
similarity index 91%
rename from plstackapi/core/views/slices.py
rename to planetstack/core/views/slices.py
index 10bc42c..5954d0c 100644
--- a/plstackapi/core/views/slices.py
+++ b/planetstack/core/views/slices.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.slices import add_slice, delete_slice, get_slices, update_slice
-from plstackapi.core.serializers import SliceSerializer
-from plstackapi.util.request import parse_request
+from core.api.slices import add_slice, delete_slice, get_slices, update_slice
+from core.serializers import SliceSerializer
+from util.request import parse_request
 
 
 class SliceListCreate(APIView):
diff --git a/plstackapi/core/views/slivers.py b/planetstack/core/views/slivers.py
similarity index 91%
rename from plstackapi/core/views/slivers.py
rename to planetstack/core/views/slivers.py
index 2f5842c..3741cce 100644
--- a/plstackapi/core/views/slivers.py
+++ b/planetstack/core/views/slivers.py
@@ -3,9 +3,9 @@
 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
+from core.api.slivers import add_sliver, delete_sliver, get_slivers, update_sliver
+from core.serializers import SliverSerializer
+from util.request import parse_request
 
 
 class SliverListCreate(APIView):
diff --git a/planetstack/core/views/subnets.py b/planetstack/core/views/subnets.py
new file mode 100644
index 0000000..881f615
--- /dev/null
+++ b/planetstack/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 core.api.subnets import add_subnet, delete_subnet, get_subnets, update_subnet
+from core.serializers import SubnetSerializer
+from 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/core/views/users.py b/planetstack/core/views/users.py
similarity index 91%
rename from plstackapi/core/views/users.py
rename to planetstack/core/views/users.py
index 0ec867f..8b27928 100644
--- a/plstackapi/core/views/users.py
+++ b/planetstack/core/views/users.py
@@ -3,9 +3,9 @@
 from rest_framework.response import Response
 from rest_framework import status
 
-from plstackapi.core.api.users import add_user, delete_user, get_users, update_user
-from plstackapi.core.serializers import UserSerializer
-from plstackapi.util.request import parse_request
+from core.api.users import add_user, delete_user, get_users, update_user
+from core.serializers import UserSerializer
+from util.request import parse_request
 
 
 class UserListCreate(APIView):
diff --git a/plstackapi/importer/__init__.py b/planetstack/importer/__init__.py
similarity index 100%
rename from plstackapi/importer/__init__.py
rename to planetstack/importer/__init__.py
diff --git a/plstackapi/importer/plclassic/__init__.py b/planetstack/importer/plclassic/__init__.py
similarity index 100%
rename from plstackapi/importer/plclassic/__init__.py
rename to planetstack/importer/plclassic/__init__.py
diff --git a/plstackapi/importer/plclassic/importer.py b/planetstack/importer/plclassic/importer.py
similarity index 82%
rename from plstackapi/importer/plclassic/importer.py
rename to planetstack/importer/plclassic/importer.py
index b113787..3a65dc3 100644
--- a/plstackapi/importer/plclassic/importer.py
+++ b/planetstack/importer/plclassic/importer.py
@@ -1,13 +1,13 @@
 import os
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
+#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
 import sys
 from optparse import OptionParser
 from getpass import getpass
 import xmlrpclib
-from plstackapi.importer.plclassic.site_importer import SiteImporter
-from plstackapi.importer.plclassic.user_importer import UserImporter
-from plstackapi.importer.plclassic.slice_importer import SliceImporter
-from plstackapi.importer.plclassic.sliver_importer import SliverImporter
+from plclassic.site_importer import SiteImporter
+from plclassic.user_importer import UserImporter
+from plclassic.slice_importer import SliceImporter
+from plclassic.sliver_importer import SliverImporter
 
 
 class Call:
diff --git a/plstackapi/importer/plclassic/role_importer.py b/planetstack/importer/plclassic/role_importer.py
similarity index 100%
rename from plstackapi/importer/plclassic/role_importer.py
rename to planetstack/importer/plclassic/role_importer.py
diff --git a/plstackapi/importer/plclassic/site_importer.py b/planetstack/importer/plclassic/site_importer.py
similarity index 96%
rename from plstackapi/importer/plclassic/site_importer.py
rename to planetstack/importer/plclassic/site_importer.py
index ca89bf5..2ee8157 100644
--- a/plstackapi/importer/plclassic/site_importer.py
+++ b/planetstack/importer/plclassic/site_importer.py
@@ -1,4 +1,4 @@
-from plstackapi.core.models import Site
+from core.models import Site
 
 class SiteImporter:
 
diff --git a/plstackapi/importer/plclassic/slice_importer.py b/planetstack/importer/plclassic/slice_importer.py
similarity index 93%
rename from plstackapi/importer/plclassic/slice_importer.py
rename to planetstack/importer/plclassic/slice_importer.py
index 4717b3d..b2dd84f 100644
--- a/plstackapi/importer/plclassic/slice_importer.py
+++ b/planetstack/importer/plclassic/slice_importer.py
@@ -1,4 +1,4 @@
-from plstackapi.core.models import Slice
+from core.models import Slice
 
 class SliceImporter:
 
@@ -15,7 +15,7 @@
         
 
         if not local_sites:
-            from plstackapi.core.models import Site
+            from core.models import Site
             sites = Site.objects.all()
             for site in sites:
                 local_sites[site.login_base] = site            
diff --git a/plstackapi/importer/plclassic/sliver_importer.py b/planetstack/importer/plclassic/sliver_importer.py
similarity index 100%
rename from plstackapi/importer/plclassic/sliver_importer.py
rename to planetstack/importer/plclassic/sliver_importer.py
diff --git a/plstackapi/importer/plclassic/user_importer.py b/planetstack/importer/plclassic/user_importer.py
similarity index 100%
rename from plstackapi/importer/plclassic/user_importer.py
rename to planetstack/importer/plclassic/user_importer.py
diff --git a/plstackapi/manage.py b/planetstack/manage.py
similarity index 67%
rename from plstackapi/manage.py
rename to planetstack/manage.py
index ea36bda..c12bf36 100644
--- a/plstackapi/manage.py
+++ b/planetstack/manage.py
@@ -3,7 +3,7 @@
 import sys
 
 if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
 
     from django.core.management import execute_from_command_line
 
diff --git a/plstackapi/openstack/__init__.py b/planetstack/openstack/__init__.py
similarity index 100%
rename from plstackapi/openstack/__init__.py
rename to planetstack/openstack/__init__.py
diff --git a/planetstack/openstack/client.py b/planetstack/openstack/client.py
new file mode 100644
index 0000000..f3abbb2
--- /dev/null
+++ b/planetstack/openstack/client.py
@@ -0,0 +1,148 @@
+try:
+    from keystoneclient.v2_0 import client as keystone_client
+    from glance import client as glance_client
+    from novaclient.v1_1 import client as nova_client
+    from quantumclient.v2_0 import client as quantum_client
+    has_openstack = True
+except:
+    has_openstack = False
+
+from planetstack.config import Config
+
+def require_enabled(callable):
+    def wrapper(*args, **kwds):
+        if has_openstack:
+            return callable(*args, **kwds)
+        else:
+            return None
+    return wrapper
+
+def parse_novarc(filename):
+    opts = {}
+    f = open(filename, 'r')
+    for line in f:
+        try:
+            line = line.replace('export', '').strip()
+            parts = line.split('=')
+            if len(parts) > 1:
+                value = parts[1].replace("\'", "")
+                value = value.replace('\"', '')
+                opts[parts[0]] = value
+        except:
+            pass
+    f.close()
+    return opts
+
+class Client:
+    def __init__(self, username=None, password=None, tenant=None, url=None, config=None, *args, **kwds):
+        if config:
+            config = Config(config)
+        else:
+            config = Config()
+        self.has_openstack = has_openstack
+        self.username = config.nova_admin_user
+        self.password = config.nova_admin_password
+        self.tenant = config.nova_admin_tenant
+        self.url = config.nova_url
+
+        if username:
+            self.username = username
+        if password:
+            self.password = password
+        if tenant:
+            self.tenant = tenant
+        if url:
+            self.url = url
+
+        if '@' in self.username:
+            self.username = self.username[:self.username.index('@')]
+
+class KeystoneClient(Client):
+    def __init__(self, *args, **kwds):
+        Client.__init__(self, *args, **kwds)
+        if has_openstack:
+            self.client = keystone_client.Client(username=self.username,
+                                                 password=self.password,
+                                                 tenant_name=self.tenant,
+                                                 auth_url=self.url)
+
+    @require_enabled
+    def connect(self, *args, **kwds):
+        self.__init__(*args, **kwds)
+
+    @require_enabled
+    def __getattr__(self, name):
+        return getattr(self.client, name)
+
+
+class GlanceClient(Client):
+    def __init__(self, *args, **kwds):
+        Client.__init__(self, *args, **kwds)
+        if has_openstack:
+            self.client = glance_client.get_client(host='0.0.0.0',
+                                                   username=self.username,
+                                                   password=self.password,
+                                                   tenant=self.tenant,
+                                                   auth_url=self.url)
+    @require_enabled
+    def __getattr__(self, name):
+        return getattr(self.client, name)
+
+class NovaClient(Client):
+    def __init__(self, *args, **kwds):
+        Client.__init__(self, *args, **kwds)
+        if has_openstack:
+            self.client = nova_client.Client(username=self.username,
+                                             api_key=self.password,
+                                             project_id=self.tenant,
+                                             auth_url=self.url,
+                                             region_name='',
+                                             extensions=[],
+                                             service_type='compute',
+                                             service_name='',
+                                             )
+
+    @require_enabled
+    def connect(self, *args, **kwds):
+        self.__init__(*args, **kwds)
+
+    @require_enabled
+    def __getattr__(self, name):
+        return getattr(self.client, name)
+
+class QuantumClient(Client):
+    def __init__(self, *args, **kwds):
+        Client.__init__(self, *args, **kwds)
+        if has_openstack:
+            self.client = quantum_client.Client(username=self.username,
+                                                password=self.password,
+                                                tenant_name=self.tenant,
+                                                auth_url=self.url)
+    @require_enabled
+    def connect(self, *args, **kwds):
+        self.__init__(*args, **kwds)
+
+    @require_enabled
+    def __getattr__(self, name):
+        return getattr(self.client, name)
+
+class OpenStackClient:
+    """
+    A simple native shell to the openstack backend services.
+    This class can receive all nova calls to the underlying testbed
+    """
+
+    def __init__ ( self, *args, **kwds) :
+        # instantiate managers
+        self.keystone = KeystoneClient(*args, **kwds)
+        self.glance = GlanceClient(*args, **kwds)
+        self.nova = NovaClient(*args, **kwds)
+        self.quantum = QuantumClient(*args, **kwds)
+
+    @require_enabled
+    def connect(self, *args, **kwds):
+        self.__init__(*args, **kwds)
+
+    @require_enabled
+    def authenticate(self):
+        return self.keystone.authenticate()
diff --git a/plstackapi/openstack/driver.py b/planetstack/openstack/driver.py
similarity index 95%
rename from plstackapi/openstack/driver.py
rename to planetstack/openstack/driver.py
index 2b0b8e2..eba424a 100644
--- a/plstackapi/openstack/driver.py
+++ b/planetstack/openstack/driver.py
@@ -1,7 +1,8 @@
 import commands
-from plstackapi.planetstack.config import Config
-from plstackapi.openstack.client import OpenStackClient
+from planetstack.config import Config
+from openstack.client import OpenStackClient
 
+has_openstack = False
 class OpenStackDriver:
 
     def __init__(self, config = None, client=None): 
@@ -11,7 +12,10 @@
             self.config = Config() 
 
         self.admin_client = OpenStackClient()
-        self.admin_user = self.admin_client.keystone.users.find(name=self.admin_client.keystone.username)
+        if has_openstack:
+            self.admin_user = self.admin_client.keystone.users.find(name=self.admin_client.keystone.username)
+        else:
+            self.admin_user = None
 
         if client:
             self.shell = client
@@ -72,8 +76,8 @@
             self.shell.keystone.users.delete(user)
         return 1 
 
-    def add_user_role(self, user_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=user_id)
+    def add_user_role(self, kuser_id, tenant_id, role_name):
+        user = self.shell.keystone.users.find(id=kuser_id)
         tenant = self.shell.keystone.tenants.find(id=tenant_id)
         role = self.shell.keystone.roles.find(name=role_name)
 
@@ -87,8 +91,8 @@
 
         return 1
 
-    def delete_user_role(self, user_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=user_id)
+    def delete_user_role(self, kuser_id, tenant_id, role_name):
+        user = self.shell.keystone.users.find(id=kuser_id)
         tenant = self.shell.keystone.tenants.find(id=tenant_id)
         role = self.shell.keystone.roles.find(name=role_name)
 
diff --git a/plstackapi/openstack/manager.py b/planetstack/openstack/manager.py
similarity index 91%
rename from plstackapi/openstack/manager.py
rename to planetstack/openstack/manager.py
index 669a05f..166ad19 100644
--- a/plstackapi/openstack/manager.py
+++ b/planetstack/openstack/manager.py
@@ -1,17 +1,17 @@
 from netaddr import IPAddress, IPNetwork
-from plstackapi.planetstack import settings
+from planetstack import settings
 from django.core import management
-management.setup_environ(settings)
-from plstackapi.planetstack.config import Config
+from planetstack.config import Config
 try:
-    from plstackapi.openstack.client import OpenStackClient
-    from plstackapi.openstack.driver import OpenStackDriver
-    from plstackapi.core.models import * 
+    from openstack.client import OpenStackClient
+    from openstack.driver import OpenStackDriver
+    from core.models import * 
     has_openstack = True
 except:
     has_openstack = False
 
-manager_enabled = Config().api_nova_enabled
+#manager_enabled = Config().api_nova_enabled
+manager_enabled = False
 
 def require_enabled(callable):
     def wrapper(*args, **kwds):
@@ -57,7 +57,7 @@
         self.client = OpenStackClient()
         self.driver = OpenStackDriver(client=self.client)
         self.caller = self.driver.admin_user
-        self.caller.user_id = self.caller.id 
+        self.caller.kuser_id = self.caller.id 
 
     @require_enabled
     def save_role(self, role):
@@ -85,26 +85,26 @@
 
     @require_enabled
     def save_user(self, user):
-        if not user.user_id:
+        if not user.kuser_id:
             name = user.email[:user.email.find('@')]
             user_fields = {'name': name,
                            'email': user.email,
                            'password': user.password,
                            'enabled': True}
             keystone_user = self.driver.create_user(**user_fields)
-            user.user_id = keystone_user.id
+            user.kuser_id = keystone_user.id
         if user.site:
-            self.driver.add_user_role(user.user_id, user.site.tenant_id, 'user')
+            self.driver.add_user_role(user.kuser_id, user.site.tenant_id, 'user')
             if user.is_admin:
-                self.driver.add_user_role(user.user_id, user.site.tenant_id, 'admin')
+                self.driver.add_user_role(user.kuser_id, user.site.tenant_id, 'admin')
             else:
                 # may have admin role so attempt to remove it
-                self.driver.delete_user_role(user.user_id, user.site.tenant_id, 'admin')
+                self.driver.delete_user_role(user.kuser_id, user.site.tenant_id, 'admin')
   
     @require_enabled
     def delete_user(self, user):
-        if user.user_id:
-            self.driver.delete_user(user.user_id)        
+        if user.kuser_id:
+            self.driver.delete_user(user.kuser_id)        
     
     @require_enabled
     def save_site(self, site, add_role=True):
@@ -114,7 +114,7 @@
                                                enabled=site.enabled)
             site.tenant_id = tenant.id
             # give caller an admin role at the tenant they've created
-            self.driver.add_user_role(self.caller.user_id, tenant.id, 'admin')
+            self.driver.add_user_role(self.caller.kuser_id, tenant.id, 'admin')
 
         # update the record
         if site.id and site.tenant_id:
@@ -137,7 +137,7 @@
             slice.tenant_id = tenant.id
 
             # give caller an admin role at the tenant they've created
-            self.driver.add_user_role(self.caller.user_id, tenant.id, 'admin')
+            self.driver.add_user_role(self.caller.kuser_id, tenant.id, 'admin')
 
             # refresh credentials using this tenant
             self.driver.shell.connect(username=self.driver.shell.keystone.username,
diff --git a/plstackapi/openstack/siteagent.py b/planetstack/openstack/siteagent.py
similarity index 76%
rename from plstackapi/openstack/siteagent.py
rename to planetstack/openstack/siteagent.py
index dab9e8a..a57fa0b 100644
--- a/plstackapi/openstack/siteagent.py
+++ b/planetstack/openstack/siteagent.py
@@ -1,9 +1,9 @@
 import os
 import sys
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
+#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
 import time
-from plstackapi.core.models.site import Site
-from plstackapi.openstack.manager import OpenStackManager    
+from core.models.site import Site
+from openstack.manager import OpenStackManager    
 
 class SiteAgent:
     def run(self):
diff --git a/plstackapi/openstack/sliveragent.py b/planetstack/openstack/sliveragent.py
similarity index 86%
rename from plstackapi/openstack/sliveragent.py
rename to planetstack/openstack/sliveragent.py
index f07f603..b2f29cf 100644
--- a/plstackapi/openstack/sliveragent.py
+++ b/planetstack/openstack/sliveragent.py
@@ -1,9 +1,9 @@
 import os
 import sys
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
+#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
 import time
-from plstackapi.core.models.sliver import Sliver
-from plstackapi.openstack.manager import OpenStackManager
+from core.models.sliver import Sliver
+from openstack.manager import OpenStackManager
 
 class SliverAgent:
 
diff --git a/plstackapi/planetstack/__init__.py b/planetstack/planetstack/__init__.py
similarity index 100%
copy from plstackapi/planetstack/__init__.py
copy to planetstack/planetstack/__init__.py
diff --git a/plstackapi/planetstack/config.py b/planetstack/planetstack/config.py
similarity index 98%
rename from plstackapi/planetstack/config.py
rename to planetstack/planetstack/config.py
index 2f98e6f..7927803 100644
--- a/plstackapi/planetstack/config.py
+++ b/planetstack/planetstack/config.py
@@ -6,7 +6,7 @@
 import tempfile
 import codecs
 from StringIO import StringIO
-from plstackapi.util.xml import Xml
+from util.xml import Xml
 
 default_config = \
 """
@@ -20,7 +20,7 @@
 
 class Config:
 
-    def __init__(self, config_file='/etc/planetstack/plstackapi_config'):
+    def __init__(self, config_file='/opt/planetstack/plstackapi_config'):
         self._files = []
         self.config_path = os.path.dirname(config_file)
         self.config = ConfigParser.ConfigParser()
diff --git a/plstackapi/planetstack/settings.py b/planetstack/planetstack/settings.py
similarity index 89%
rename from plstackapi/planetstack/settings.py
rename to planetstack/planetstack/settings.py
index 40e839a..8970c42 100644
--- a/plstackapi/planetstack/settings.py
+++ b/planetstack/planetstack/settings.py
@@ -9,22 +9,20 @@
 
 MANAGERS = ADMINS
 
-AUTH_USER_MODEL = 'core.PLUser'
-
-from plstackapi.planetstack.config import Config
-config = Config()
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': config.db_name,                      # Or path to database file if using sqlite3.
+        'NAME': 'planetstack',                      # Or path to database file if using sqlite3.
         # The following settings are not used with sqlite3:
-        'USER': config.db_user,
-        'PASSWORD': config.db_password,
-        'HOST': config.db_host,                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
+        'USER': 'postgres',
+        'PASSWORD': 'admin',
+        'HOST': 'localhost',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
         'PORT': '',                      # Set to empty string for default.
     }
 }
 
+AUTH_USER_MODEL = 'core.User'
+
 # Hosts/domain names that are valid for this site; required if DEBUG is False
 # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
 ALLOWED_HOSTS = []
@@ -106,15 +104,16 @@
     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 )
 
-ROOT_URLCONF = 'plstackapi.core.urls'
+ROOT_URLCONF = 'planetstack.urls'
 
 # Python dotted path to the WSGI application used by Django's runserver.
-WSGI_APPLICATION = 'plstackapi.planetstack.wsgi.application'
+WSGI_APPLICATION = 'planetstack.wsgi.application'
 
 TEMPLATE_DIRS = (
     # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
     # Always use forward slashes, even on Windows.
     # Don't forget to use absolute paths, not relative paths.
+    "/opt/planetstack/templates"
 )
 
 INSTALLED_APPS = (
@@ -130,9 +129,8 @@
     'django.contrib.admindocs',
     'rest_framework',
     'django_extensions',
+    'core',
     'django_evolution',
-    #'plstackapi.planetstack',
-    'plstackapi.core',
 )
 
 # A sample logging configuration. The only tangible logging
diff --git a/plstackapi/planetstack/tests.py b/planetstack/planetstack/tests.py
similarity index 100%
rename from plstackapi/planetstack/tests.py
rename to planetstack/planetstack/tests.py
diff --git a/plstackapi/core/urls.py b/planetstack/planetstack/urls.py
similarity index 73%
rename from plstackapi/core/urls.py
rename to planetstack/planetstack/urls.py
index d469881..dbe9f49 100644
--- a/plstackapi/core/urls.py
+++ b/planetstack/planetstack/urls.py
@@ -2,19 +2,19 @@
 
 # Uncomment the next two lines to enable the admin:
 from django.contrib import admin
-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.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.nodes import NodeListCreate, NodeRetrieveUpdateDestroy
-from plstackapi.core.models import Site
-from plstackapi.core.api_root import api_root
+from core.views.roles import RoleListCreate, RoleRetrieveUpdateDestroy
+from core.views.sites import SiteListCreate, SiteRetrieveUpdateDestroy
+from core.views.site_privileges import SitePrivilegeListCreate, SitePrivilegeRetrieveUpdateDestroy
+from core.views.users import UserListCreate, UserRetrieveUpdateDestroy
+from core.views.slices import SliceListCreate, SliceRetrieveUpdateDestroy
+from core.views.slice_memberships import SliceMembershipListCreate, SliceMembershipRetrieveUpdateDestroy
+from core.views.slivers import SliverListCreate, SliverRetrieveUpdateDestroy
+from core.views.keys import KeyListCreate, KeyRetrieveUpdateDestroy
+from core.views.deployment_networks import DeploymentNetworkListCreate, DeploymentNetworkRetrieveUpdateDestroy
+from core.views.images import ImageListCreate, ImageRetrieveUpdateDestroy
+from core.views.nodes import NodeListCreate, NodeRetrieveUpdateDestroy
+from core.models import Site
+from core.api_root import api_root
 from rest_framework import generics
 
 admin.autodiscover()
diff --git a/plstackapi/planetstack/wsgi.py b/planetstack/planetstack/wsgi.py
similarity index 93%
rename from plstackapi/planetstack/wsgi.py
rename to planetstack/planetstack/wsgi.py
index 11c4ce5..6e03e11 100644
--- a/plstackapi/planetstack/wsgi.py
+++ b/planetstack/planetstack/wsgi.py
@@ -19,7 +19,7 @@
 # if running multiple sites in the same mod_wsgi process. To fix this, use
 # mod_wsgi daemon mode with each site in its own daemon process, or use
 # os.environ["DJANGO_SETTINGS_MODULE"] = "planetstack.settings"
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
 
 # This application object is used by any WSGI server configured to use this
 # file. This includes Django's development server, if the WSGI_APPLICATION
diff --git a/plstackapi/plstackapi-debug-server.py b/planetstack/plstackapi-debug-server.py
similarity index 71%
rename from plstackapi/plstackapi-debug-server.py
rename to planetstack/plstackapi-debug-server.py
index 56542bf..aa60119 100644
--- a/plstackapi/plstackapi-debug-server.py
+++ b/planetstack/plstackapi-debug-server.py
@@ -3,14 +3,13 @@
 import sys
 import threading
 
-from plstackapi.planetstack.config import Config 
-from plstackapi.openstack.sliveragent import SliverAgent
-from plstackapi.openstack.siteagent import SiteAgent
+from planetstack.config import Config 
+from openstack.sliveragent import SliverAgent
+from openstack.siteagent import SiteAgent
 
 if __name__ == '__main__':
 
     # bootstrap envirnment
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "plstackapi.planetstack.settings")
     from django.core.management import ManagementUtility
     config = Config()
     url = "%s:%s" % (config.api_host, config.api_port)
diff --git a/config/plstackapi_config b/planetstack/plstackapi_config
similarity index 100%
rename from config/plstackapi_config
rename to planetstack/plstackapi_config
diff --git a/planetstack/templates/admin/base_site.html b/planetstack/templates/admin/base_site.html
new file mode 100644
index 0000000..2bd6c82
--- /dev/null
+++ b/planetstack/templates/admin/base_site.html
@@ -0,0 +1,18 @@
+{% extends "admin/base.html" %}
+{% load i18n %}
+{% block title %}{{ title }} | {% trans 'PlanetStack' %}{% endblock %}
+{% block extrastyle %}
+<style>
+#header{ background-color: #333940; border-bottom: solid 3px #999; }
+ 
+#branding h1{ color: #fff; }
+.module h2, .module caption, .inline-group h2 { background:#ccc url(/admin_media/img/admin/nav-bg.gif) bottom left repeat-x; color: #333940; }
+a.section:link, a.section:visited { color: #666666; }
+</style>
+{% endblock %}
+
+{% block branding %}
+<h1 id="site-name">{% trans 'PlanetStack Administration' %}</h1>
+{% endblock %}
+
+{% block nav-global %}{% endblock %}
diff --git a/planetstack/templates/admin/core/SiteDeploymentNetwork/sitedepnettabular.html b/planetstack/templates/admin/core/SiteDeploymentNetwork/sitedepnettabular.html
new file mode 100644
index 0000000..71a62ba
--- /dev/null
+++ b/planetstack/templates/admin/core/SiteDeploymentNetwork/sitedepnettabular.html
@@ -0,0 +1,79 @@
+{% load i18n admin_static admin_modify %}
+<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
+  <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
+{{ inline_admin_formset.formset.management_form }}
+<fieldset class="module">
+   <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
+   {{ inline_admin_formset.formset.non_form_errors }}
+   <table>
+     <thead><tr>
+     {% for field in inline_admin_formset.fields %}
+       {% if not field.widget.is_hidden %}
+         <th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
+         {% if field.help_text %}&nbsp;<img src="{% static "admin/img/icon-unknown.gif" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
+         </th>
+       {% endif %}
+     {% endfor %}
+     {% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
+     </tr></thead>
+
+     <tbody>
+     {% for inline_admin_form in inline_admin_formset %}
+        {% if inline_admin_form.form.non_field_errors %}
+        <tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
+        {% endif %}
+        <tr class="form-row {% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"
+             id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
+        <td class="original">
+          {% if inline_admin_form.original or inline_admin_form.show_url %}<p>
+          {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
+          {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
+            </p>{% endif %}
+          {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
+          {{ inline_admin_form.fk_field.field }}
+          {% spaceless %}
+          {% for fieldset in inline_admin_form %}
+            {% for line in fieldset %}
+              {% for field in line %}
+                {% if field.is_hidden %} {{ field.field }} {% endif %}
+              {% endfor %}
+            {% endfor %}
+          {% endfor %}
+          {% endspaceless %}
+        </td>
+        {% for fieldset in inline_admin_form %}
+          {% for line in fieldset %}
+            {% for field in line %}
+              <td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
+              {% if field.is_readonly %}
+                  <p>{{ field.contents|linebreaksbr }}</p>
+              {% else %}
+                  {{ field.field.errors.as_ul }}
+                  {{ field.field }}
+              {% endif %}
+              </td>
+            {% endfor %}
+          {% endfor %}
+        {% endfor %}
+        {% if inline_admin_formset.formset.can_delete %}
+          <td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
+        {% endif %}
+        </tr>
+     {% endfor %}
+     </tbody>
+   </table>
+</fieldset>
+  </div>
+</div>
+
+<script type="text/javascript">
+
+(function($) {
+  $("#{{ inline_admin_formset.formset.prefix }}-group .tabular.inline-related tbody tr").tabularFormset({
+    prefix: "{{ inline_admin_formset.formset.prefix }}",
+    adminStaticPrefix: '{% static "admin/" %}',
+    addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
+    deleteText: "{% trans 'Remove' %}"
+  });
+})(django.jQuery);
+</script>
diff --git a/plstackapi/util/__init__.py b/planetstack/util/__init__.py
similarity index 100%
rename from plstackapi/util/__init__.py
rename to planetstack/util/__init__.py
diff --git a/plstackapi/util/glob.py b/planetstack/util/glob.py
similarity index 100%
rename from plstackapi/util/glob.py
rename to planetstack/util/glob.py
diff --git a/plstackapi/util/request.py b/planetstack/util/request.py
similarity index 100%
rename from plstackapi/util/request.py
rename to planetstack/util/request.py
diff --git a/plstackapi/util/xml.py b/planetstack/util/xml.py
similarity index 100%
rename from plstackapi/util/xml.py
rename to planetstack/util/xml.py
diff --git a/plstackapi/__init__.py b/plstackapi/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/plstackapi/__init__.py
+++ /dev/null
diff --git a/plstackapi/core/models/__init__.py b/plstackapi/core/models/__init__.py
deleted file mode 100644
index d16444f..0000000
--- a/plstackapi/core/models/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from plstackapi.core.models.plcorebase import PlCoreBase
-from plstackapi.core.models.deploymentnetwork import DeploymentNetwork
-from plstackapi.core.models.site import Site
-from plstackapi.core.models.site import SitePrivilege
-from plstackapi.core.models.image import Image
-from plstackapi.core.models.pluser import PLUser
-from plstackapi.core.models.role import Role
-from plstackapi.core.models.key import Key
-from plstackapi.core.models.node import Node
-from plstackapi.core.models.slice import Slice
-from plstackapi.core.models.slice import SliceMembership
-from plstackapi.core.models.sliver import Sliver
-
diff --git a/plstackapi/core/models/key.py b/plstackapi/core/models/key.py
deleted file mode 100644
index 661b901..0000000
--- a/plstackapi/core/models/key.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import os
-from django.db import models
-from plstackapi.core.models import PlCoreBase
-from plstackapi.core.models import PLUser
-
-# Create your models here.
-
-class Key(PlCoreBase):
-    key_id = models.CharField(null=True, blank=True, 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(PLUser, related_name='keys')
-
-    def __unicode__(self):  return u'%s' % (self.user.email[:self.user.email.find('@')])
-
-    def save(self, *args, **kwds):
-        self.os_manager.save_key(self)
-        super(Key, self).save(*args, **kwds)
-
-    def delete(self, *args, **kwds):
-        self.os_manager.delete_key(self)
-        super(Key, self).delete(*args, **kwds) 
-    
diff --git a/plstackapi/core/models/role.py b/plstackapi/core/models/role.py
deleted file mode 100644
index 41bfd62..0000000
--- a/plstackapi/core/models/role.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import os
-import datetime
-from django.db import models
-from plstackapi.core.models import PlCoreBase
-
-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)
-
-    def __unicode__(self):  return u'%s' % (self.role_type)
-
-
-    def save(self, *args, **kwds):
-        self.os_manager.save_role(self)
-        super(Role, self).save(*args, **kwds)
-    
-    def delete(self, *args, **kwds):
-        self.os_manager.delete_role(self)   
-        super(Role, self).delete(*args, **kwds)
-            
diff --git a/plstackapi/openstack/client.py b/plstackapi/openstack/client.py
deleted file mode 100644
index 04aef25..0000000
--- a/plstackapi/openstack/client.py
+++ /dev/null
@@ -1,123 +0,0 @@
-from keystoneclient.v2_0 import client as keystone_client
-from glance import client as glance_client
-from novaclient.v1_1 import client as nova_client
-from quantumclient.v2_0 import client as quantum_client
-
-from plstackapi.planetstack.config import Config
-
-def parse_novarc(filename):
-    opts = {}
-    f = open(filename, 'r')
-    for line in f:
-        try:
-            line = line.replace('export', '').strip()
-            parts = line.split('=')
-            if len(parts) > 1:
-                value = parts[1].replace("\'", "")
-                value = value.replace('\"', '')
-                opts[parts[0]] = value
-        except:
-            pass
-    f.close()
-    return opts
-
-class Client:
-    def __init__(self, username=None, password=None, tenant=None, url=None, config=None, *args, **kwds):
-        if config:
-            config = Config(config)
-        else:
-            config = Config()
-        self.username = config.nova_admin_user
-        self.password = config.nova_admin_password
-        self.tenant = config.nova_admin_tenant
-        self.url = config.nova_url
-
-        if username:
-            self.username = username
-        if password:
-            self.password = password
-        if tenant:
-            self.tenant = tenant
-        if url:
-            self.url = url
-
-        if '@' in self.username:
-            self.username = self.username[:self.username.index('@')]
-
-class KeystoneClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        self.client = keystone_client.Client(username=self.username,
-                                             password=self.password,
-                                             tenant_name=self.tenant,
-                                             auth_url=self.url)
-
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-
-class GlanceClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        self.client = glance_client.get_client(host='0.0.0.0',
-                                               username=self.username,
-                                               password=self.password,
-                                               tenant=self.tenant,
-                                               auth_url=self.url)
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class NovaClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        self.client = nova_client.Client(username=self.username,
-                                         api_key=self.password,
-                                         project_id=self.tenant,
-                                         auth_url=self.url,
-                                         region_name='',
-                                         extensions=[],
-                                         service_type='compute',
-                                         service_name='',
-                                         )
-
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class QuantumClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        self.client = quantum_client.Client(username=self.username,
-                                            password=self.password,
-                                            tenant_name=self.tenant,
-                                            auth_url=self.url)
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class OpenStackClient:
-    """
-    A simple native shell to the openstack backend services.
-    This class can receive all nova calls to the underlying testbed
-    """
-
-    def __init__ ( self, *args, **kwds) :
-        # instantiate managers
-        self.keystone = KeystoneClient(*args, **kwds)
-        self.glance = GlanceClient(*args, **kwds)
-        self.nova = NovaClient(*args, **kwds)
-        self.quantum = QuantumClient(*args, **kwds)
-
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-        
-
-    def authenticate(self):
-        return self.keystone.authenticate()