Fix get resources for slices
[sfa.git] / sfa / openstack / osaggregate.py
1
2 from sfa.util.faults import SfaAPIError
3 from sfa.rspecs.rspec import RSpec
4 from sfa.rspecs.elements.hardware_type import HardwareType
5 from sfa.rspecs.elements.node import Node
6 from sfa.rspecs.elements.sliver import Sliver
7 from sfa.rspecs.elements.login import Login
8 from sfa.rspecs.elements.services import Services
9 from sfa.util.xrn import Xrn
10 from sfa.util.osxrn import OSXrn
11 from sfa.rspecs.version_manager import VersionManager
12
13 class OSAggregate:
14
15     def __init__(self, driver):
16         self.driver = driver
17
18     def instance_to_sliver(self, instance, slice_xrn=None):
19         # should include? 
20         # * instance.image_ref
21         # * instance.kernel_id
22         # * instance.ramdisk_id 
23         import nova.db.sqlalchemy.models
24         name=None
25         type=None
26         sliver_id = None
27         if isinstance(instance, dict):
28             # this is an isntance type dict
29             name = instance['name']
30             type = instance['name'] 
31         elif isinstance(instance, nova.db.sqlalchemy.models.Instance):
32             # this is an object that describes a running instance
33             name = instance.display_name
34             type = instance.instance_type.name
35         else:
36             raise SfaAPIError("instnace must be an instance_type dict or" + \
37                                " a nova.db.sqlalchemy.models.Instance object")
38         if slice_xrn:
39             xrn = Xrn(slice_xrn, 'slice')
40             sliver_id = xrn.get_sliver_id(instance.project_id, instance.hostname, instance.id)     
41     
42         sliver = Sliver({'slice_id': sliver_id,
43                          'name': name,
44                          'type': 'plos-' + type,
45                          'tags': []})
46         return sliver
47
48     def get_rspec(self, slice_xrn=None, version=None, options={}):
49         version_manager = VersionManager()
50         version = version_manager.get_version(version)
51         if not slice_xrn:
52             rspec_version = version_manager._get_version(version.type, version.version, 'ad')
53             nodes = self.get_aggregate_nodes()
54         else:
55             rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
56             nodes = self.get_slice_nodes(slice_xrn)
57         rspec = RSpec(version=rspec_version, user_options=options)
58         rspec.version.add_nodes(nodes)
59         return rspec.toxml()
60
61     def get_slice_nodes(self, slice_xrn):
62         name = OSXrn(xrn = slice_xrn).name
63         instances = self.driver.shell.db.instance_get_all_by_project(name)
64         rspec_nodes = []
65         for instance in instances:
66             rspec_node = Node()
67             xrn = OSXrn(instance.hostname, 'node')
68             rspec_node['component_id'] = xrn.urn
69             rspec_node['component_name'] = xrn.name
70             rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()   
71             sliver = self.instance_to_sliver(instance) 
72             rspec_node['slivers'] = [sliver]
73             rspec_nodes.append(rspec_node)
74         return rspec_nodes
75
76     def get_aggregate_nodes(self):
77                 
78         zones = self.driver.shell.db.zone_get_all()
79         if not zones:
80             zones = ['cloud']
81         else:
82             zones = [zone.name for zone in zones]
83
84         rspec_nodes = []
85         for zone in zones:
86             rspec_node = Node()
87             xrn = OSXrn(zone, 'node')
88             rspec_node['component_id'] = xrn.urn
89             rspec_node['component_name'] = xrn.name
90             rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
91             rspec_node['exclusive'] = 'false'
92             rspec_node['hardware_types'] = [HardwareType({'name': 'plos-pc'}),
93                                                 HardwareType({'name': 'pc'})]
94             instances = self.driver.shell.db.instance_type_get_all().values()
95             slivers = [self.instance_to_sliver(inst) for inst in instances]
96             rspec_node['slivers'] = slivers
97             rspec_nodes.append(rspec_node) 
98
99         return rspec_nodes 
100
101
102     def verify_slice(self, slicename, users, options={}):
103         """
104         Create the slice if it doesn't alredy exist  
105         """
106         import nova.exception.ProjectNotFound
107         try:
108             slice = self.driver.shell.auth_manager.get_project(slicename)
109         except nova.exception.ProjectNotFound:
110             # convert urns to user names
111             usernames = [Xrn(user['urn']).get_leaf() for user in users]
112             # assume that the first user is the project manager
113             proj_manager = usernames[0] 
114             self.driver.shell.auth_manager.create_project(slicename, proj_manager)
115
116     def verify_slice_users(self, slicename, users, options={}):
117         """
118         Add requested users to the specified slice.  
119         """
120         
121         # There doesn't seem to be an effcient way to 
122         # look up all the users of a project, so lets not  
123         # attempt to remove stale users . For now lets just
124         # ensure that the specified users exist     
125         for user in users:
126             username = Xrn(user['urn']).get_leaf()
127             try:
128                 self.driver.shell.auth_manager.get_user(username)
129             except nova.exception.UserNotFound:
130                 self.driver.shell.auth_manager.create_user(username)
131             self.verify_user_keys(username, user['keys'], options)
132
133     def verify_user_keys(self, username, keys, options={}):
134         """
135         Add requested keys.
136         """
137         append = options.get('append', True)    
138         existing_keys = self.driver.shell.db.key_pair_get_all_by_user(username)
139         existing_pub_keys = [key.public_key for key in existing_keys]
140         removed_pub_keys = set(existing_pub_keys).difference(keys)
141         added_pub_keys = set(keys).difference(existing_pub_keys)
142
143         # add new keys
144         for public_key in added_pub_keys:
145             key = {}
146             key['user_id'] = username
147             key['name'] =  username
148             key['public'] = public_key
149             self.driver.shell.db.key_pair_create(key)
150
151         # remove old keys
152         if not append:
153             for key in existing_keys:
154                 if key.public_key in removed_pub_keys:
155                     self.driver.shell.db.key_pair_destroy(username, key.name)
156             
157     def verify_instances(self, slicename, rspec):
158         rsepc = RSpec(rspec)
159         nodes = rspec.version.get_nodes_with_slivers()
160         old_instances = self.driver.shell.db.instance_get_all_by_project(name)
161         for node in nodes:
162             for slivers in node.get('slivers', []):
163                 pass
164                 # get instance type
165                 # get image
166                 # start instance