ed75438b7d5331c440a180cced432e810ad5580f
[plstackapi.git] / planetstack / ec2_observer / steps / sync_slivers.py
1 import os
2 import json
3 import base64
4 from django.db.models import F, Q
5 from planetstack.config import Config
6 from ec2_observer.syncstep import SyncStep
7 from core.models.sliver import Sliver
8 from core.models.slice import SlicePrivilege, SliceDeployment
9 from core.models.network import Network, NetworkSlice, NetworkDeployments
10 from util.logger import Logger, logging
11 from ec2_observer.awslib import *
12 from core.models.site import *
13 from core.models.slice import *
14 from ec2_observer.creds import *
15 import pdb
16
17 logger = Logger(level=logging.INFO)
18
19 class SyncSlivers(SyncStep):
20     provides=[Sliver]
21     requested_interval=0
22
23     def fetch_pending(self, deletion):
24         if deletion:
25             object_source = Sliver.deleted_objects
26         else:
27             object_source = Sliver.objects
28
29         all_slivers = object_source.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
30         my_slivers = [] 
31
32         for sliver in all_slivers:
33             sd = SliceDeployment.objects.filter(Q(slice=sliver.slice))
34             if (sd):
35                 if (sd.deployment.name=='Amazon EC2'):
36                     my_slivers.append(sliver)
37             if (sliver.node.deployment.name=='Amazon EC2'):
38                 my_slivers.append(sliver)
39         return my_slivers
40
41     def delete_record(self, sliver):
42         user = sliver.creator
43         e = get_creds(user=user, site=user.site)
44         result = aws_run('ec2 terminate-instances --instance-ids=%s'%sliver.instance_id, env=e)
45
46     def sync_record(self, sliver):
47         logger.info("sync'ing sliver:%s deployment:%s " % (sliver, sliver.node.deployment))
48
49         if not sliver.instance_id:
50             # public keys
51             slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice)
52             pubkeys = [sm.user.public_key for sm in slice_memberships if sm.user.public_key]
53
54             if sliver.creator.public_key:
55                 pubkeys.append(sliver.creator.public_key)
56
57             if sliver.slice.creator.public_key:
58                 pubkeys.append(sliver.slice.creator.public_key) 
59
60             # netowrks
61             # include all networks available to the slice and/or associated network templates
62             #nics = []
63             #networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]  
64             #network_deployments = NetworkDeployments.objects.filter(network__in=networks, 
65                                                                     #deployment=sliver.node.deployment)
66             # Gather private networks first. This includes networks with a template that has
67             # visibility = private and translation = none
68             #for network_deployment in network_deployments:
69             #   if network_deployment.network.template.visibility == 'private' and \
70             #      network_deployment.network.template.translation == 'none': 
71             #       nics.append({'net-id': network_deployment.net_id})
72     
73             # now include network template
74             #network_templates = [network.template.sharedNetworkName for network in networks \
75             #                    if network.template.sharedNetworkName]
76             #for net in driver.shell.quantum.list_networks()['networks']:
77             #   if net['name'] in network_templates: 
78             #       nics.append({'net-id': net['id']}) 
79             # look up image id
80
81             instance_type = sliver.node.name.rsplit('.',1)[0]
82
83             # Bail out of we don't have a key
84             key_name = sliver.creator.email.lower().replace('@', 'AT').replace('.', '')
85             u = sliver.creator
86             s = u.site
87             e = get_creds(user=u, site=s)
88             key_sig = aws_run('ec2 describe-key-pairs', env=e)
89             ec2_keys = key_sig['KeyPairs']
90             key_found = False
91             for key in ec2_keys:
92                 if (key['KeyName']==key_name):
93                     key_found = True
94                     break
95
96             if (not key_found):
97                 # set backend_status
98                 raise Exception('Will not sync sliver without key')
99
100             image_id = sliver.image.path
101             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)
102             sliver.instance_id = instance_sig['Instances'][0]['InstanceId']
103             sliver.save()
104             state = instance_sig['Instances'][0]['State']['Code']
105             if (state==16):
106                 sliver.ip = instance_sig['Instances'][0]['PublicIpAddress']
107                 sliver.save()
108             else:
109                 # This status message should go into backend_status
110                 raise Exception('Waiting for instance to start')
111         else:
112             ret = aws_run('ec2 describe-instances --instance-ids %s'%sliver.instance_id, env=e)
113             state = ret['Reservations'][0]['Instances'][0]['State']['Code']
114             if (state==16):
115                 sliver.ip = ret['Reservations'][0]['Instances'][0]['PublicIpAddress']
116                 sliver.save()
117