| import os |
| import json |
| import base64 |
| from django.db.models import F, Q |
| from planetstack.config import Config |
| from ec2_observer.syncstep import SyncStep |
| from core.models.sliver import Sliver |
| from core.models.slice import SlicePrivilege, SliceDeployments |
| from core.models.network import Network, NetworkSlice, NetworkDeployments |
| from util.logger import Logger, logging |
| from ec2_observer.awslib import * |
| from core.models.site import * |
| from core.models.slice import * |
| from ec2_observer.creds import * |
| import pdb |
| |
| logger = Logger(level=logging.INFO) |
| |
| class SyncSlivers(SyncStep): |
| provides=[Sliver] |
| requested_interval=0 |
| |
| def fetch_pending(self, deletion): |
| if deletion: |
| object_source = Sliver.deleted_objects |
| else: |
| object_source = Sliver.objects |
| |
| all_slivers = object_source.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) |
| my_slivers = [] |
| |
| for sliver in all_slivers: |
| sd = SliceDeployments.objects.filter(Q(slice=sliver.slice)) |
| if (sd): |
| if (sd.deployment.name=='Amazon EC2'): |
| my_slivers.append(sliver) |
| if (sliver.node.deployment.name=='Amazon EC2'): |
| my_slivers.append(sliver) |
| return my_slivers |
| |
| def delete_record(self, sliver): |
| user = sliver.creator |
| e = get_creds(user=user, site=user.site) |
| result = aws_run('ec2 terminate-instances --instance-ids=%s'%sliver.instance_id, env=e) |
| |
| def sync_record(self, sliver): |
| logger.info("sync'ing sliver:%s deployment:%s " % (sliver, sliver.node.deployment)) |
| |
| if not sliver.instance_id: |
| # public keys |
| slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice) |
| pubkeys = [sm.user.public_key for sm in slice_memberships if sm.user.public_key] |
| |
| if sliver.creator.public_key: |
| pubkeys.append(sliver.creator.public_key) |
| |
| if sliver.slice.creator.public_key: |
| pubkeys.append(sliver.slice.creator.public_key) |
| |
| # netowrks |
| # include all networks available to the slice and/or associated network templates |
| #nics = [] |
| #networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)] |
| #network_deployments = NetworkDeployments.objects.filter(network__in=networks, |
| #deployment=sliver.node.deployment) |
| # Gather private networks first. This includes networks with a template that has |
| # visibility = private and translation = none |
| #for network_deployment in network_deployments: |
| # if network_deployment.network.template.visibility == 'private' and \ |
| # network_deployment.network.template.translation == 'none': |
| # nics.append({'net-id': network_deployment.net_id}) |
| |
| # now include network template |
| #network_templates = [network.template.sharedNetworkName for network in networks \ |
| # if network.template.sharedNetworkName] |
| #for net in driver.shell.quantum.list_networks()['networks']: |
| # if net['name'] in network_templates: |
| # nics.append({'net-id': net['id']}) |
| # look up image id |
| |
| instance_type = sliver.node.name.rsplit('.',1)[0] |
| |
| # Bail out of we don't have a key |
| key_name = sliver.creator.email.lower().replace('@', 'AT').replace('.', '') |
| u = sliver.creator |
| s = u.site |
| e = get_creds(user=u, site=s) |
| key_sig = aws_run('ec2 describe-key-pairs', env=e) |
| ec2_keys = key_sig['KeyPairs'] |
| key_found = False |
| for key in ec2_keys: |
| if (key['KeyName']==key_name): |
| key_found = True |
| break |
| |
| if (not key_found): |
| # set backend_status |
| raise Exception('Will not sync sliver without key') |
| |
| image_id = sliver.image.path |
| instance_sig = aws_run('ec2 run-instances --image-id %s --instance-type %s --count 1 --key-name %s --placement AvailabilityZone=%s'%(image_id,instance_type,key_name,sliver.node.site.name), env=e) |
| sliver.instance_id = instance_sig['Instances'][0]['InstanceId'] |
| sliver.save() |
| state = instance_sig['Instances'][0]['State']['Code'] |
| if (state==16): |
| sliver.ip = instance_sig['Instances'][0]['PublicIpAddress'] |
| sliver.save() |
| else: |
| # This status message should go into backend_status |
| raise Exception('Waiting for instance to start') |
| else: |
| ret = aws_run('ec2 describe-instances --instance-ids %s'%sliver.instance_id, env=e) |
| state = ret['Reservations'][0]['Instances'][0]['State']['Code'] |
| if (state==16): |
| sliver.ip = ret['Reservations'][0]['Instances'][0]['PublicIpAddress'] |
| sliver.save() |
| |