Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index b9a2345..5e3e287 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -185,7 +185,8 @@
             if (not self.write_protect):
                 self.deleted = True
                 self.enacted=None
-                self.save(update_fields=['enacted','deleted'], silent=silent)
+                self.policed=None
+                self.save(update_fields=['enacted','deleted','policed'], silent=silent)
 
 
     def save(self, *args, **kwargs):
diff --git a/xos/core/models/slice.py b/xos/core/models/slice.py
index 4fc8489..0649d6f 100644
--- a/xos/core/models/slice.py
+++ b/xos/core/models/slice.py
@@ -99,6 +99,7 @@
             qs = Slice.objects.filter(id__in=slice_ids)
         return qs
 
+    """
     def delete(self, *args, **kwds):
         # delete networks associated with this slice
         from core.models.network import Network
@@ -112,6 +113,7 @@
         slice_privileges.delete() 
         # continue with normal delete
         super(Slice, self).delete(*args, **kwds) 
+    """
          
 
 class SliceRole(PlCoreBase):
diff --git a/xos/dependency_walker.py b/xos/dependency_walker.py
index 0b23136..ba9de11 100644
--- a/xos/dependency_walker.py
+++ b/xos/dependency_walker.py
@@ -71,9 +71,10 @@
 			except AttributeError:
 				if not missing_links.has_key(model+'.'+link):
 					print "Model %s missing link for dependency %s"%(model, link)
-                                        logger.log_exc("Model %s missing link for dependency %s"%(model, link))
+                                        logger.log_exc("WARNING: Model %s missing link for dependency %s."%(model, link))
 					missing_links[model+'.'+link]=True
 
+
 		if (peer):
 			try:
 				peer_objects = peer.all()
@@ -83,11 +84,13 @@
 				peer_objects = []
 
 			for o in peer_objects:
-				fn(o, object)
+				#if (isinstance(o,PlCoreBase)):
+				if (hasattr(o,'updated')):
+					fn(o, object)
 				# Uncomment the following line to enable recursion
 				# walk_inv_deps(fn, o)
 
-def p(x):
+def p(x,source):
 	print x,x.__class__.__name__
 	return
 
diff --git a/xos/model_policies/model_policy_Slice.py b/xos/model_policies/model_policy_Slice.py
index a9936bd..b610601 100644
--- a/xos/model_policies/model_policy_Slice.py
+++ b/xos/model_policies/model_policy_Slice.py
@@ -1,16 +1,33 @@
+def handle_delete(slice):
+    from core.models import Controller, ControllerSlice, SiteDeployment, Network, NetworkSlice,NetworkTemplate, Slice
+    from collections import defaultdict
+
+    public_nets = []
+    private_net = None
+    networks = Network.objects.filter(owner=slice)
+
+    for n in networks:
+        n.delete()	
+    
+    # Note that sliceprivileges and slicecontrollers are autodeleted, through the dependency graph
 
 def handle(slice):
     from core.models import Controller, ControllerSlice, SiteDeployment, Network, NetworkSlice,NetworkTemplate, Slice
     from collections import defaultdict
 
+    print "MODEL POLICY: slice", slice
+
     # slice = Slice.get(slice_id)
 
     controller_slices = ControllerSlice.objects.filter(slice=slice)
     existing_controllers = [cs.controller for cs in controller_slices] 
         
+    print "MODEL POLICY: slice existing_controllers=", existing_controllers
+
     all_controllers = Controller.objects.all() 
     for controller in all_controllers:
         if controller not in existing_controllers:
+            print "MODEL POLICY: slice adding controller", controller
             sd = ControllerSlice(slice=slice, controller=controller)
             sd.save()
 
diff --git a/xos/model_policy.py b/xos/model_policy.py
index 3fa7218..9333adc 100644
--- a/xos/model_policy.py
+++ b/xos/model_policy.py
@@ -11,62 +11,105 @@
 from django.db.models import F, Q
 
 modelPolicyEnabled = True
