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