[EDGEPOD-151] Modification in Fabric Switch and Switch Port Synchronizer to use fabric per site

Change-Id: I8dd412003c30315e04455fa049ceaf36d8353f91
diff --git a/VERSION b/VERSION
index 05d78bc..cb2b00e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0.1-dev
+3.0.1
diff --git a/xos/synchronizer/steps/helpers.py b/xos/synchronizer/steps/helpers.py
index 3ac04fe..e3308f6 100644
--- a/xos/synchronizer/steps/helpers.py
+++ b/xos/synchronizer/steps/helpers.py
@@ -13,6 +13,10 @@
 # limitations under the License.
 
 from __future__ import absolute_import
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get('logging'))
 
 class Helpers():
     @staticmethod
@@ -23,8 +27,25 @@
             return 'http://%s' % url
 
     @staticmethod
-    def get_onos_fabric_service(model_accessor):
-        # FIXME do not select by name but follow ServiceDependency
-        fabric_service = model_accessor.Service.objects.get(name="fabric")
-        onos_fabric_service = fabric_service.provider_services[0].leaf_model
+    def get_onos_fabric_service(model_accessor, switch=None):
+        fabric = None
+        if switch:
+            fabric = model_accessor.Service.objects.get(id=switch.fabric_id)
+        else:
+            fabric = model_accessor.Service.objects.get(name="fabric")
+        onos_fabric_service = fabric.provider_services[0].leaf_model
         return onos_fabric_service
+
+    @staticmethod
+    def get_onos(model, model_accessor, onos=None):
+        if(model.fabric != None):
+            onos = Helpers.get_onos_fabric_service(model_accessor, model)
+        else:
+            fabric_service = model_accessor.FabricService.objects.all()
+            if(len(fabric_service) == 1):
+                onos = Helpers.get_onos_fabric_service(model_accessor)
+
+        if not onos:
+            log.error("Configuration error. Fabric Service without ONOS is not possible.")
+            raise Exception("Configuration error. Fabric Service without ONOS is not possible.") 
+        return onos
diff --git a/xos/synchronizer/steps/sync_fabric_port.py b/xos/synchronizer/steps/sync_fabric_port.py
index 4f0c914..e3e0265 100644
--- a/xos/synchronizer/steps/sync_fabric_port.py
+++ b/xos/synchronizer/steps/sync_fabric_port.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,7 +27,6 @@
 
 log = create_logger(Config().get('logging'))
 
-
 class SyncFabricPort(SyncStep):
     provides = [SwitchPort]
     observes = [SwitchPort, PortInterface, FabricIpAddress]
@@ -71,12 +69,9 @@
 
         log.debug("Port %s/%s data" % (model.switch.ofId, model.portId), data=data)
 
-        onos = Helpers.get_onos_fabric_service(self.model_accessor)
-
+        onos = Helpers.get_onos(model.switch, self.model_accessor)
         url = 'http://%s:%s/onos/v1/network/configuration/' % (onos.rest_hostname, onos.rest_port)
-
         r = requests.post(url, json=data, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))
-
         if r.status_code != 200:
             log.error(r.text)
             raise Exception("Failed to add port  %s/%s into ONOS" % (model.switch.ofId, model.portId))
@@ -85,18 +80,12 @@
                 log.info("Port %s/%s response" % (model.switch.ofId, model.portId), json=r.json())
             except Exception:
                 log.info("Port %s/%s response" % (model.switch.ofId, model.portId), text=r.text)
-
         # Now set the port's administrative state.
-        # TODO(smbaker): See if netcfg allows us to specify the portstate instead of using a separate REST call
-
-        url = 'http://%s:%s/onos/v1/devices/%s/portstate/%s' % (onos.rest_hostname,
-                                                                onos.rest_port,
-                                                                model.switch.ofId,
-                                                                model.portId)
+        # TODO(smbaker): See if netcfg allows us to specify the portstate instead of using a separate REST call.
+        url = 'http://%s:%s/onos/v1/devices/%s/portstate/%s' % (onos.rest_hostname, onos.rest_port, model.switch.ofId, model.portId)
         data = {"enabled": True if model.admin_state == "enabled" else False}
         log.debug("Sending portstate %s to %s/%s" % (data, model.switch.ofId, model.portId))
         r = requests.post(url, json=data, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))
-
         if r.status_code != 200:
             log.error(r.text)
             raise Exception("Failed to set portstate  %s/%s into ONOS" % (model.switch.ofId, model.portId))
@@ -106,12 +95,10 @@
             except Exception:
                 log.info("Portstate %s/%s response" % (model.switch.ofId, model.portId), text=r.text)
 
-    def delete_netcfg_item(self, partial_url):
-        onos = Helpers.get_onos_fabric_service(self.model_accessor)
+    def delete_netcfg_item(self, partial_url, switch, model_accessor):
+        onos = Helpers.get_onos(switch, model_accessor)
         url = 'http://%s:%s/onos/v1/network/configuration/ports/%s' % (onos.rest_hostname, onos.rest_port, partial_url)
-
         r = requests.delete(url, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))
-
         if r.status_code != 204:
             log.error(r.text)
             raise Exception("Failed to %s port %s from ONOS" % url)
@@ -144,4 +131,4 @@
         key = urllib.quote(key, safe='')
 
         # deleting the port
-        self.delete_netcfg_item(key)
+        self.delete_netcfg_item(key, model.switch, self.model_accessor)
diff --git a/xos/synchronizer/steps/sync_fabric_switch.py b/xos/synchronizer/steps/sync_fabric_switch.py
index 15031cf..16943e4 100644
--- a/xos/synchronizer/steps/sync_fabric_switch.py
+++ b/xos/synchronizer/steps/sync_fabric_switch.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,7 +26,6 @@
 
 log = create_logger(Config().get('logging'))
 
-
 class SyncFabricSwitch(SyncStep):
     provides = [Switch]
     observes = Switch
@@ -56,11 +54,9 @@
             }
         }
 
-        onos = Helpers.get_onos_fabric_service(model_accessor=self.model_accessor)
-
+        onos = Helpers.get_onos(model, self.model_accessor)
         url = 'http://%s:%s/onos/v1/network/configuration/' % (onos.rest_hostname, onos.rest_port)
         r = requests.post(url, json=data, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))
-
         if r.status_code != 200:
             log.error(r.text)
             raise Exception("Failed to add device %s into ONOS: %s" % (model.name, r.text))
@@ -72,12 +68,9 @@
 
     def delete_record(self, model):
         log.info("Removing switch %s from onos-fabric" % model.name)
-        onos = Helpers.get_onos_fabric_service(model_accessor=self.model_accessor)
-        url = 'http://%s:%s/onos/v1/network/configuration/devices/%s' % (
-            onos.rest_hostname, onos.rest_port, model.ofId)
-
+        onos = Helpers.get_onos(model, self.model_accessor)
+        url = 'http://%s:%s/onos/v1/network/configuration/devices/%s' % (onos.rest_hostname, onos.rest_port, model.ofId)
         r = requests.delete(url, auth=HTTPBasicAuth(onos.rest_username, onos.rest_password))
-
         if r.status_code != 204:
             log.error(r.text)
             raise Exception("Failed to remove switch %s from ONOS" % model.name)