| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 1 | import hashlib |
| 2 | import os |
| 3 | import socket |
| 4 | import sys |
| 5 | import base64 |
| 6 | import time |
| 7 | from django.db.models import F, Q |
| 8 | from xos.config import Config |
| Sapan Bhatia | 16be143 | 2016-01-14 11:41:38 -0500 | [diff] [blame] | 9 | from synchronizers.base.syncstep import SyncStep |
| 10 | from synchronizers.base.ansible import run_template_ssh |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 11 | from core.models import Service, Slice |
| 12 | from util.logger import Logger, logging |
| 13 | |
| 14 | logger = Logger(level=logging.INFO) |
| 15 | |
| Tony Mack | d851547 | 2015-08-19 11:58:18 -0400 | [diff] [blame] | 16 | class SyncInstanceUsingAnsible(SyncStep): |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 17 | # All of the following should be defined for classes derived from this |
| 18 | # base class. Examples below use VCPETenant. |
| 19 | |
| 20 | # provides=[VCPETenant] |
| 21 | # observes=VCPETenant |
| 22 | # requested_interval=0 |
| 23 | # template_name = "sync_vcpetenant.yaml" |
| 24 | # service_key_name = "/opt/xos/observers/vcpe/vcpe_private_key" |
| 25 | |
| 26 | def __init__(self, **args): |
| 27 | SyncStep.__init__(self, **args) |
| 28 | |
| 29 | def defer_sync(self, o, reason): |
| 30 | logger.info("defer object %s due to %s" % (str(o), reason)) |
| 31 | raise Exception("defer object %s due to %s" % (str(o), reason)) |
| 32 | |
| 33 | def get_extra_attributes(self, o): |
| 34 | # This is a place to include extra attributes that aren't part of the |
| 35 | # object itself. |
| 36 | |
| 37 | return {} |
| 38 | |
| Tony Mack | d851547 | 2015-08-19 11:58:18 -0400 | [diff] [blame] | 39 | def get_instance(self, o): |
| 40 | # We need to know what instance is associated with the object. Let's |
| 41 | # assume 'o' has a field called 'instance'. If the field is called |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 42 | # something else, or if custom logic is needed, then override this |
| 43 | # method. |
| 44 | |
| Tony Mack | d851547 | 2015-08-19 11:58:18 -0400 | [diff] [blame] | 45 | return o.instance |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 46 | |
| 47 | def run_playbook(self, o, fields): |
| 48 | tStart = time.time() |
| 49 | run_template_ssh(self.template_name, fields) |
| 50 | logger.info("playbook execution time %d" % int(time.time()-tStart)) |
| 51 | |
| 52 | def pre_sync_hook(self, o, fields): |
| 53 | pass |
| 54 | |
| 55 | def post_sync_hook(self, o, fields): |
| 56 | pass |
| 57 | |
| 58 | def sync_fields(self, o, fields): |
| 59 | self.run_playbook(o, fields) |
| 60 | |
| 61 | def sync_record(self, o): |
| 62 | logger.info("sync'ing object %s" % str(o)) |
| 63 | |
| Tony Mack | d851547 | 2015-08-19 11:58:18 -0400 | [diff] [blame] | 64 | instance = self.get_instance(o) |
| 65 | if not instance: |
| 66 | self.defer_sync(o, "waiting on instance") |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 67 | return |
| 68 | |
| 69 | if not os.path.exists(self.service_key_name): |
| 70 | raise Exception("Service key %s does not exist" % self.service_key_name) |
| 71 | |
| 72 | service_key = file(self.service_key_name).read() |
| 73 | |
| Tony Mack | d851547 | 2015-08-19 11:58:18 -0400 | [diff] [blame] | 74 | fields = { "instance_name": instance.name, |
| 75 | "hostname": instance.node.name, |
| 76 | "instance_id": instance.instance_id, |
| Scott Baker | 39b8c2c | 2015-07-21 11:10:13 -0700 | [diff] [blame] | 77 | "private_key": service_key, |
| 78 | "ansible_tag": "vcpe_tenant_" + str(o.id) |
| 79 | } |
| 80 | |
| 81 | # If 'o' defines a 'sync_attributes' list, then we'll copy those |
| 82 | # attributes into the Ansible recipe's field list automatically. |
| 83 | if hasattr(o, "sync_attributes"): |
| 84 | for attribute_name in o.sync_attributes: |
| 85 | fields[attribute_name] = getattr(o, attribute_name) |
| 86 | |
| 87 | fields.update(self.get_extra_attributes(o)) |
| 88 | |
| 89 | self.sync_fields(o, fields) |
| 90 | |
| 91 | o.save() |
| 92 | |
| 93 | def delete_record(self, m): |
| 94 | pass |
| 95 | |