+bad_instances=[]
 
 def EnableModelPolicy(x):
     global modelPolicyEnabled
     modelPolicyEnabled = x
 
+def update_wp(d, o):
+    try:
+        save_fields = []
+        if (d.write_protect != o.write_protect):
+            d.write_protect = o.write_protect
+            save_fields.append('write_protect')
+        if (save_fields):
+            d.save(update_fields=save_fields)
+    except AttributeError,e:
+        raise e
+
 def update_dep(d, o):
-	try:
-		if (d.updated < o.updated):
-			d.save(update_fields=['updated'])
-	except AttributeError,e:
-		raise e
-	
+    try:
+        print 'Trying to update %s'%d
+        save_fields = []
+        if (d.updated < o.updated):
+            save_fields = ['updated']
+
+        if (save_fields):
+            d.save(update_fields=save_fields)
+    except AttributeError,e:
+        raise e
+
 def delete_if_inactive(d, o):
-	#print "Deleting %s (%s)"%(d,d.__class__.__name__)
-	# d.delete()	
-	return
+    try:
+        d.delete()
+        print "Deleted %s (%s)"%(d,d.__class__.__name__)
+    except:
+        pass
+    return
+
 
 @atomic
 def execute_model_policy(instance, deleted):
-	# Automatic dirtying
-	walk_inv_deps(update_dep, instance)
+    # Automatic dirtying
+    if (instance in bad_instances):
+        return
 
-	sender_name = instance.__class__.__name__
-	policy_name = 'model_policy_%s'%sender_name
-	noargs = False
+    # These are the models whose children get deleted when they are
+    delete_policy_models = ['Slice','Sliver','Network']
+    sender_name = instance.__class__.__name__
+    policy_name = 'model_policy_%s'%sender_name
+    noargs = False
 
-	if deleted:
-		walk_inv_deps(delete_if_inactive, instance)
-	else:
-		try:
-			policy_handler = getattr(model_policies, policy_name, None)
-			logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))                       
-			if policy_handler is not None:
-				policy_handler.handle(instance)
-		except:
-			logger.log_exc("Model Policy Error:") 
-			print "Policy Exceution Error"
+    if (not deleted):
+        walk_inv_deps(update_dep, instance)
+        walk_deps(update_wp, instance)
+    elif (sender_name in delete_policy_models):
+        walk_inv_deps(delete_if_inactive, instance)
 
-	instance.policed=datetime.now()
+
+
+    try:
+        policy_handler = getattr(model_policies, policy_name, None)
+        logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))
+        if policy_handler is not None:
+            if (deleted):
+                try:
+                    policy_handler.handle_delete(instance)
+                except AttributeError:
+                    pass
+            else:
+                policy_handler.handle(instance)
+    except:
+        logger.log_exc("Model Policy Error:")
+
+    try:
+        instance.policed=datetime.now()
         instance.save(update_fields=['policed'])
+    except:
+        logging.error('Object %r is defective'%instance)
+        bad_instances.append(instance)
 
 def run_policy():
-        from core.models import Sliver,Slice,Controller,Network,User,SlicePrivilege,Site,SitePrivilege,Image,ControllerSlice,ControllerUser,ControllerSite
-	while (True):
-		start = time.time()
-		models = [Sliver,Slice, Controller, Network, User, SlicePrivilege, Site, SitePrivilege, Image, ControllerSlice, ControllerSite, ControllerUser]
-		objects = []
-		
-		for m in models:
-        		res = m.objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
-			objects.extend(res)	
+    from core.models import Sliver,Slice,Controller,Network,User,SlicePrivilege,Site,SitePrivilege,Image,ControllerSlice,ControllerUser,ControllerSite
+    while (True):
+        start = time.time()
+        models = [Sliver,Slice, Controller, Network, User, SlicePrivilege, Site, SitePrivilege, Image, ControllerSlice, ControllerSite, ControllerUser]
+        objects = []
+        deleted_objects = []
 
