Bug fixes to sync_slivers step
[plstackapi.git] / planetstack / openstack_observer / steps / sync_slivers.py
1 import os
2 import base64
3 from django.db.models import F, Q
4 from planetstack.config import Config
5 from observer.openstacksyncstep import OpenStackSyncStep
6 from core.models.sliver import Sliver
7 from core.models.slice import Slice, SlicePrivilege, SliceDeployments
8 from core.models.network import Network, NetworkSlice, NetworkDeployments
9 from util.logger import Logger, logging
10 from observer.ansible import *
11
12 logger = Logger(level=logging.INFO)
13
14 def escape(s):
15     s = s.replace('\n',r'\n').replace('"',r'\"')
16     return s
17     
18 class SyncSlivers(OpenStackSyncStep):
19     provides=[Sliver]
20     requested_interval=0
21
22     def get_userdata(self, sliver):
23         userdata = 'opencloud:\n   slicename: "%s"\n   hostname: "%s"\n' % (sliver.slice.name, sliver.node.name)
24         return userdata
25
26     def sync_record(self, sliver):
27         logger.info("sync'ing sliver:%s deployment:%s " % (sliver, sliver.node.deployment))
28
29         metadata_update = {}
30         if (sliver.numberCores):
31             metadata_update["cpu_cores"] = str(sliver.numberCores)
32
33         for tag in sliver.slice.tags.all():
34             if tag.name.startswith("sysctl-"):
35                 metadata_update[tag.name] = tag.value
36
37         # public keys
38         slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice)
39         pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
40         if sliver.creator.public_key:
41             pubkeys.add(sliver.creator.public_key)
42
43         if sliver.slice.creator.public_key:
44             pubkeys.add(sliver.slice.creator.public_key) 
45
46         nics = []
47         networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]   
48         network_deployments = NetworkDeployments.objects.filter(network__in=networks, 
49                                                                 deployment=sliver.node.deployment)
50
51         for network_deployment in network_deployments:
52             if network_deployment.network.template.visibility == 'private' and \
53                network_deployment.network.template.translation == 'none' and network_deployment.net_id: 
54                 nics.append({'net-id': network_deployment.net_id})
55
56         # now include network template
57         network_templates = [network.template.sharedNetworkName for network in networks \
58                              if network.template.sharedNetworkName]
59
60         #driver = self.driver.client_driver(caller=sliver.creator, tenant=sliver.slice.name, deployment=sliver.deploymentNetwork)
61         driver = self.driver.admin_driver(tenant='admin', deployment=sliver.deploymentNetwork)
62         nets = driver.shell.quantum.list_networks()['networks']
63         for net in nets:
64             if net['name'] in network_templates: 
65                 nics.append({'net-id': net['id']}) 
66
67         if (not nics):
68             for net in nets:
69                 if net['name']=='public':
70                     nics.append(net['id'])
71
72         # look up image id
73         deployment_driver = self.driver.admin_driver(deployment=sliver.deploymentNetwork.name)
74         image_id = None
75         images = deployment_driver.shell.glanceclient.images.list()
76         for image in images:
77             if image.name == sliver.image.name or not image_id:
78                 image_id = image.id
79                 
80         # look up key name at the deployment
81         # create/fetch keypair
82         keyname = None
83         keyname = sliver.creator.email.lower().replace('@', 'AT').replace('.', '') +\
84                   sliver.slice.name
85         key_fields =  {'name': keyname,
86                        'public_key': sliver.creator.public_key}
87             
88
89         userData = self.get_userdata(sliver)
90         if sliver.userData:
91             userData = sliver.userData
92             
93         sliver_name = '@'.join([sliver.slice.name,sliver.node.name])
94         tenant_fields = {'endpoint':sliver.node.deployment.auth_url,
95                      'admin_user': sliver.node.deployment.admin_user,
96                      'admin_password': sliver.node.deployment.admin_password,
97                      'admin_tenant': 'admin',
98                      'tenant': sliver.slice.name,
99                      'tenant_description': sliver.slice.description,
100                      'name':sliver_name,
101                      'image_id':image_id,
102                      'key_name':keyname,
103                      'flavor_id':1,
104                      'nics':nics,
105                      'meta':metadata_update,
106                      'key':key_fields,
107                      'user_data':r'%s'%escape(userData)}
108
109         res = run_template('sync_slivers.yaml', tenant_fields)
110         if (len(res)!=2):
111             raise Exception('Could not sync sliver %s'%sliver.slice.name)
112         else:
113             sliver_id = res[1]['id'] # 0 is for the key
114
115             sliver.instance_id = sliver_id
116             sliver.instance_name = sliver_name
117             sliver.save()    
118
119     def delete_record(self, sliver):
120         if sliver.instance_id:
121             driver = self.driver.client_driver(caller=sliver.creator, 
122                                                tenant=sliver.slice.name,
123                                                deployment=sliver.deploymentNetwork.name)
124             driver.destroy_instance(sliver.instance_id)