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