-		for o in objects:
-			print "Working on %r"%o
-			execute_model_policy(o, False)
-		
-		
-		if (time.time()-start<1):
-			time.sleep(1)	
+        for m in models:
+            res = m.objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
+            objects.extend(res)
+            res = m.deleted_objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
+            deleted_objects.extend(res)
+
+        for o in objects:
+            execute_model_policy(o, o.deleted)
+
+        for o in deleted_objects:
+            execute_model_policy(o, True)
+
+
+        if (time.time()-start<1):
+            time.sleep(1)
diff --git a/xos/openstack_observer/event_loop.py b/xos/openstack_observer/event_loop.py
index 04b5c97..a63ff3c 100644
--- a/xos/openstack_observer/event_loop.py
+++ b/xos/openstack_observer/event_loop.py
@@ -193,7 +193,8 @@
 		pp.pprint(step_graph)
 		self.ordered_steps = toposort(self.dependency_graph, map(lambda s:s.__name__,self.sync_steps))
 		#self.ordered_steps = ['SyncRoles', 'SyncControllerSites', 'SyncControllerSitePrivileges','SyncImages', 'SyncControllerImages','SyncControllerUsers','SyncControllerUserSitePrivileges','SyncControllerSlices', 'SyncControllerSlicePrivileges', 'SyncControllerUserSlicePrivileges', 'SyncControllerNetworks','SyncSlivers']
-		#self.ordered_steps = ['SyncControllerSites','SyncControllerUsers','SyncControllerSlices','SyncControllerNetworks']
+		#self.ordered_steps = ['SyncControllerSites','SyncRoles','SyncControllerUsers','SyncControllerSlices','SyncControllerNetworks']
+		#self.ordered_steps = ['SyncControllerNetworks']
 		#self.ordered_steps = ['SyncSlivers','SyncNetworkSlivers']
 
 		print "Order of steps=",self.ordered_steps
diff --git a/xos/openstack_observer/steps/sync_controller_images.py b/xos/openstack_observer/steps/sync_controller_images.py
index 19009dd..94b18a0 100644
--- a/xos/openstack_observer/steps/sync_controller_images.py
+++ b/xos/openstack_observer/steps/sync_controller_images.py
@@ -8,6 +8,7 @@
 from core.models import Image, ControllerImages
 from util.logger import observer_logger as logger 
 from observer.ansible import *
+import json
 
 class SyncControllerImages(OpenStackSyncStep):
     provides=[ControllerImages]
@@ -23,6 +24,11 @@
 
     def sync_record(self, controller_image):
         logger.info("Working on image %s on controller %s" % (controller_image.image.name, controller_image.controller))
+
+	controller_register = json.loads(controller_image.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_image.controller.name)
+
         image_fields = {'endpoint':controller_image.controller.auth_url,
                         'admin_user':controller_image.controller.admin_user,
                         'admin_password':controller_image.controller.admin_password,
diff --git a/xos/openstack_observer/steps/sync_controller_networks.py b/xos/openstack_observer/steps/sync_controller_networks.py
index 8866e53..d327b7b 100644
--- a/xos/openstack_observer/steps/sync_controller_networks.py
+++ b/xos/openstack_observer/steps/sync_controller_networks.py
@@ -11,6 +11,7 @@
 from util.logger import observer_logger as logger
 from observer.ansible import *
 from openstack.driver import OpenStackDriver
+import json
 
 import pdb
 
@@ -44,7 +45,8 @@
                     'name':network_name,
                     'subnet_name':subnet_name,
                     'ansible_tag':'%s-%s@%s'%(network_name,slice.slicename,controller_network.controller.name),
-                    'cidr':cidr
+                    'cidr':cidr,
+                    'delete':False	
                     }
 
         res = run_template('sync_controller_networks.yaml', network_fields, path = 'controller_networks',expected_num=2)
@@ -61,6 +63,10 @@
     def sync_record(self, controller_network):
         logger.info("sync'ing network controller %s for network %s slice %s controller %s" % (controller_network, controller_network.network, str(controller_network.network.owner), controller_network.controller))
 
