CORD-1008 Dockerfile and docker-compose for vtn synchronizer

Change-Id: Ia6624c199624fcb9d497da1326220353c5d2614b
diff --git a/xos/synchronizer/Dockerfile.synchronizer b/xos/synchronizer/Dockerfile.synchronizer
new file mode 100644
index 0000000..2ce888a
--- /dev/null
+++ b/xos/synchronizer/Dockerfile.synchronizer
@@ -0,0 +1,13 @@
+FROM xosproject/xos-synchronizer-base
+
+ADD . /opt/xos/synchronizers/vtn
+
+ADD __init__.py /opt/xos/services/__init__.py
+ADD __init__.py /opt/xos/services/vtn/__init__.py
+ADD tmp.vtnnetport.py /opt/xos/services/vtn/vtnnetport.py
+
+ENTRYPOINT []
+
+WORKDIR "/opt/xos/synchronizers/vtn"
+
+CMD bash -c "cd /opt/xos/synchronizers/vtn; ./run-from-api.sh"
diff --git a/xos/synchronizer/Makefile b/xos/synchronizer/Makefile
new file mode 100644
index 0000000..a07b843
--- /dev/null
+++ b/xos/synchronizer/Makefile
@@ -0,0 +1,6 @@
+synchronizer:
+	cp ../vtnnetport.py tmp.vtnnetport.py
+	sudo docker build --rm -f Dockerfile.synchronizer -t xosproject/vtn-synchronizer .
+
+up:
+	docker-compose -p vtn up -d
diff --git a/xos/synchronizer/__init__.py b/xos/synchronizer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xos/synchronizer/__init__.py
diff --git a/xos/synchronizer/docker-compose.yml b/xos/synchronizer/docker-compose.yml
new file mode 100644
index 0000000..bc7500a
--- /dev/null
+++ b/xos/synchronizer/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '2'
+
+networks:
+  xos:
+    external: true
+
+services:
+  synchronizer:
+    image: xosproject/vtn-synchronizer
+    networks:
+      - xos
+    #command: bash -c "sleep 86400"
+    volumes:
+        - /opt/cord_profile/key_import/vtn_rsa:/opt/xos/services/vtn/keys/vtn_rsa:ro
+        - /opt/cord_profile/node_key:/opt/cord_profile/node_key:ro
+        - /opt/cord/build/platform-install/credentials/xosadmin@opencord.org:/opt/xos/services/vtn/credentials/xosadmin@opencord.org
+    external_links: 
+        - rcordbs_xos_redis_1:redis
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "1000k"
+        max-file: "5"
diff --git a/xos/synchronizer/run-from-api.sh b/xos/synchronizer/run-from-api.sh
new file mode 100755
index 0000000..4744fc4
--- /dev/null
+++ b/xos/synchronizer/run-from-api.sh
@@ -0,0 +1,2 @@
+export XOS_DIR=/opt/xos
+python vtn-synchronizer.py  -C $XOS_DIR/synchronizers/vtn/vtn_from_api_config
diff --git a/xos/synchronizer/steps/sync_onos_netcfg.py b/xos/synchronizer/steps/sync_onos_netcfg.py
index b6f427d..056c1be 100644
--- a/xos/synchronizer/steps/sync_onos_netcfg.py
+++ b/xos/synchronizer/steps/sync_onos_netcfg.py
@@ -27,7 +27,9 @@
             self.call()
 
     def get_node_tag(self, node, tagname):
-        tags = Tag.select_by_content_object(node).filter(name=tagname)
+        tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(node),
+                                  object_id=node.id,
+                                  name=tagname)
         return tags[0].value
 
     def get_tenants_who_want_config(self):
@@ -41,7 +43,7 @@
         return tenants
 
     def save_tenant_attribute(self, tenant, name, value):
-        tas = TenantAttribute.objects.filter(tenant=tenant, name=name)
+        tas = TenantAttribute.objects.filter(tenant_id=tenant.id, name=name)
         if tas:
             ta = tas[0]
             if ta.value != value:
@@ -145,10 +147,8 @@
 
         # Generate apps->org.onosproject.cordvtn->cordvtn->publicGateways
         # Pull the gateway information from vRouter
-        try:
-            from services.vrouter.models import VRouterService
-
-            vrouters = VRouterService.get_service_objects().all()
+        if model_accessor.has_model_class("VRouterService"):
+            vrouters = VRouterService.objects.all()
             if vrouters:
                 for gateway in vrouters[0].get_gateways():
                     gatewayIp = gateway['gateway_ip'].split('/',1)[0]
@@ -158,13 +158,13 @@
                         "gatewayMac": gatewayMac
                     }
                     data["apps"]["org.opencord.vtn"]["cordvtn"]["publicGateways"].append(gateway_dict)
-        except:
+        else:
             logger.info("No VRouter service present, not adding publicGateways to config")
 
         return json.dumps(data, indent=4, sort_keys=True)
 
     def call(self, **args):
