9026f6a1f03ec7d1f924a7b0c85e49d4a2bb17b3
[sfa.git] / sfa / managers / aggregate_manager_pl.py
1 ### $Id: slices.py 15842 2009-11-22 09:56:13Z anil $
2 ### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/plc/slices.py $
3
4 import datetime
5 import time
6 import traceback
7 import sys
8
9 from types import StringTypes
10 from sfa.util.namespace import *
11 from sfa.util.rspec import *
12 from sfa.util.specdict import *
13 from sfa.util.faults import *
14 from sfa.util.record import SfaRecord
15 from sfa.util.policy import Policy
16 from sfa.util.record import *
17 from sfa.util.sfaticket import SfaTicket
18 from sfa.util.debug import log
19 from sfa.plc.slices import Slices
20 import sfa.plc.peers as peers
21 from sfa.plc.network import *
22 from sfa.plc.api import SfaAPI
23 from sfa.plc.slices import *
24
25 def delete_slice(api, xrn):
26     hrn, type = urn_to_hrn(xrn)
27     slicename = hrn_to_pl_slicename(hrn)
28     slices = api.plshell.GetSlices(api.plauth, {'name': slicename})
29     if not slices:
30         return 1
31     slice = slices[0]
32
33     # determine if this is a peer slice
34     peer = peers.get_peer(api, hrn)
35     if peer:
36         api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice['slice_id'], peer)
37     api.plshell.DeleteSliceFromNodes(api.plauth, slicename, slice['node_ids'])
38     if peer:
39         api.plshell.BindObjectToPeer(api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
40     return 1
41
42 def __get_hostnames(nodes):
43     hostnames = []
44     for node in nodes:
45         hostnames.append(node.hostname)
46     return hostnames
47     
48 def create_slice(api, xrn, xml):
49     hrn, type = urn_to_hrn(xrn)
50     peer = None
51
52     """
53     Verify HRN and initialize the slice record in PLC if necessary.
54     """
55     slices = Slices(api)
56     peer = slices.get_peer(hrn)
57     sfa_peer = slices.get_sfa_peer(hrn)
58     registry = api.registries[api.hrn]
59     credential = api.getCredential()
60     site_id, remote_site_id = slices.verify_site(registry, credential, hrn, 
61                                                  peer, sfa_peer)
62     slice = slices.verify_slice(registry, credential, hrn, site_id, 
63                                 remote_site_id, peer, sfa_peer)
64
65     network = Network(api)
66
67     slice = network.get_slice(api, hrn)
68     current = __get_hostnames(slice.get_nodes())
69     api.logger.info("Current = %s" % " ".join(current))
70     api.logger.info("before addrspec")
71     network.addRSpec(xml, api.config.SFA_AGGREGATE_RSPEC_SCHEMA)
72     api.logger.info("after addrspec")
73     request = __get_hostnames(network.nodesWithSlivers())
74     
75     # remove nodes not in rspec
76     deleted_nodes = list(set(current).difference(request))
77     api.logger.info("Deleted nodes = " + " ".join(deleted_nodes))
78
79     # add nodes from rspec
80     added_nodes = list(set(request).difference(current))
81     api.logger.info("Added nodes = " + " ".join(added_nodes))
82     
83
84
85     if peer:
86         api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice.id, peer)
87
88     api.plshell.AddSliceToNodes(api.plauth, slice.name, added_nodes) 
89     api.plshell.DeleteSliceFromNodes(api.plauth, slice.name, deleted_nodes)
90
91     network.updateSliceTags()
92
93     if peer:
94         api.plshell.BindObjectToPeer(api.plauth, 'slice', slice.id, peer, 
95                                      slice.peer_id)
96
97     # print network.toxml()
98
99     return True
100
101
102 def get_ticket(api, xrn, rspec, origin_hrn=None):
103     slice_hrn, type = urn_to_hrn(xrn)
104     # the the slice record
105     registry = api.registries[api.hrn]
106     credential = api.getCredential()
107     records = registry.resolve(credential, xrn)
108     
109     # make sure we get a local slice record
110     record = None  
111     for tmp_record in records:
112         if tmp_record['type'] == 'slice' and \
113            not tmp_record['peer_authority']:
114             record = SliceRecord(dict=tmp_record)
115     if not record:
116         raise RecordNotFound(slice_hrn)
117
118     # get sliver info
119     slivers = Slices(api).get_slivers(slice_hrn)
120     if not slivers:
121         raise SliverDoesNotExist(slice_hrn)
122     
123     # get initscripts
124     initscripts = []
125     data = {
126         'timestamp': int(time.time()),
127         'initscripts': initscripts,
128         'slivers': slivers
129     }
130
131     # create the ticket
132     object_gid = record.get_gid_object()
133     new_ticket = SfaTicket(subject = object_gid.get_subject())
134     new_ticket.set_gid_caller(api.auth.client_gid)
135     new_ticket.set_gid_object(object_gid)
136     new_ticket.set_issuer(key=api.key, subject=api.hrn)
137     new_ticket.set_pubkey(object_gid.get_pubkey())
138     new_ticket.set_attributes(data)
139     new_ticket.set_rspec(rspec)
140     #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
141     new_ticket.encode()
142     new_ticket.sign()
143     
144     return new_ticket.save_to_string(save_parents=True)
145
146 def start_slice(api, xrn):
147     hrn, type = urn_to_hrn(xrn)
148     slicename = hrn_to_pl_slicename(hrn)
149     slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
150     if not slices:
151         raise RecordNotFound(hrn)
152     slice_id = slices[0]
153     attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
154     attribute_id = attributes[0]['slice_attribute_id']
155     api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
156
157     return 1
158  
159 def stop_slice(api, xrn):
160     hrn, type = urn_to_hrn(xrn)
161     slicename = hrn_to_pl_slicename(hrn)
162     slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
163     if not slices:
164         raise RecordNotFound(hrn)
165     slice_id = slices[0]['slice_id']
166     attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
167     attribute_id = attributes[0]['slice_attribute_id']
168     api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
169     return 1
170
171 def reset_slice(api, xrn):
172     # XX not implemented at this interface
173     return 1
174
175 def get_slices(api):
176     # XX just import the legacy module and excute that until
177     # we transition the code to this module
178     from sfa.plc.slices import Slices
179     slices = Slices(api)
180     slices.refresh()
181     return [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slices['hrn']]
182      
183  
184 def get_rspec(api, xrn=None, origin_hrn=None):
185     hrn, type = urn_to_hrn(xrn)
186     network = Network(api)
187     if (hrn):
188         if network.get_slice(api, hrn):
189             network.addSlice()
190
191     return network.toxml()
192
193 """
194 Returns the request context required by sfatables. At some point, this
195 mechanism should be changed to refer to "contexts", which is the
196 information that sfatables is requesting. But for now, we just return
197 the basic information needed in a dict.
198 """
199 def fetch_context(slice_xrn, user_xrn, contexts):
200     slice_hrn, type = urn_to_hrn(slice_xrn)
201     user_hrn, type = urn_to_hrn(user_xrn)
202     base_context = {'sfa':{'user':{'hrn':user_hrn}, 'slice':{'hrn':slice_hrn}}}
203     return base_context
204
205 def main():
206     api = SfaAPI()
207     """
208     rspec = get_rspec(api, "plc.princeton.sapan", None)
209     #rspec = get_rspec(api, "plc.princeton.coblitz", None)
210     #rspec = get_rspec(api, "plc.pl.sirius", None)
211     print rspec
212     """
213     f = open(sys.argv[1])
214     xml = f.read()
215     f.close()
216     create_slice(api, "plc.princeton.sapan", xml)
217
218 if __name__ == "__main__":
219     main()