updated openstack driver
diff --git a/plstackapi/core/models.py b/plstackapi/core/models.py
index 30285c6..ec18626 100644
--- a/plstackapi/core/models.py
+++ b/plstackapi/core/models.py
@@ -1,5 +1,5 @@
 from django.db import models
-from plstackapi.openstack.shell import OpenStackShell
+from plstackapi.openstack.driver import OpenStackDriver
 
 # Create your models here.
 
@@ -25,30 +25,22 @@
     def __unicode__(self):  return u'%s' % (self.name)
 
     def save(self, *args, **kwargs):
-        os_shell = OpenStackShell()
-        tenant_fields = {'name': self.login_base,
-                         'enabled': self.enabled,
-                         'description': self.name}
-        
+        driver  = OpenStackDriver()
         if not self.id:
-            # check if keystone tenant record exists
-            tenants = os_shell.keystone.tenants.findall(name=self.login_base)
-            if not tenants:
-                tenant = os_shell.keystone.tenants.create(**tenant_fields)
-            else:
-                tenant = tenants[0]
+            tenant = driver.create_tenant(name=self.login_base, 
+                                          description=self.name, 
+                                          enabled=self.enabled)
             self.tenant_id = tenants.id
         else:
             # update record
-            os_shell.keystone.tenants.update(self.tenant_id, **tenant_fields)
+            self.driver.update_tenant(self.tenant_id, name=self.login_base,
+                                      description=self.name, enabled=self.enabled)
         super(Site, self).save(*args, **kwargs)
 
     def delete(self, *args, **kwds):
         # delete keystone tenant
-        os_shell = OpenStackShell()
-        tenant = os_shell.keystone.tenants.find(id=self.tenant_id)
-        os_shell.keystone.tenants.delete(tenant)
-
+        driver  = OpenStackDriver()
+        driver.delete_tenant(self.tenant_id)
         super(Site, self).delete(*args, **kwargs)
 
 class Slice(PlCoreBase):
@@ -65,29 +57,26 @@
 
     def save(self, *args, **kwds):
         # sync keystone tenant
-        os_shell = OpenStackShell()
+        driver  = OpenStackDriver()
+
         tenant_fields = {'name': self.name,
                          'enabled': self.enabled,
                          'description': self.description}
         if not self.id:
-            # check if keystone tenant record exists
-            tenants = os_shell.keystone.tenants.findall(name=self.name)
-            if not tenants:
-                tenant = os_shell.keystone.tenants.create(**tenant_fields)
-            else:
-                tenant = tenants[0]
+            tenant = driver.create_tenant(name=self.name,
+                                          description=self.description,
+                                          enabled=self.enabled)
             self.tenant_id = tenants.id
         else:
             # update record
-            os_shell.keystone.tenants.update(self.tenant_id, **tenant_fields)
-        super(Site, self).save(*args, **kwargs)
+            self.driver.update_tenant(self.tenant_id, name=self.name,
+                                      description=self.description, enabled=self.enabled)
+        super(Slice, self).save(*args, **kwargs)
 
     def delete(self, *args, **kwds):
         # delete keystone tenant
-        os_shell = OpenStackShell()
-        tenant = os_shell.keystone.tenants.find(id=self.tenant_id)
-        os_shell.keystone.tenants.delete(tenant)
-
+        driver  = OpenStackDriver()
+        driver.delete_tenant(self.tenant_id)
         super(Slice, self).delete(*args, **kwargs)
 
 class DeploymentNetwork(PlCoreBase):
@@ -108,13 +97,33 @@
 
 
 class Sliver(PlCoreBase):
-    tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id")
-    name = models.CharField(max_length=200, unique=True)
-    slice = models.ForeignKey(Slice)
+    tenant_id = models.CharField(help_text="Keystone tenant id")
+    instance_id = models.CharField()    
+    name = models.CharField()
+    flavor = models.CharField()
+    image = modesl.CharField()    
+    slice = models.ForeignKey(Slice, related_name='slice')
     siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork)
+    node = models.ForeignKey(Node, related_name='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,
+                                          image=self.image)
+        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)
+        
+
 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.")
diff --git a/plstackapi/openstack/driver.py b/plstackapi/openstack/driver.py
index 44a8cb3..1ff99cf 100644
--- a/plstackapi/openstack/driver.py
+++ b/plstackapi/openstack/driver.py
@@ -10,8 +10,29 @@
             self.config = Config() 
         self.shell = OpenStackShell()
 
+    def create_tenant(self, **kwds):
+       """Create keystone tenant. Suggested fields: name, description, enabled"""  
+        required_fields = ['name', 'enabled', 'description']
+        for field in required_fields:
+            if field not in **kwds:
+                raise Exception, "Must specify %s" % field
 
-    def spawn_instances(self, name, key_name, hostnames=[], flavor=None, image=None, security_group=None, pubkeys=[]):
+        tenants = self.shell.keystone.tenants.findall(name=kwds['name'])
+        if not tenants:
+            tenant = self.shell.keystone.tenants.create(**kwds)
+        else:
+            tenant = tenants[0]
+        return tenant
+
+    def update_tenant(self, id, **kwds):
+        return self.shell.keystone.tenants.update(self.id, **kwds)
+
+    def delete_tenant(self, id):
+        tenant = self.shell.keystone.tenants.find(id=id)
+        return self.shell.keystone.tenants.delete(tenant)
+         
+
+    def spawn_instance(self, name, key_name=None, hostname=None, flavor=None, image=None, security_group=None, pubkeys=[]):
         if not flavor:
             flavor = self.config.nova_default_flavor
         if not image:
@@ -22,25 +43,30 @@
         authorized_keys = "\n".join(pubkeys)
         files = {'/root/.ssh/authorized_keys': authorized_keys}
        
-        for hostname in hostnames:
-            flavor_id = self.shell.nova.flavors.find(name=flavor)
-            images = self.shell.glance.get_images(name=image)
-            if not images:
-                raise Exception, "Image not found: " + image  
-            image_id = images[0]['id']
-            hints = {'force_hosts': hostname}
-            server = self.shell.nova.servers.create(
-                                                name=name,
-                                                key_name = key_name,
-                                                flavor=flavor_id,
-                                                image=image_id,
-                                                security_group = security_group,
-                                                files=files,
-                                                scheduler_hints=hints)
+        flavor_id = self.shell.nova.flavors.find(name=flavor)
+        images = self.shell.glance.get_images(name=image)
+        if not images:
+            raise Exception, "Image not found: " + image  
+        image_id = images[0]['id']
+        hints = {}
+        if hostname:
+            hints['force_hosts']= hostname
+        server = self.shell.nova.servers.create(
+                                            name=name,
+                                            key_name = key_name,
+                                            flavor=flavor_id,
+                                            image=image_id,
+                                            security_group = security_group,
+                                            files=files,
+                                            scheduler_hints=hints)
+        return server
           
-    def destroy_instances(self, name, hostnames=[]):
-        servers = self.shell.nova.servers.list()
+    def destroy_instance(self, name, id=None):
+        args = {'name': name}
+        if id:
+            args['id'] = id
+        servers = self.shell.nova.servers.findall(**args)
         for server in servers:
-            hostname = server._info['OS-EXT-SRV-ATTR:host']
-            if name == server.name and hostname in hostnames:
-                self.shell.nova.servers.delete(server)
+            if name == server.name:
+                if not id or id = server.id:
+                    self.shell.nova.servers.delete(server)