-        vtn_service = VTNService.get_service_objects().all()
+        vtn_service = VTNService.objects.all()
         if not vtn_service:
             raise Exception("No VTN Service")
 
diff --git a/xos/synchronizer/steps/sync_port_addresses.py b/xos/synchronizer/steps/sync_port_addresses.py
index 57de70b..029755b 100644
--- a/xos/synchronizer/steps/sync_port_addresses.py
+++ b/xos/synchronizer/steps/sync_port_addresses.py
@@ -10,6 +10,8 @@
 
 logger = Logger(level=logging.INFO)
 
+# TODO: This file seems obsolete -- evaluate for deletion.
+
 # XXX should save and load this
 glo_saved_vtn_maps = []
 
diff --git a/xos/synchronizer/steps/sync_vtn_service.py b/xos/synchronizer/steps/sync_vtn_service.py
index 44e29d7..6db26f8 100644
--- a/xos/synchronizer/steps/sync_vtn_service.py
+++ b/xos/synchronizer/steps/sync_vtn_service.py
@@ -212,7 +212,7 @@
                     logger.error("Received error from vtn service (%d)" % r.status_code)
 
     def call(self, **args):
-        vtn_service = VTNService.get_service_objects().all()
+        vtn_service = VTNService.objects.all()
         if not vtn_service:
             raise Exception("No VTN Service")
 
diff --git a/xos/synchronizer/vtn_from_api_config b/xos/synchronizer/vtn_from_api_config
new file mode 100644
index 0000000..ed8289c
--- /dev/null
+++ b/xos/synchronizer/vtn_from_api_config
@@ -0,0 +1,20 @@
+# Sets options for the synchronizer
+[observer]
+name=vtn
+dependency_graph=/opt/xos/synchronizers/vtn/model-deps
+steps_dir=/opt/xos/synchronizers/vtn/steps
+sys_dir=/opt/xos/synchronizers/vtn/sys
+#logfile=/var/log/xos_backend.log
+log_file=console
+log_level=debug
+pretend=False
+backoff_disabled=True
+save_ansible_output=True
+proxy_ssh=True
+proxy_ssh_key=/opt/cord_profile/node_key
+proxy_ssh_user=root
+accessor_kind=api
+accessor_password=@/opt/xos/services/vtn/credentials/xosadmin@opencord.org
+
+[networking]
+use_vtn=True
diff --git a/xos/vtnnetport.py b/xos/vtnnetport.py
index 0268733..e1c15bb 100644
--- a/xos/vtnnetport.py
+++ b/xos/vtnnetport.py
@@ -1,5 +1,19 @@
-from core.models import *
-from services.vtn.models import VTNService
+# This library can be used in two different contexts:
+#    1) From the VTN synchronizer
+#    2) From the handcrafted VTN API endpoint
+#
+# If (1) then the modelaccessor module can provide us with models from the API
+# or django as appropriate. If (2) then we must use django, until we can
+# reconcile what to do about handcrafted API endpoints
+
+import __main__ as main_program
+
+if "synchronizer" in main_program.__file__:
+    from synchronizers.new_base.modelaccessor import *
+    in_synchronizer = True
+else:
+    from core.models import *
+    in_synchronizer = False
 
 VTN_SERVCOMP_KINDS=["PRIVATE","VSG"]
 
@@ -132,29 +146,45 @@
 
     def get_vsg_tenants(self):
         # If the VSG service isn't onboarded, then return an empty list.
-        try:
-            from services.vsg.models import VSGTenant
-            vsg_tenants=[]
-            for tenant in VSGTenant.get_tenant_objects().all():
-                if tenant.instance == self.xos_port.instance:
-                    vsg_tenants.append(tenant)
-            return vsg_tenants
-        except ImportError:
-            # TODO: Set up logging for this library...
-            print "Failed to import VSG, returning no tenants"
-            return []
+        if (in_synchronizer):
+            if not model_accessor.has_model_class("VSGTenant"):
+                 print "VSGTenant model does not exist. Returning no tenants"
+                 return []
+            VSGTenant = model_accessor.get_model_class("VSGTenant")   # suppress undefined local variable error
+        else:
+            try:
+                from services.vsg.models import VSGTenant
+            except ImportError:
+                # TODO: Set up logging for this library...
+                print "Failed to import VSG, returning no tenants"
+                return []
+
+        vsg_tenants=[]
+        for tenant in VSGTenant.objects.all():
+            if tenant.instance.id == self.xos_port.instance.id:
+                vsg_tenants.append(tenant)
+        return vsg_tenants
 
     @property
     def vlan_id(self):
         if not self.xos_port.instance:
             return None
+
         # Only some kinds of networks can have s-tags associated with them.
         # Currently, only VSG access networks qualify.
         if not self.xos_port.network.template.vtn_kind in ["VSG",]:
             return None
-        tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag")
+
+        if (in_synchronizer):
+            tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(self.xos_port.instance),
+                                      object_id=self.xos_port.instance.id,
+                                      name="s_tag")
+        else:
+            tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag")
+
         if not tags:
             return None
+
         return tags[0].value
 
     @property