+	controller_register = json.loads(controller_network.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_network.controller.name)
+
         if not controller_network.controller.admin_user:
             logger.info("controller %r has no admin_user, skipping" % controller_network.controller)
             return
@@ -70,6 +76,32 @@
 	    logger.info("saved network controller: %s" % (controller_network))
 
     def delete_record(self, controller_network):
+	controller_register = json.loads(controller_network.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_network.controller.name)
+
+	try:
+        	slice = controller_network.network.owner # XXX: FIXME!!
+        except:
+                raise Exception('Could not get slice for Network %s'%controller_network.network.name)
+
+	network_name = controller_network.network.name
+        subnet_name = '%s-%d'%(network_name,controller_network.pk)
+	cidr = controller_network.subnet
+	network_fields = {'endpoint':controller_network.controller.auth_url,
+                    'admin_user':slice.creator.email, # XXX: FIXME
+                    'tenant_name':slice.name, # XXX: FIXME
+                    'admin_password':slice.creator.remote_password,
+                    'name':network_name,
+                    'subnet_name':subnet_name,
+                    'ansible_tag':'%s-%s@%s'%(network_name,slice.slicename,controller_network.controller.name),
+                    'cidr':cidr,
+		    'delete':True	
+                    }
+
+        res = run_template('sync_controller_networks.yaml', network_fields, path = 'controller_networks',expected_num=1)
+
+	"""
         driver = OpenStackDriver().client_driver(caller=controller_network.network.owner.creator,
                                                  tenant=controller_network.network.owner.name,
                                                  controller=controller_network.controller.name)
@@ -81,3 +113,4 @@
             driver.delete_router(controller_network.router_id)
         if controller_network.net_id:
             driver.delete_network(controller_network.net_id)
+	"""
diff --git a/xos/openstack_observer/steps/sync_controller_networks.yaml b/xos/openstack_observer/steps/sync_controller_networks.yaml
index 8f0d4c1..6754c47 100644
--- a/xos/openstack_observer/steps/sync_controller_networks.yaml
+++ b/xos/openstack_observer/steps/sync_controller_networks.yaml
@@ -15,6 +15,7 @@
         state=present
         {% endif %}
         shared=true
+  {% if not delete %}
   - quantum_subnet:
         auth_url={{ endpoint }} 
         login_username={{ admin_user }}
@@ -30,3 +31,4 @@
         no_gateway=true 
         cidr={{ cidr }}
         {% endif %}
+  {% endif %}
diff --git a/xos/openstack_observer/steps/sync_controller_site_privileges.py b/xos/openstack_observer/steps/sync_controller_site_privileges.py
index 499a0ff..6a13736 100644
--- a/xos/openstack_observer/steps/sync_controller_site_privileges.py
+++ b/xos/openstack_observer/steps/sync_controller_site_privileges.py
@@ -9,6 +9,7 @@
 from core.models.controlleruser import ControllerUser, ControllerSitePrivilege
 from util.logger import observer_logger as logger
 from observer.ansible import *
+import json
 
 class SyncControllerSitePrivileges(OpenStackSyncStep):
     provides=[SitePrivilege]
@@ -25,6 +26,11 @@
     def sync_record(self, controller_site_privilege):
         logger.info("sync'ing controler_site_privilege %s at controller %s" % (controller_site_privilege, controller_site_privilege.controller))
 
+	controller_register = json.loads(controller_site_privilege.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_site_privilege.controller.name)
+
+
         if not controller_site_privilege.controller.admin_user:
             logger.info("controller %r has no admin_user, skipping" % controller_site_privilege.controller)
             return
@@ -68,6 +74,10 @@
             controller_site_privilege.save()
 
     def delete_record(self, controller_site_privilege):
