WIP: vcpe observers
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.py b/xos/observers/vcpe/steps/sync_vcpetenant.py
new file mode 100644
index 0000000..cc1d520
--- /dev/null
+++ b/xos/observers/vcpe/steps/sync_vcpetenant.py
@@ -0,0 +1,111 @@
+import os
+import socket
+import sys
+import base64
+from django.db.models import F, Q
+from xos.config import Config
+from observer.syncstep import SyncStep
+from observer.ansible import run_template_ssh
+from core.models import Service
+from cord.models import VCPEService, VCPETenant, VOLTTenant
+from hpc.models import HpcService, CDNPrefix
+from util.logger import Logger, logging
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+class SyncVCPETenant(SyncStep):
+ provides=[VCPETenant]
+ observes=VCPETenant
+ requested_interval=0
+ template_name = "sync_vcpetenant.yaml"
+ service_key_name = "/opt/xos/observers/vcpe/vcpe_private_key"
+
+ def __init__(self, **args):
+ SyncStep.__init__(self, **args)
+
+ def defer_sync(self, o, reason):
+ o.backend_register="{}"
+ o.backend_status = "2 - " + reason
+ o.save(update_fields=['enacted','backend_status','backend_register'])
+ logger.info("defer object %s due to %s" % (str(o), reason))
+
+ def fetch_pending(self, deleted):
+ if (not deleted):
+ objs = VCPETenant.get_tenant_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+ else:
+ objs = VCPETenant.get_deleted_tenant_objects()
+
+ return objs
+
+ def get_extra_attributes(self, o):
+ # This is a place to include extra attributes that aren't part of the
+ # object itself. In our case, it's handy to know the VLAN IDs when
+ # configuring the VCPE.
+
+ dnsdemux_ip = "none"
+ for service in HpcService.objects.all():
+ for slice in service.slices.all():
+ if "dnsdemux" in slice.name:
+ for sliver in slice.slivers.all():
+ if dnsdemux_ip=="none":
+ try:
+ dnsdemux_ip = socket.gethostbyname(sliver.node.name)
+ except:
+ pass
+
+ volts = [x for x in VOLTTenant.get_tenant_objects() if x.vcpe.id==o.id]
+ vlan_ids = [x.vlan_id for x in volts]
+ return {"vlan_ids": vlan_ids,
+ "dnsdemux_ip": dnsdemux_ip}
+
+ def get_sliver(self, o):
+ # We need to know what slivers is associated with the object.
+ # For vCPE this is easy, as VCPETenant has a sliver field.
+
+ return o.sliver
+
+ def sync_record(self, o):
+ logger.info("sync'ing VCPETenant %s" % str(o))
+
+ sliver = self.get_sliver(o)
+ if not sliver:
+ self.defer_sync(o, "waiting on sliver")
+ return
+
+ service = o.sliver.slice.service
+ if not service:
+ # Ansible uses the service's keypair in order to SSH into the
+ # instance. It would be bad if the slice had no service.
+
+ raise Exception("Slice %s is not associated with a service" % sliver.slice.name)
+
+ if not os.path.exists(self.service_key_name):
+ raise Exception("Service key %s does not exist" % self.service_key_name)
+
+ service_key = file(self.service_key_name).read()
+
+ fields = { "sliver_name": sliver.name,
+ "hostname": sliver.node.name,
+ "instance_id": sliver.instance_id,
+ "private_key": service_key,
+ }
+
+ if hasattr(o, "sync_attributes"):
+ for attribute_name in o.sync_attributes:
+ fields[attribute_name] = getattr(o, attribute_name)
+
+ fields.update(self.get_extra_attributes(o))
+
+ print fields
+
+ run_template_ssh(self.template_name, fields)
+
+ o.save()
+
+ def delete_record(self, m):
+ pass
+
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.yaml b/xos/observers/vcpe/steps/sync_vcpetenant.yaml
new file mode 100644
index 0000000..99ab4bb
--- /dev/null
+++ b/xos/observers/vcpe/steps/sync_vcpetenant.yaml
@@ -0,0 +1,19 @@
+---
+- hosts: {{ sliver_name }}
+ connection: ssh
+ user: ubuntu
+ sudo: yes
+ vars:
+ cdn_enable: {{ cdn_enable }}
+ dnsdemux_ip: {{ dnsdemux_ip }}
+ firewall_enable: {{ firewall_enable }}
+ url_filter_enable: {{ url_filter_enable }}
+ tasks:
+ - name: make sure /etc/dnsmasq.d exists
+ file: path=/etc/dnsmasq.d state=directory owner=root group=root
+
+ - name: configure dnsmasq servers
+ template: src=/opt/xos/observers/vcpe/templates/dnsmasq_servers.j2 dest=/etc/dnsmasq.d/servers.conf owner=root group=root
+
+ - name: setup networking
+ template: src=/opt/xos/observers/vcpe/templates/vlan_sample.j2 dest=/etc/vlan_sample owner=root group=root
diff --git a/xos/observers/vcpe/templates/dnsmasq_servers.j2 b/xos/observers/vcpe/templates/dnsmasq_servers.j2
new file mode 100644
index 0000000..ac97035
--- /dev/null
+++ b/xos/observers/vcpe/templates/dnsmasq_servers.j2
@@ -0,0 +1,15 @@
+# This file autogenerated by vCPE observer
+# It contains a list of DNS servers for dnsmasq to use.
+
+{% if cdn_enable %}
+# CDN
+server=/foo.com/{{ dnsdemux_ip }}
+{% endif %}
+
+{% if url_filter_enable %}
+# placeholder; figure out what to really use...
+server=dns.xerocole.com
+{% else %}
+# use google's DNS service
+server=8.8.8.8
+{% endif %}
diff --git a/xos/observers/vcpe/templates/vlan_sample.j2 b/xos/observers/vcpe/templates/vlan_sample.j2
new file mode 100644
index 0000000..48cdce8
--- /dev/null
+++ b/xos/observers/vcpe/templates/vlan_sample.j2
@@ -0,0 +1 @@
+placeholder