blob: d6c6b844bf2a762e99d6957757d2b31464bec415 [file] [log] [blame]
Scott Baker64b889b2015-05-05 17:53:12 -07001import os
2import socket
3import sys
4import base64
Scott Baker3145da12015-06-09 12:03:07 -07005import time
Scott Baker64b889b2015-05-05 17:53:12 -07006from django.db.models import F, Q
7from xos.config import Config
8from observer.syncstep import SyncStep
9from observer.ansible import run_template_ssh
10from core.models import Service
11from cord.models import VCPEService, VCPETenant, VOLTTenant
12from hpc.models import HpcService, CDNPrefix
13from util.logger import Logger, logging
14
15# hpclibrary will be in steps/..
16parentdir = os.path.join(os.path.dirname(__file__),"..")
17sys.path.insert(0,parentdir)
18
Scott Bakercdf47142015-06-01 16:15:42 -070019from broadbandshield import BBS
20
Scott Baker64b889b2015-05-05 17:53:12 -070021logger = Logger(level=logging.INFO)
22
23class SyncVCPETenant(SyncStep):
24 provides=[VCPETenant]
25 observes=VCPETenant
26 requested_interval=0
27 template_name = "sync_vcpetenant.yaml"
28 service_key_name = "/opt/xos/observers/vcpe/vcpe_private_key"
29
30 def __init__(self, **args):
31 SyncStep.__init__(self, **args)
32
33 def defer_sync(self, o, reason):
Scott Baker61c8e8d2015-06-02 14:34:04 -070034 logger.info("defer object %s due to %s" % (str(o), reason))
Scott Baker59e88d52015-06-02 09:48:47 -070035 raise Exception("defer object %s due to %s" % (str(o), reason))
Scott Baker64b889b2015-05-05 17:53:12 -070036
37 def fetch_pending(self, deleted):
38 if (not deleted):
39 objs = VCPETenant.get_tenant_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
40 else:
41 objs = VCPETenant.get_deleted_tenant_objects()
42
43 return objs
44
45 def get_extra_attributes(self, o):
46 # This is a place to include extra attributes that aren't part of the
47 # object itself. In our case, it's handy to know the VLAN IDs when
48 # configuring the VCPE.
49
50 dnsdemux_ip = "none"
51 for service in HpcService.objects.all():
52 for slice in service.slices.all():
53 if "dnsdemux" in slice.name:
54 for sliver in slice.slivers.all():
Scott Baker4d5d5d72015-06-05 12:09:36 -070055 # Connect to a dnsdemux that's on the hpc_client network
56 # if one is available.
57 for ns in sliver.networkslivers.all():
58 if ns.ip and ns.network.labels and ("hpc_client" in ns.network.labels):
59 dnsdemux_ip = ns.ip
Scott Baker64b889b2015-05-05 17:53:12 -070060 if dnsdemux_ip=="none":
61 try:
62 dnsdemux_ip = socket.gethostbyname(sliver.node.name)
63 except:
64 pass
65
Scott Baker2e64a3a2015-05-06 20:06:21 -070066 cdn_prefixes = []
67 for prefix in CDNPrefix.objects.all():
68 cdn_prefixes.append(prefix.prefix)
69
Scott Bakerf674e912015-05-08 10:56:13 -070070 volts = [x for x in VOLTTenant.get_tenant_objects() if (x.vcpe is not None) and (x.vcpe.id==o.id)]
Scott Baker64b889b2015-05-05 17:53:12 -070071 vlan_ids = [x.vlan_id for x in volts]
72 return {"vlan_ids": vlan_ids,
Scott Baker2e64a3a2015-05-06 20:06:21 -070073 "dnsdemux_ip": dnsdemux_ip,
74 "cdn_prefixes": cdn_prefixes}
Scott Baker64b889b2015-05-05 17:53:12 -070075
76 def get_sliver(self, o):
77 # We need to know what slivers is associated with the object.
78 # For vCPE this is easy, as VCPETenant has a sliver field.
79
80 return o.sliver
81
82 def sync_record(self, o):
83 logger.info("sync'ing VCPETenant %s" % str(o))
84
85 sliver = self.get_sliver(o)
86 if not sliver:
87 self.defer_sync(o, "waiting on sliver")
88 return
89
90 service = o.sliver.slice.service
91 if not service:
92 # Ansible uses the service's keypair in order to SSH into the
93 # instance. It would be bad if the slice had no service.
94
95 raise Exception("Slice %s is not associated with a service" % sliver.slice.name)
96
97 if not os.path.exists(self.service_key_name):
98 raise Exception("Service key %s does not exist" % self.service_key_name)
99
100 service_key = file(self.service_key_name).read()
101
102 fields = { "sliver_name": sliver.name,
103 "hostname": sliver.node.name,
104 "instance_id": sliver.instance_id,
105 "private_key": service_key,
Scott Baker83734052015-05-12 16:13:29 -0700106 "ansible_tag": "vcpe_tenant_" + str(o.id)
Scott Baker64b889b2015-05-05 17:53:12 -0700107 }
108
109 if hasattr(o, "sync_attributes"):
110 for attribute_name in o.sync_attributes:
111 fields[attribute_name] = getattr(o, attribute_name)
112
113 fields.update(self.get_extra_attributes(o))
Scott Baker3145da12015-06-09 12:03:07 -0700114 tStart = time.time()
Scott Baker64b889b2015-05-05 17:53:12 -0700115 run_template_ssh(self.template_name, fields)
Scott Baker3145da12015-06-09 12:03:07 -0700116 logger.info("playbook execution time %d" % int(time.time()-tStart))
Scott Baker64b889b2015-05-05 17:53:12 -0700117
Scott Bakercdf47142015-06-01 16:15:42 -0700118 if o.url_filter_enable:
Scott Bakercf155f42015-06-08 19:09:53 -0700119 if (str(o.service_specific_id) != "SYNCME"):
Scott Bakerdf877da2015-06-08 18:58:39 -0700120 # XXX FIXME
121 # Also fix the spot in cord/models.py
122 logger.info("skipping sync of URL filter for SSID %s" % str(o.service_specific_id))
123 else:
Scott Baker3145da12015-06-09 12:03:07 -0700124 tStart = time.time()
Scott Bakerdf877da2015-06-08 18:58:39 -0700125 bbs = BBS(o.bbs_account, "123")
126 bbs.sync(o.url_filter_level, o.users)
Scott Baker3145da12015-06-09 12:03:07 -0700127 logger.info("bbs update tiem %d" % int(time.time()-tStart))
Scott Bakercdf47142015-06-01 16:15:42 -0700128
Scott Baker64b889b2015-05-05 17:53:12 -0700129 o.save()
130
131 def delete_record(self, m):
132 pass
133