migrate code over from xos repo

Change-Id: I764ac3196babdb1ce78dded2b2d8d6ad6e965ca6
diff --git a/xos/synchronizer/model_policies/__init__.py b/xos/synchronizer/model_policies/__init__.py
new file mode 100644
index 0000000..36c6e25
--- /dev/null
+++ b/xos/synchronizer/model_policies/__init__.py
@@ -0,0 +1,12 @@
+from .model_policy_Slice import *
+from .model_policy_Instance import *
+from .model_policy_User import *
+from .model_policy_Network import *
+from .model_policy_Site import *
+from .model_policy_SitePrivilege import *
+from .model_policy_SlicePrivilege import *
+from .model_policy_ControllerSlice import *
+from .model_policy_ControllerSite import *
+from .model_policy_ControllerUser import *
+from .model_policy_Controller import *
+from .model_policy_Image import *
diff --git a/xos/synchronizer/model_policies/model_policy_Controller.py b/xos/synchronizer/model_policies/model_policy_Controller.py
new file mode 100644
index 0000000..c62b612
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Controller.py
@@ -0,0 +1,62 @@
+
+def handle(controller):
+    from core.models import Controller, Site, ControllerSite, Slice, ControllerSlice, User, ControllerUser, ControllerImages, ControllerNetwork, Image, Network
+    from collections import defaultdict
+
+    # relations for all sites
+    ctrls_by_site = defaultdict(list)
+    ctrl_sites = ControllerSite.objects.all()
+    for ctrl_site in ctrl_sites:
+        ctrls_by_site[ctrl_site.site].append(ctrl_site.controller)
+    sites = Site.objects.all()
+    for site in sites:
+        if site not in ctrls_by_site or \
+            controller not in ctrls_by_site[site]:
+            controller_site = ControllerSite(controller=controller, site=site)
+            controller_site.save()
+    # relations for all slices
+    ctrls_by_slice = defaultdict(list)
+    ctrl_slices = ControllerSlice.objects.all()
+    for ctrl_slice in ctrl_slices:
+        ctrls_by_slice[ctrl_slice.slice].append(ctrl_slice.controller)
+    slices = Slice.objects.all()
+    for slice in slices:
+        if slice not in ctrls_by_slice or \
+            controller not in ctrls_by_slice[slice]:
+            controller_slice = ControllerSlice(controller=controller, slice=slice)
+            controller_slice.save()
+    # relations for all users
+    ctrls_by_user = defaultdict(list)
+    ctrl_users = ControllerUser.objects.all()
+    for ctrl_user in ctrl_users:
+        ctrls_by_user[ctrl_user.user].append(ctrl_user.controller)
+    users = User.objects.all()
+    for user in users:
+        if user not in ctrls_by_user or \
+            controller not in ctrls_by_user[user]:
+            controller_user = ControllerUser(controller=controller, user=user)
+            controller_user.save()
+    # relations for all networks
+    ctrls_by_network = defaultdict(list)
+    ctrl_networks = ControllerNetwork.objects.all()
+    for ctrl_network in ctrl_networks:
+        ctrls_by_network[ctrl_network.network].append(ctrl_network.controller)
+    networks = Network.objects.all()
+    for network in networks:
+        if network not in ctrls_by_network or \
+            controller not in ctrls_by_network[network]:
+            controller_network = ControllerNetwork(controller=controller, network=network)
+            if network.subnet and network.subnet.strip():
+                controller_network.subnet = network.subnet.strip()
+            controller_network.save()
+    # relations for all images
+    ctrls_by_image = defaultdict(list)
+    ctrl_images = ControllerImages.objects.all()
+    for ctrl_image in ctrl_images:
+        ctrls_by_image[ctrl_image.image].append(ctrl_image.controller)
+    images = Image.objects.all()
+    for image in images:
+        if image not in ctrls_by_image or \
+            controller not in ctrls_by_image[image]:
+            controller_image = ControllerImages(controller=controller, image=image)
+            controller_image.save()
diff --git a/xos/synchronizer/model_policies/model_policy_ControllerSite.py b/xos/synchronizer/model_policies/model_policy_ControllerSite.py
new file mode 100644
index 0000000..4b76080
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_ControllerSite.py
@@ -0,0 +1,16 @@
+def handle(controller_site):
+    from core.models import ControllerSite, Site
+   
+    try:
+        my_status_code = int(controller_site.backend_status[0])
+        try:
+            his_status_code = int(controller_site.site.backend_status[0])
+        except:
+            his_status_code = 0
+ 
+        if (my_status_code not in [0,his_status_code]):
+            controller_site.site.backend_status = controller_site.backend_status
+            controller_site.site.save(update_fields = ['backend_status'])
+    except Exception,e:
+        print str(e)	
+        pass
diff --git a/xos/synchronizer/model_policies/model_policy_ControllerSlice.py b/xos/synchronizer/model_policies/model_policy_ControllerSlice.py
new file mode 100644
index 0000000..bfe7995
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_ControllerSlice.py
@@ -0,0 +1,25 @@
+def handle(controller_slice):
+    from core.models import ControllerSlice, Slice
+   
+    try:
+        my_status_code = int(controller_slice.backend_status[0])
+        try:
+            his_status_code = int(controller_slice.slice.backend_status[0])
+        except:
+            his_status_code = 0
+ 
+        fields = []
+        if (my_status_code not in [0,his_status_code]):
+            controller_slice.slice.backend_status = controller_slice.backend_status
+            fields+=['backend_status']
+
+        if (controller_slice.backend_register != controller_slice.slice.backend_register):
+            controller_slice.slice.backend_register = controller_slice.backend_register
+            fields+=['backend_register']
+
+        controller_slice.slice.save(update_fields = fields)
+
+        
+    except Exception,e:
+        print str(e)	
+        pass
diff --git a/xos/synchronizer/model_policies/model_policy_ControllerUser.py b/xos/synchronizer/model_policies/model_policy_ControllerUser.py
new file mode 100644
index 0000000..b69c9b8
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_ControllerUser.py
@@ -0,0 +1,16 @@
+def handle(controller_user):
+    from core.models import ControllerUser, User
+   
+    try:
+        my_status_code = int(controller_user.backend_status[0])
+        try:
+            his_status_code = int(controller_user.user.backend_status[0])
+        except:
+            his_status_code = 0
+ 
+        if (my_status_code not in [0,his_status_code]):
+            controller_user.user.backend_status = controller_user.backend_status
+            controller_user.user.save(update_fields = ['backend_status'])
+    except Exception,e:
+        print str(e)	
+        pass
diff --git a/xos/synchronizer/model_policies/model_policy_Image.py b/xos/synchronizer/model_policies/model_policy_Image.py
new file mode 100644
index 0000000..c77d5bb
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Image.py
@@ -0,0 +1,17 @@
+def handle(image):
+    from core.models import Controller, ControllerImages, Image
+    from collections import defaultdict
+
+    if (image.kind == "container"):
+        # container images do not get instantiated
+        return
+
+    controller_images = ControllerImages.objects.filter(image=image)
+    existing_controllers = [cs.controller for cs in controller_images] 
+    
+    all_controllers = Controller.objects.all() 
+    for controller in all_controllers:
+        if controller not in existing_controllers:
+            sd = ControllerImages(image=image, controller=controller)
+            sd.save()
+
diff --git a/xos/synchronizer/model_policies/model_policy_Instance.py b/xos/synchronizer/model_policies/model_policy_Instance.py
new file mode 100644
index 0000000..dd1a8d5
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Instance.py
@@ -0,0 +1,58 @@
+def handle_container_on_metal(instance):
+        from core.models import Instance, Flavor, Port, Image
+
+        print "MODEL POLICY: instance", instance, "handle container_on_metal"
+
+        if instance.deleted:
+            return
+
+        if (instance.isolation in ["container"]) and (instance.slice.network not in ["host", "bridged"]):
+            # Our current docker-on-metal network strategy requires that there be some
+            # VM on the server that connects to the networks, so that
+            # the containers can piggyback off of that configuration.
+            if not Instance.objects.filter(slice=instance.slice, node=instance.node, isolation="vm").exists():
+                flavors = Flavor.objects.filter(name="m1.small")
+                if not flavors:
+                    raise XOSConfigurationError("No m1.small flavor")
+
+                images = Image.objects.filter(kind="vm")
+
+                companion_instance = Instance(slice = instance.slice,
+                                node = instance.node,
+                                image = images[0],
+                                creator = instance.creator,
+                                deployment = instance.node.site_deployment.deployment,
+                                flavor = flavors[0])
+                companion_instance.save()
+
+                print "MODEL POLICY: instance", instance, "created companion", companion_instance
+
+        # Add the ports for the container
+        for network in instance.slice.networks.all():
+            # hmmm... The NAT ports never become ready, because sync_ports never
+            # instantiates them. Need to think about this.
+            print "MODEL POLICY: instance", instance, "handling network", network
+            if (network.name.endswith("-nat")):
+                continue
+
+            if not Port.objects.filter(network=network, instance=instance).exists():
+                port = Port(network = network, instance=instance)
+                port.save()
+                print "MODEL POLICY: instance", instance, "created port", port
+
+def handle(instance):
+    from core.models import Controller, ControllerSlice, ControllerNetwork, NetworkSlice
+
+    networks = [ns.network for ns in NetworkSlice.objects.filter(slice=instance.slice)]
+    controller_networks = ControllerNetwork.objects.filter(network__in=networks,
+                                                                controller=instance.node.site_deployment.controller)
+
+    for cn in controller_networks:
+        if (cn.lazy_blocked):
+                print "MODEL POLICY: instance", instance, "unblocking network", cn.network
+		cn.lazy_blocked=False
+		cn.backend_register = '{}'
+		cn.save()
+
+    if (instance.isolation in ["container", "container_vm"]):
+        handle_container_on_metal(instance)
diff --git a/xos/synchronizer/model_policies/model_policy_Network.py b/xos/synchronizer/model_policies/model_policy_Network.py
new file mode 100644
index 0000000..06347c5
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Network.py
@@ -0,0 +1,41 @@
+from core.models import *
+
+def handle(network):
+	from core.models import ControllerSlice,ControllerNetwork, Network
+	from collections import defaultdict
+
+        print "MODEL POLICY: network", network
+
+        # network = Network.get(network_id)
+	# network controllers are not visible to users. We must ensure
+	# networks are deployed at all deploymets available to their slices.
+	slice_controllers = ControllerSlice.objects.all()
+	slice_deploy_lookup = defaultdict(list)
+	for slice_controller in slice_controllers:
+		slice_deploy_lookup[slice_controller.slice].append(slice_controller.controller)
+
+	network_controllers = ControllerNetwork.objects.all()
+	network_deploy_lookup = defaultdict(list)
+	for network_controller in network_controllers:
+		network_deploy_lookup[network_controller.network].append(network_controller.controller)
+
+	expected_controllers = slice_deploy_lookup[network.owner]
+	for expected_controller in expected_controllers:
+		if network not in network_deploy_lookup or \
+		  expected_controller not in network_deploy_lookup[network]:
+                        lazy_blocked=True
+
+                        # check and see if some instance already exists
+                        for networkslice in network.networkslices.all():
+                            if networkslice.slice.instances.filter(node__site_deployment__controller=expected_controller).exists():
+                               print "MODEL_POLICY: network, setting lazy_blocked to false because instance on controller already exists"
+                               lazy_blocked=False
+
+			nd = ControllerNetwork(network=network, controller=expected_controller, lazy_blocked=lazy_blocked)
+                        print "MODEL POLICY: network", network, "create ControllerNetwork", nd, "lazy_blocked", lazy_blocked
+                        if network.subnet:
+                            # XXX: Possibly unpredictable behavior if there is
+                            # more than one ControllerNetwork and the subnet
+                            # is specified.
+                            nd.subnet = network.subnet
+			nd.save()
diff --git a/xos/synchronizer/model_policies/model_policy_Site.py b/xos/synchronizer/model_policies/model_policy_Site.py
new file mode 100644
index 0000000..23010a2
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Site.py
@@ -0,0 +1,14 @@
+
+def handle(site):
+    from core.models import Controller, ControllerSite, Site 
+
+    # site = Site.get(site_id)
+    # make sure site has a ControllerSite record for each controller
+    ctrl_sites = ControllerSite.objects.filter(site=site)
+    existing_controllers = [cs.controller for cs in ctrl_sites]
+
+    all_controllers = Controller.objects.all()
+    for ctrl in all_controllers:
+        if ctrl not in existing_controllers:
+            ctrl_site = ControllerSite(controller=ctrl, site=site)
+            ctrl_site.save() 
diff --git a/xos/synchronizer/model_policies/model_policy_SitePrivilege.py b/xos/synchronizer/model_policies/model_policy_SitePrivilege.py
new file mode 100644
index 0000000..d9c6a1e
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_SitePrivilege.py
@@ -0,0 +1,15 @@
+def handle(site_privilege):
+    from core.models import Controller, SitePrivilege, ControllerSitePrivilege
+    
+    # site_privilege = SitePrivilege.get(site_privilege_id)
+    # apply site privilage at all controllers
+    controller_site_privileges = ControllerSitePrivilege.objects.filter(
+        site_privilege = site_privilege,
+        )
+    existing_controllers = [sp.controller for sp in controller_site_privileges]
+    all_controllers = Controller.objects.all()
+    for controller in all_controllers:
+        if controller not in existing_controllers:
+            ctrl_site_priv = ControllerSitePrivilege(controller=controller, site_privilege=site_privilege)
+            ctrl_site_priv.save()  
+
diff --git a/xos/synchronizer/model_policies/model_policy_Slice.py b/xos/synchronizer/model_policies/model_policy_Slice.py
new file mode 100644
index 0000000..088d583
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Slice.py
@@ -0,0 +1,102 @@
+from xos.config import Config
+
+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
+
+    # only create nat_net if not using VTN
+    support_nat_net = not getattr(Config(), "networking_use_vtn", False)
+
+    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()
+
+    if slice.network in ["host", "bridged"]:
+        # Host and Bridged docker containers need no networks and they will
+        # only get in the way.
+        print "MODEL POLICY: Skipping network creation"
+    elif slice.network in ["noauto"]:
+        # do nothing
+        pass
+    else:
+        # make sure slice has at least 1 public and 1 private networkd
+        public_nets = []
+        private_nets = []
+        networks = Network.objects.filter(owner=slice)
+        for network in networks:
+            if not network.autoconnect:
+                continue
+            if network.template.name == 'Public dedicated IPv4':
+                public_nets.append(network)
+            elif network.template.name == 'Public shared IPv4':
+                public_nets.append(network)
+            elif network.template.name == 'Private':
+                private_nets.append(network)
+        if support_nat_net and (not public_nets):
+            # ensure there is at least one public network, and default it to dedicated
+            nat_net = Network(
+                    name = slice.name+'-nat',
+                        template = NetworkTemplate.objects.get(name='Public shared IPv4'),
+                    owner = slice
+                    )
+            if slice.exposed_ports:
+                nat_net.ports = slice.exposed_ports
+            nat_net.save()
+            public_nets.append(nat_net)
+            print "MODEL POLICY: slice", slice, "made nat-net"
+
+        if not private_nets:
+            private_net = Network(
+                name = slice.name+'-private',
+                template = NetworkTemplate.objects.get(name='Private'),
+                owner = slice
+            )
+            private_net.save()
+            print "MODEL POLICY: slice", slice, "made private net"
+            private_nets = [private_net]
+        # create slice networks
+        public_net_slice = None
+        private_net_slice = None
+        net_slices = NetworkSlice.objects.filter(slice=slice, network__in=private_nets+public_nets)
+        for net_slice in net_slices:
+            if net_slice.network in public_nets:
+                public_net_slice = net_slice
+            elif net_slice.network in private_nets:
+                private_net_slice = net_slice
+        if support_nat_net and (not public_net_slice):
+            public_net_slice = NetworkSlice(slice=slice, network=public_nets[0])
+            public_net_slice.save()
+            print "MODEL POLICY: slice", slice, "made public_net_slice"
+        if not private_net_slice:
+            private_net_slice = NetworkSlice(slice=slice, network=private_nets[0])
+            private_net_slice.save()
+            print "MODEL POLICY: slice", slice, "made private_net_slice"
+
+    print "MODEL POLICY: slice", slice, "DONE"
+
+
diff --git a/xos/synchronizer/model_policies/model_policy_SlicePrivilege.py b/xos/synchronizer/model_policies/model_policy_SlicePrivilege.py
new file mode 100644
index 0000000..bca7f22
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_SlicePrivilege.py
@@ -0,0 +1,15 @@
+def handle(slice_privilege):
+    from core.models import Controller, SlicePrivilege, ControllerSlicePrivilege
+   
+    # slice_privilege = SlicePrivilege.get(slice_privilege_id) 
+    # apply slice privilage at all controllers
+    controller_slice_privileges = ControllerSlicePrivilege.objects.filter(
+        slice_privilege = slice_privilege,
+        )
+    existing_controllers = [sp.controller for sp in controller_slice_privileges]
+    all_controllers = Controller.objects.all()
+    for controller in all_controllers:
+        if controller not in existing_controllers:
+            ctrl_slice_priv = ControllerSlicePrivilege(controller=controller, slice_privilege=slice_privilege)
+            ctrl_slice_priv.save()  
+
diff --git a/xos/synchronizer/model_policies/model_policy_Sliver.py b/xos/synchronizer/model_policies/model_policy_Sliver.py
new file mode 100644
index 0000000..a13428d
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_Sliver.py
@@ -0,0 +1,13 @@
+
+def handle(instance):
+    from core.models import Controller, ControllerSlice, ControllerNetwork, NetworkSlice
+
+    networks = [ns.network for ns in NetworkSlice.objects.filter(slice=instance.slice)]
+    controller_networks = ControllerNetwork.objects.filter(network__in=networks,
+                                                                controller=instance.node.site_deployment.controller)
+
+    for cn in controller_networks:
+        if (cn.lazy_blocked):	
+		cn.lazy_blocked=False
+		cn.backend_register = '{}'
+		cn.save()
diff --git a/xos/synchronizer/model_policies/model_policy_User.py b/xos/synchronizer/model_policies/model_policy_User.py
new file mode 100644
index 0000000..8d14244
--- /dev/null
+++ b/xos/synchronizer/model_policies/model_policy_User.py
@@ -0,0 +1,14 @@
+def handle(user):
+    from core.models import Controller, ControllerSite, ControllerUser, User
+    from collections import defaultdict
+
+    # user = User.get(user_id)
+    
+    controller_users = ControllerUser.objects.filter(user=user)
+    existing_controllers = [cu.controller for cu in controller_users]
+    all_controllers = Controller.objects.all()
+    for controller in all_controllers:
+        if controller not in existing_controllers:
+            ctrl_user = ControllerUser(controller=controller, user=user)
+            ctrl_user.save()  
+