change the format of the 'data' to something that nm is used to
[sfa.git] / sfa / methods / get_ticket.py
1 ### $Id$
2 ### $URL$
3
4 from sfa.util.faults import *
5 from sfa.util.method import Method
6 from sfa.util.parameter import Parameter, Mixed
7 from sfa.trust.auth import Auth
8 from sfa.util.config import Config
9 from sfa.trust.credential import Credential
10 from sfa.util.genitable import GeniTable
11 from sfa.util.sfaticket import SfaTicket
12 from sfa.plc.slices import Slices
13 from sfatables.runtime import SFATablesRules
14
15 class get_ticket(Method):
16     """
17     Retrieve a ticket. This operation is currently implemented on PLC
18     only (see SFA, engineering decisions); it is not implemented on
19     components.
20     
21     The ticket is filled in with information from the PLC database. This
22     information includes resources, and attributes such as user keys and
23     initscripts.
24     
25     @param cred credential string
26     @param name name of the slice to retrieve a ticket for
27     @param rspec resource specification dictionary
28     
29     @return the string representation of a ticket object
30     """
31
32     interfaces = ['registry', 'aggregate', 'slicemgr']
33     
34     accepts = [
35         Parameter(str, "Credential string"),
36         Parameter(str, "Human readable name of slice to retrive a ticket for (hrn)"),
37         Parameter(str, "Resource specification (rspec)"),
38         Mixed(Parameter(str, "Request hash"),
39               Parameter(None, "Request hash not specified"))
40         ]
41
42     returns = Parameter(str, "String represeneation of a ticket object")
43     
44     def call(self, cred, hrn, rspec, request_hash=None):
45         self.api.auth.authenticateCred(cred, [cred, hrn, rspec], request_hash)
46         self.api.auth.check(cred, "getticket")
47         self.api.auth.verify_object_belongs_to_me(hrn)
48         self.api.auth.verify_object_permission(hrn)
49
50         # find record info
51         table = GeniTable()
52         records = table.findObjects({'hrn': hrn, 'type': 'slice', 'peer_authority': None})
53         if not records:
54             raise RecordNotFound(hrn)
55         record = records[0]
56         auth_hrn = record['authority']
57         auth_info = self.api.auth.get_auth_info(auth_hrn)
58         object_gid = record.get_gid_object()
59         new_ticket = SfaTicket(subject = object_gid.get_subject())
60         new_ticket.set_gid_caller(self.api.auth.client_gid)
61         new_ticket.set_gid_object(object_gid)
62         new_ticket.set_issuer(key=auth_info.get_pkey_object(), subject=auth_hrn)
63         new_ticket.set_pubkey(object_gid.get_pubkey())
64
65         # determine aggregate tyep 
66         sfa_aggregate_type = Config().get_aggregate_rspec_type()
67         rspec_manager = __import__("sfa.rspecs.aggregates.rspec_manager_"+sfa_aggregate_type, fromlist = ["sfa.rspecs.aggregates"])
68
69         # Fukter the incoming rspec using sfatables
70         incoming_rules = SFATablesRules('INCOMING')
71         #incoming_rules.set_slice(hrn) # This is a temporary kludge. Eventually, we'd like to fetch the context requested by the match/target
72         contexts = incoming_rules.contexts
73         caller_hrn = Credential(string=cred).get_gid_caller().get_hrn()
74         request_context = rspec_manager.fetch_context(hrn, caller_hrn, contexts)
75         incoming_rules.set_context(request_context)
76         rspec = incoming_rules.apply(rspec)
77
78         # get sliver info    
79         slivers = Slices(self.api).get_slivers(hrn)
80         if not slivers:
81             raise SliverDoesNotExist(hrn)
82         sliver = slivers[0]
83             
84         # get initscripts
85         initscripts = None
86         data = {
87             'timestamp': int(time.time()),
88             'initscripts': initscripts,
89             'slivers': sliver 
90         }
91
92         new_ticket.set_attributes(attributes)
93         new_ticket.set_rspec(rspec)
94
95         new_ticket.set_parent(self.api.auth.hierarchy.get_auth_ticket(auth_hrn))
96
97         new_ticket.encode()
98         new_ticket.sign()
99
100         return new_ticket.save_to_string(save_parents=True)
101