Revert "Delete observers dir"

This reverts commit 7c5e0cae8320fa42c5127eea2ea3acf0e3a596ce.
diff --git a/xos/observers/vbng/model-deps b/xos/observers/vbng/model-deps
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/xos/observers/vbng/model-deps
@@ -0,0 +1 @@
+{}
diff --git a/xos/observers/vbng/run.sh b/xos/observers/vbng/run.sh
new file mode 100755
index 0000000..efb586f
--- /dev/null
+++ b/xos/observers/vbng/run.sh
@@ -0,0 +1,6 @@
+#if [[ ! -e ./vbng-observer.py ]]; then
+#    ln -s ../../xos-observer.py vbng-observer.py
+#fi
+
+export XOS_DIR=/opt/xos
+python vbng-observer.py  -C $XOS_DIR/observers/vbng/vbng_observer_config
diff --git a/xos/observers/vbng/start.sh b/xos/observers/vbng/start.sh
new file mode 100755
index 0000000..98008f4
--- /dev/null
+++ b/xos/observers/vbng/start.sh
@@ -0,0 +1,6 @@
+#if [[ ! -e ./vbng-observer.py ]]; then
+#    ln -s ../../xos-observer.py vbng-observer.py
+#fi
+
+export XOS_DIR=/opt/xos
+nohup python vbng-observer.py  -C $XOS_DIR/observers/vbng/vbng_observer_config > /dev/null 2>&1 &
diff --git a/xos/observers/vbng/steps/sync_vbngtenant.py b/xos/observers/vbng/steps/sync_vbngtenant.py
new file mode 100644
index 0000000..c997f4f
--- /dev/null
+++ b/xos/observers/vbng/steps/sync_vbngtenant.py
@@ -0,0 +1,142 @@
+import os
+import requests
+import socket
+import sys
+import base64
+from django.db.models import F, Q
+from xos.config import Config
+from synchronizers.base.syncstep import SyncStep
+from synchronizers.base.ansible import run_template_ssh
+from core.models import Service
+from services.cord.models import VCPEService, VCPETenant, VBNGTenant, VBNGService
+from services.hpc.models import HpcService, CDNPrefix
+from util.logger import Logger, logging
+
+# VBNG_API = "http://10.0.3.136:8181/onos/virtualbng/privateip/"
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+class SyncVBNGTenant(SyncStep):
+    provides=[VCPETenant]
+    observes=VCPETenant
+    requested_interval=0
+
+    def __init__(self, **args):
+        SyncStep.__init__(self, **args)
+
+    def fetch_pending(self, deleted):
+        if (not deleted):
+            objs = VBNGTenant.get_tenant_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+        else:
+            objs = VBNGTenant.get_deleted_tenant_objects()
+
+        return objs
+
+    def defer_sync(self, o, reason):
+        logger.info("defer object %s due to %s" % (str(o), reason))
+        raise Exception("defer object %s due to %s" % (str(o), reason))
+
+    def get_vbng_service(self, o):
+        if not o.provider_service:
+             raise Exception("vBNG tenant %s has no provider_service" % str(o.id))
+        services = VBNGService.get_service_objects().filter(id = o.provider_service.id)
+        if not services:
+             raise Exception("vBNG tenant %s is associated with the wrong kind of provider_service" % str(o.id))
+        return services[0]
+
+    def get_vbng_url(self, o):
+        service = self.get_vbng_service(o)
+
+        # if the service object specifies a vbng_url, then use it
+        if service.vbng_url:
+            return service.vbng_url
+
+        # otherwise, see if the service has tenancy in ONOS
+        for tenant in service.subscribed_tenants.all():
+            if tenant.provider_service and tenant.provider_service.kind == "onos":
+                onos_service = tenant.provider_service
+                if not onos_service.slices.exists():
+                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service has no slices")
+                onos_slice = onos_service.slices.all()[0]
+                if not onos_slice.instances.exists():
+                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice has no instances")
+                instance = onos_slice.instances.all()[0]
+
+                #onos_app = ONOSApp.objects.filter(id = tenant.id)
+                #instance = onos_app.instance
+                #if not instance:
+                #    raise Exception("ONOSApp has no instance")
+
+                if not instance.instance_name:
+                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice's first instance is not instantiated")
+                ip = instance.get_network_ip("nat")
+                if not ip:
+                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice's first instance does not have an ip")
+
+                logger.info("Using ip %s from ONOS Instance %s" % (ip, instance))
+
+                return "http://%s:8181/onos/virtualbng/" % ip
+
+        raise Exception("vBNG service does not have vbng_url set, and is not linked to an ONOSApp")
+
+    def get_private_interface(self, o):
+        vcpes = VCPETenant.get_tenant_objects().all()
+        vcpes = [x for x in vcpes if (x.vbng is not None) and (x.vbng.id == o.id)]
+        if not vcpes:
+            raise Exception("No vCPE tenant is associated with vBNG %s" % str(o.id))
+        if len(vcpes)>1:
+            raise Exception("More than one vCPE tenant is associated with vBNG %s" % str(o.id))
+
+        vcpe = vcpes[0]
+        instance = vcpe.instance
+
+        if not instance:
+            raise Exception("No instance associated with vBNG %s" % str(o.id))
+
+        if not vcpe.wan_ip:
+            self.defer_sync(o, "does not have a WAN IP yet")
+
+        if not vcpe.wan_container_mac:
+            # this should never happen; container MAC is computed from WAN IP
+            self.defer_sync(o, "does not have a WAN container MAC yet")
+
+        return (vcpe.wan_ip, vcpe.wan_container_mac, vcpe.instance.node.name)
+
+    def sync_record(self, o):
+        logger.info("sync'ing VBNGTenant %s" % str(o))
+
+        if not o.routeable_subnet:
+            (private_ip, private_mac, private_hostname) = self.get_private_interface(o)
+            logger.info("contacting vBNG service to request mapping for private ip %s mac %s host %s" % (private_ip, private_mac, private_hostname) )
+
+            url = self.get_vbng_url(o) + "privateip/%s/%s/%s" % (private_ip, private_mac, private_hostname)
+            logger.info( "vbng url: %s" % url )
+            r = requests.post(url )
+            if (r.status_code != 200):
+                raise Exception("Received error from bng service (%d)" % r.status_code)
+            logger.info("received public IP %s from private IP %s" % (r.text, private_ip))
+
+            if r.text == "0":
+                raise Exception("VBNG service failed to return a routeable_subnet (probably ran out)")
+
+            o.routeable_subnet = r.text
+            o.mapped_ip = private_ip
+            o.mapped_mac = private_mac
+            o.mapped_hostname = private_hostname
+
+        o.save()
+
+    def delete_record(self, o):
+        logger.info("deleting VBNGTenant %s" % str(o))
+
+        if o.mapped_ip:
+            private_ip = o.mapped_ip
+            logger.info("contacting vBNG service to delete private ip %s" % private_ip)
+            r = requests.delete(self.get_vbng_url(o) + "privateip/%s" % private_ip, )
+            if (r.status_code != 200):
+                raise Exception("Received error from bng service (%d)" % r.status_code)
+
diff --git a/xos/observers/vbng/stop.sh b/xos/observers/vbng/stop.sh
new file mode 100755
index 0000000..d49591e
--- /dev/null
+++ b/xos/observers/vbng/stop.sh
@@ -0,0 +1 @@
+pkill -9 -f vbng-observer.py
diff --git a/xos/observers/vbng/supervisor/vbng-observer.conf b/xos/observers/vbng/supervisor/vbng-observer.conf
new file mode 100644
index 0000000..cff77b8
--- /dev/null
+++ b/xos/observers/vbng/supervisor/vbng-observer.conf
@@ -0,0 +1,2 @@
+[program:vbng-observer]
+command=python /opt/xos/observers/vbng/vbng-observer.py -C /opt/xos/observers/vbng/vbng_observer_config
diff --git a/xos/observers/vbng/vbng-observer.py b/xos/observers/vbng/vbng-observer.py
new file mode 100755
index 0000000..d6a71ff
--- /dev/null
+++ b/xos/observers/vbng/vbng-observer.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+# This imports and runs ../../xos-observer.py
+
+import importlib
+import os
+import sys
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+sys.path.append(observer_path)
+mod = importlib.import_module("xos-observer")
+mod.main()
diff --git a/xos/observers/vbng/vbng_observer_config b/xos/observers/vbng/vbng_observer_config
new file mode 100644
index 0000000..b75d498
--- /dev/null
+++ b/xos/observers/vbng/vbng_observer_config
@@ -0,0 +1,38 @@
+
+[plc]
+name=plc
+deployment=VICCI
+
+[db]
+name=xos
+user=postgres
+password=password
+host=localhost
+port=5432
+
+[api]
+host=128.112.171.237
+port=8000
+ssl_key=None
+ssl_cert=None
+ca_ssl_cert=None
+ratelimit_enabled=0
+omf_enabled=0
+mail_support_address=support@localhost
+nova_enabled=True
+
+[observer]
+name=vbng
+dependency_graph=/opt/xos/observers/vbng/model-deps
+steps_dir=/opt/xos/observers/vbng/steps
+sys_dir=/opt/xos/observers/vbng/sys
+deleters_dir=/opt/xos/observers/vbng/deleters
+log_file=console
+#/var/log/hpc.log
+driver=None
+pretend=False
+backoff_disabled=True
+
+[feefie]
+client_id='vicci_dev_central'
+user_id='pl'