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