+	controller_register = json.loads(controller_site_privilege.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_site_privilege.controller.name)
+
         if controller_site_privilege.role_id:
             driver = self.driver.admin_driver(controller=controller_site_privilege.controller)
             user = ControllerUser.objects.get(
diff --git a/xos/openstack_observer/steps/sync_controller_sites.py b/xos/openstack_observer/steps/sync_controller_sites.py
index acb6ba9..f101315 100644
--- a/xos/openstack_observer/steps/sync_controller_sites.py
+++ b/xos/openstack_observer/steps/sync_controller_sites.py
@@ -6,6 +6,7 @@
 from core.models.site import *
 from observer.ansible import *
 from util.logger import observer_logger as logger
+import json
 
 class SyncControllerSites(OpenStackSyncStep):
     requested_interval=0
@@ -17,6 +18,10 @@
         return pending.filter(controller__isnull=False)
 
     def sync_record(self, controller_site):
+	controller_register = json.loads(controller_site.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_site.controller.name)
+
 	template = os_template_env.get_template('sync_controller_sites.yaml')
 	tenant_fields = {'endpoint':controller_site.controller.auth_url,
 		         'admin_user': controller_site.controller.admin_user,
@@ -34,6 +39,10 @@
         controller_site.save()
             
     def delete_record(self, controller_site):
+	controller_register = json.loads(controller_site.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_site.controller.name)
+
 	if controller_site.tenant_id:
             driver = self.driver.admin_driver(controller=controller_site.controller)
             driver.delete_tenant(controller_site.tenant_id)
diff --git a/xos/openstack_observer/steps/sync_controller_slice_privileges.py b/xos/openstack_observer/steps/sync_controller_slice_privileges.py
index f1600ca..38f23c2 100644
--- a/xos/openstack_observer/steps/sync_controller_slice_privileges.py
+++ b/xos/openstack_observer/steps/sync_controller_slice_privileges.py
@@ -9,6 +9,7 @@
 from core.models.controlleruser import ControllerUser, ControllerSlicePrivilege
 from observer.ansible import *
 from util.logger import observer_logger as logger
+import json
 
 class SyncControllerSlicePrivileges(OpenStackSyncStep):
     provides=[SlicePrivilege]
@@ -25,6 +26,10 @@
     def sync_record(self, controller_slice_privilege):
         logger.info("sync'ing controler_slice_privilege %s at controller %s" % (controller_slice_privilege, controller_slice_privilege.controller))
 
+	controller_register = json.loads(controller_slice_privilege.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_slice_privilege.controller.name)
+
         if not controller_slice_privilege.controller.admin_user:
             logger.info("controller %r has no admin_user, skipping" % controller_slice_privilege.controller)
             return
@@ -68,6 +73,10 @@
             controller_slice_privilege.save()
 
     def delete_record(self, controller_slice_privilege):
+	controller_register = json.loads(controller_slice_privilege.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_slice_privilege.controller.name)
+
         if controller_slice_privilege.role_id:
             driver = self.driver.admin_driver(controller=controller_slice_privilege.controller)
             user = ControllerUser.objects.get(
diff --git a/xos/openstack_observer/steps/sync_controller_slices.py b/xos/openstack_observer/steps/sync_controller_slices.py
index 591a1b6..8d4a5e0 100644
--- a/xos/openstack_observer/steps/sync_controller_slices.py
+++ b/xos/openstack_observer/steps/sync_controller_slices.py
@@ -5,12 +5,11 @@
 from django.db.models import F, Q
 from xos.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
-from core.models import User
-from core.models.slice import Slice, ControllerSlice
-from core.models.controlleruser import ControllerUser
+from core.models import *
 from observer.ansible import *
 from openstack.driver import OpenStackDriver
 from util.logger import observer_logger as logger
+import json
 
 class SyncControllerSlices(OpenStackSyncStep):
     provides=[Slice]
@@ -26,6 +25,10 @@
     def sync_record(self, controller_slice):
         logger.info("sync'ing slice controller %s" % controller_slice)
 
+        controller_register = json.loads(controller_slice.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+            raise Exception('Controller %s is disabled'%controller_slice.controller.name)
+
         if not controller_slice.controller.admin_user:
             logger.info("controller %r has no admin_user, skipping" % controller_slice.controller)
             return
@@ -55,31 +58,38 @@
         tenant_id = res[0]['id']
         if (not controller_slice.tenant_id):
             try:
-                    driver = OpenStackDriver().admin_driver(controller=controller_slice.controller)
-                    driver.shell.nova.quotas.update(tenant_id=controller_slice.tenant_id, instances=int(controller_slice.slice.max_slivers))
+                driver = OpenStackDriver().admin_driver(controller=controller_slice.controller)
+                driver.shell.nova.quotas.update(tenant_id=controller_slice.tenant_id, instances=int(controller_slice.slice.max_slivers))
             except:
-                    logger.log_exc('Could not update quota for %s'%controller_slice.slice.name)
-                    raise Exception('Could not update quota for %s'%controller_slice.slice.name)
-                
+                logger.log_exc('Could not update quota for %s'%controller_slice.slice.name)
+                raise Exception('Could not update quota for %s'%controller_slice.slice.name)
+
             controller_slice.tenant_id = tenant_id
             controller_slice.backend_status = '1 - OK'
             controller_slice.save()
 
 
     def delete_record(self, controller_slice):
-        user = User.objects.get(id=controller_slice.slice.creator.id)
-        driver = OpenStackDriver().admin_driver(controller=controller_slice.controller)
-        client_driver = driver.client_driver(caller=user,
-                                             tenant=controller_slice.slice.name,
-                                             controller=controller_slice.controller)
+        controller_register = json.loads(controller_slice.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+            raise Exception('Controller %s is disabled'%controller_slice.controller.name)
 
-        if controller_slice.router_id and controller_slice.subnet_id:
-            client_driver.delete_router_interface(controller_slice.router_id, controller_slice.subnet_id)
-        if controller_slice.subnet_id:
-            client_driver.delete_subnet(controller_slice.subnet_id)
-        if controller_slice.router_id:
-            client_driver.delete_router(controller_slice.router_id)
-        if controller_slice.network_id:
-            client_driver.delete_network(controller_slice.network_id)
-        if controller_slice.tenant_id:
-            driver.delete_tenant(controller_slice.tenant_id)
+        controller_users = ControllerUser.objects.filter(user=controller_slice.slice.creator,
+                                                              controller=controller_slice.controller)
+        if not controller_users:
+            raise Exception("slice createor %s has not accout at controller %s" % (controller_slice.slice.creator, controller_slice.controller.name))
+        else:
+            controller_user = controller_users[0]
+
+        tenant_fields = {'endpoint':controller_slice.controller.auth_url,
+                          'admin_user': controller_slice.controller.admin_user,
+                          'admin_password': controller_slice.controller.admin_password,
+                          'admin_tenant': 'admin',
+                          'tenant': controller_slice.slice.name,
+                          'tenant_description': controller_slice.slice.description,
+                          'name':controller_user.user.email,
+                          'ansible_tag':'%s@%s'%(controller_slice.slice.name,controller_slice.controller.name),
+                          'delete': True}
+
+        expected_num = 1
+        run_template('sync_controller_slices.yaml', tenant_fields, path='controller_slices', expected_num=expected_num)
diff --git a/xos/openstack_observer/steps/sync_controller_slices.yaml b/xos/openstack_observer/steps/sync_controller_slices.yaml
index de1caf4..380f001 100644
--- a/xos/openstack_observer/steps/sync_controller_slices.yaml
+++ b/xos/openstack_observer/steps/sync_controller_slices.yaml
@@ -2,7 +2,11 @@
 - hosts: 127.0.0.1
   connection: local
   tasks:
+  {% if delete %}
+  - keystone_user: endpoint={{ endpoint }} login_user={{ admin_user }} login_password={{ admin_password }} login_tenant_name={{ admin_tenant }} tenant={{ tenant }} tenant_description="{{ tenant_description }}" state=absent
+  {% else %}	
   - keystone_user: endpoint={{ endpoint }} login_user={{ admin_user }} login_password={{ admin_password }} login_tenant_name={{ admin_tenant }} tenant={{ tenant }} tenant_description="{{ tenant_description }}"
   {% for role in roles %}
   - keystone_user: endpoint={{ endpoint}} login_user={{ admin_user }} login_password={{ admin_password }} login_tenant_name={{ admin_tenant }} user="{{ name }}" role={{ role }} tenant={{ tenant }}
   {% endfor %}
+  {% endif %} 
diff --git a/xos/openstack_observer/steps/sync_controller_users.py b/xos/openstack_observer/steps/sync_controller_users.py
index acb3050..47d1096 100644
--- a/xos/openstack_observer/steps/sync_controller_users.py
+++ b/xos/openstack_observer/steps/sync_controller_users.py
@@ -9,6 +9,7 @@
 from core.models.controlleruser import ControllerUser
 from observer.ansible import *
 from util.logger import observer_logger as logger
+import json
 
 class SyncControllerUsers(OpenStackSyncStep):
     provides=[User]
@@ -25,6 +26,10 @@
     def sync_record(self, controller_user):
         logger.info("sync'ing user %s at controller %s" % (controller_user.user, controller_user.controller))
 
+	controller_register = json.loads(controller_user.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_user.controller.name)
+
         if not controller_user.controller.admin_user:
             logger.info("controller %r has no admin_user, skipping" % controller_user.controller)
             return
@@ -72,6 +77,10 @@
             controller_user.save()
 
     def delete_record(self, controller_user):
+	controller_register = json.loads(controller_user.controller.backend_register)
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%controller_user.controller.name)
+
         if controller_user.kuser_id:
             driver = self.driver.admin_driver(controller=controller_user.controller)
             driver.delete_user(controller_user.kuser_id)
diff --git a/xos/openstack_observer/steps/sync_slivers.py b/xos/openstack_observer/steps/sync_slivers.py
index 9ee7cfa..9b5dd99 100644
--- a/xos/openstack_observer/steps/sync_slivers.py
+++ b/xos/openstack_observer/steps/sync_slivers.py
@@ -29,6 +29,10 @@
 
     def sync_record(self, sliver):
         logger.info("sync'ing sliver:%s slice:%s controller:%s " % (sliver, sliver.slice.name, sliver.node.site_deployment.controller))
+        controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
+
+        if (controller_register.get('disabled',False)):
+            raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
 
         metadata_update = {}
         if (sliver.numberCores):
@@ -143,6 +147,11 @@
         sliver.save()
 
     def delete_record(self, sliver):
+        controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
+
+        if (controller_register.get('disabled',False)):
+            raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
+
         sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)
         controller = sliver.node.site_deployment.controller
         tenant_fields = {'endpoint':controller.auth_url,
@@ -156,12 +165,12 @@
                      'delete': True}
 
         try:
-               res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)

+            res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)

         except Exception,e:

-               print "Could not sync %s"%sliver_name

-               #import traceback

-               #traceback.print_exc()

-               raise e

+            print "Could not sync %s"%sliver_name

+            #import traceback

+            #traceback.print_exc()

+            raise e

 
         if (len(res)!=1):
             raise Exception('Could not delete sliver %s'%sliver.slice.name)
diff --git a/xos/openstack_observer/syncstep.py b/xos/openstack_observer/syncstep.py
index a4d591d..b752760 100644
--- a/xos/openstack_observer/syncstep.py
+++ b/xos/openstack_observer/syncstep.py
@@ -108,7 +108,6 @@
                     next_run = scratchpad['next_run']
                     if (not backoff_disabled and next_run>time.time()):
                         sync_failed = True
-                        print "BACKING OFF, exponent = %d"%scratchpad['exponent']
             except:
                 pass
 
@@ -176,5 +175,11 @@
 
         return failed
 
+    def sync_record(self, o):
+        return
+
+    def delete_record(self, o):
+        return
+
     def __call__(self, **args):
         return self.call(**args)