move over vtn services from XOS repo
diff --git a/xos/synchronizer/manifest b/xos/synchronizer/manifest
new file mode 100644
index 0000000..dccfcdc
--- /dev/null
+++ b/xos/synchronizer/manifest
@@ -0,0 +1,10 @@
+manifest
+vtn-synchronizer.py
+steps/sync_tenant.py
+steps/sync_port_addresses.py
+start.sh
+stop.sh
+model-deps
+supervisor/vtn-observer.conf
+run.sh
+vtn_synchronizer_config
diff --git a/xos/synchronizer/model-deps b/xos/synchronizer/model-deps
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/xos/synchronizer/model-deps
@@ -0,0 +1 @@
+{}
diff --git a/xos/synchronizer/run.sh b/xos/synchronizer/run.sh
new file mode 100755
index 0000000..000a563
--- /dev/null
+++ b/xos/synchronizer/run.sh
@@ -0,0 +1,2 @@
+export XOS_DIR=/opt/xos
+python vtn-synchronizer.py -C $XOS_DIR/synchronizers/vtn/vtn_synchronizer_config
diff --git a/xos/synchronizer/start.sh b/xos/synchronizer/start.sh
new file mode 100755
index 0000000..2c43440
--- /dev/null
+++ b/xos/synchronizer/start.sh
@@ -0,0 +1,2 @@
+export XOS_DIR=/opt/xos
+nohup python vtn-synchronizer.py -C $XOS_DIR/synchronizers/vtn/vtn_synchronizer_config > /dev/null 2>&1 &
diff --git a/xos/synchronizer/steps/sync_port_addresses.py b/xos/synchronizer/steps/sync_port_addresses.py
new file mode 100644
index 0000000..553df6f
--- /dev/null
+++ b/xos/synchronizer/steps/sync_port_addresses.py
@@ -0,0 +1,133 @@
+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 core.models import Service, Port, Controller, Tag, Tenant
+from core.models.service import COARSE_KIND
+from services.vsg.models import VSGTenant
+from xos.logger import Logger, logging
+from requests.auth import HTTPBasicAuth
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+# XXX should save and load this
+glo_saved_vtn_maps = []
+
+class SyncPortAddresses(SyncStep):
+ requested_interval = 0 # 3600
+ provides=[Port]
+ observes=Port
+
+ def __init__(self, **args):
+ SyncStep.__init__(self, **args)
+
+ def call(self, **args):
+ global glo_saved_vtn_maps
+
+ logger.info("sync'ing vsg tenant to port addresses")
+
+ # build up a dictionary of port-->[wan_addrs] mappings
+ port_addrs = {}
+ for vsg in VSGTenant.get_tenant_objects().all():
+ if not vsg.instance:
+ logger.info("skipping vsg %s because it has no instance" % vsg)
+
+ wan_ip = vsg.wan_container_ip
+ if not wan_ip:
+ logger.info("skipping vsg %s because it has no wan_container_ip" % vsg)
+
+ wan_mac = vsg.wan_container_mac
+ if not wan_mac:
+ logger.info("skipping vsg %s because it has no wan_container_mac" % vsg)
+
+ lan_network = vsg.get_lan_network(vsg.instance)
+ if not lan_network:
+ logger.info("skipping vsg %s because it has no lan_network" % vsg)
+
+ lan_port = Port.objects.filter(instance = vsg.instance, network=lan_network)
+ if not lan_port:
+ logger.info("skipping vsg %s because it has no lan_port" % vsg)
+ lan_port = lan_port[0]
+
+ if not lan_port.port_id:
+ logger.info("skipping vsg %s because its lan_port has no port_id" % vsg)
+
+ if not (lan_port.pk in port_addrs):
+ port_addrs[lan_port.pk] = []
+ entry = {"mac_address": wan_mac, "ip_address": wan_ip}
+ addr_pairs = port_addrs[lan_port.pk]
+ if not entry in addr_pairs:
+ addr_pairs.append(entry)
+
+ # now do the VM_WAN_IP from the instance
+ if vsg.instance:
+ wan_vm_ip = vsg.wan_vm_ip
+ wan_vm_mac = vsg.wan_vm_mac
+ entry = {"mac_address": wan_vm_mac, "ip_address": wan_vm_ip}
+ if not entry in addr_pairs:
+ addr_pairs.append(entry)
+
+ # Get all ports in all controllers
+ ports_by_id = {}
+ for controller in Controller.objects.all():
+ if not controller.admin_tenant:
+ logger.info("controller %s has no admin_tenant" % controller)
+ continue
+ try:
+ driver = self.driver.admin_driver(controller = controller)
+ ports = driver.shell.quantum.list_ports()["ports"]
+ except:
+ logger.log_exc("failed to get ports from controller %s" % controller)
+ continue
+
+ for port in ports:
+ ports_by_id[port["id"]] = port
+
+ for port_pk in port_addrs.keys():
+ port = Port.objects.get(pk=port_pk)
+ addr_pairs = port_addrs[port_pk]
+ neutron_port = ports_by_id.get(port.port_id,None)
+ if not neutron_port:
+ logger.info("failed to get neutron port for port %s" % port)
+ continue
+
+ ips = [x["ip_address"] for x in addr_pairs]
+
+ changed = False
+
+ # delete addresses in neutron that don't exist in XOS
+ aaps = neutron_port.get("allowed_address_pairs", [])
+ for aap in aaps[:]:
+ if not aap["ip_address"] in ips:
+ logger.info("removing address %s from port %s" % (aap["ip_address"], port))
+ aaps.remove(aap)
+ changed = True
+
+ aaps_ips = [x["ip_address"] for x in aaps]
+
+ # add addresses in XOS that don't exist in neutron
+ for addr in addr_pairs:
+ if not addr["ip_address"] in aaps_ips:
+ logger.info("adding address %s to port %s" % (addr, port))
+ aaps.append( addr )
+ aaps_ips.append(addr["ip_address"])
+ changed = True
+
+ if changed:
+ logger.info("updating port %s" % port)
+ driver.shell.quantum.update_port(port.port_id, {"port": {"allowed_address_pairs": aaps}})
+
+
+
+
+
+
+
diff --git a/xos/synchronizer/steps/sync_tenant.py b/xos/synchronizer/steps/sync_tenant.py
new file mode 100644
index 0000000..a0e6cdb
--- /dev/null
+++ b/xos/synchronizer/steps/sync_tenant.py
@@ -0,0 +1,94 @@
+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 core.models import Service, Tenant
+from core.models.service import COARSE_KIND
+from xos.logger import Logger, logging
+from requests.auth import HTTPBasicAuth
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+# XXX should save and load this
+glo_saved_vtn_maps = []
+
+class SyncTenant(SyncStep):
+ provides=[Tenant]
+ observes=Tenant
+ requested_interval=0
+
+ def __init__(self, **args):
+ SyncStep.__init__(self, **args)
+
+ def get_vtn_onos_service(self):
+# vtn_tenant = Tenant.objects.filter(name="VTN_ONOS_app") # XXX fixme - hardcoded
+# if not vtn_tenant:
+# raise "No VTN Onos App found"
+# vtn_tenant = vtn_tenant[0]
+#
+# vtn_service = vtn_tenant.provider_service
+ vtn_service = Service.objects.filter(name="service_ONOS_VTN") # XXX fixme - harcoded
+ if not vtn_service:
+ raise "No VTN Onos Service"
+
+ return vtn_service[0]
+
+ def get_vtn_addr(self):
+ vtn_service = self.get_vtn_onos_service()
+
+ if not vtn_service.slices.exists():
+ raise "VTN Service has no slices"
+
+ vtn_slice = vtn_service.slices.all()[0]
+
+ if not vtn_slice.instances.exists():
+ raise "VTN Slice has no instances"
+
+ vtn_instance = vtn_slice.instances.all()[0]
+
+ return vtn_instance.node.name
+
+ def call(self, **args):
+ global glo_saved_vtn_maps
+
+ logger.info("sync'ing vtn services")
+
+ vtn_maps = []
+ for service in Service.objects.all():
+ for id in service.get_vtn_src_ids():
+ dependencies = service.get_vtn_dependencies_ids()
+ if dependencies:
+ for dependency in dependencies:
+ vtn_maps.append( (id, dependency) )
+
+ for vtn_map in vtn_maps:
+ if not (vtn_map in glo_saved_vtn_maps):
+ # call vtn rest api to add map
+ url = "http://" + self.get_vtn_addr() + ":8181/onos/cordvtn/service-dependency/%s/%s" % (vtn_map[0], vtn_map[1])
+
+ print "POST %s" % url
+ r = requests.post(url, auth=HTTPBasicAuth('karaf', 'karaf') ) # XXX fixme - hardcoded auth
+ if (r.status_code != 200):
+ raise Exception("Received error from vtn service (%d)" % r.status_code)
+
+ for vtn_map in glo_saved_vtn_maps:
+ if not vtn_map in vtn_maps:
+ # call vtn rest api to delete map
+ url = "http://" + self.get_vtn_addr() + ":8181/onos/cordvtn/service-dependency/%s/%s" % (vtn_map[0],vtn_map[1])
+
+ print "DELETE %s" % url
+ r = requests.delete(url, auth=HTTPBasicAuth('karaf', 'karaf') ) # XXX fixme - hardcoded auth
+ if (r.status_code != 200):
+ raise Exception("Received error from vtn service (%d)" % r.status_code)
+
+ glo_saved_vtn_maps = vtn_maps
+ # TODO: save this
+
diff --git a/xos/synchronizer/stop.sh b/xos/synchronizer/stop.sh
new file mode 100755
index 0000000..7ff2b06
--- /dev/null
+++ b/xos/synchronizer/stop.sh
@@ -0,0 +1 @@
+pkill -9 -f vtn-synchronizer.py
diff --git a/xos/synchronizer/supervisor/vtn-observer.conf b/xos/synchronizer/supervisor/vtn-observer.conf
new file mode 100644
index 0000000..714afa7
--- /dev/null
+++ b/xos/synchronizer/supervisor/vtn-observer.conf
@@ -0,0 +1,2 @@
+[program:vtn-observer]
+command=python /opt/xos/observers/vbng/vtn-observer.py -C /opt/xos/observers/vbng/vtn_observer_config
diff --git a/xos/synchronizer/vtn-synchronizer.py b/xos/synchronizer/vtn-synchronizer.py
new file mode 100755
index 0000000..84bec4f
--- /dev/null
+++ b/xos/synchronizer/vtn-synchronizer.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__)),"../../synchronizers/base")
+sys.path.append(observer_path)
+mod = importlib.import_module("xos-synchronizer")
+mod.main()
diff --git a/xos/synchronizer/vtn_synchronizer_config b/xos/synchronizer/vtn_synchronizer_config
new file mode 100644
index 0000000..d931839
--- /dev/null
+++ b/xos/synchronizer/vtn_synchronizer_config
@@ -0,0 +1,44 @@
+
+[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=vtn
+dependency_graph=/opt/xos/synchronizers/vtn/model-deps
+steps_dir=/opt/xos/synchronizers/vtn/steps
+sys_dir=/opt/xos/synchronizers/vtn/sys
+deleters_dir=/opt/xos/synchronizers/vtn/deleters
+log_file=console
+#/var/log/hpc.log
+driver=openstack
+pretend=False
+backoff_disabled=True
+
+[nova]
+ca_ssl_cert=/etc/ssl/certs/ca-certificates.crt
+
+[feefie]
+client_id='vicci_dev_central'
+user_id='pl'
+
+[networking]
+use_vtn=True