added support for urn name format. urn is the default name format used over the wire
[sfa.git] / sfa / methods / get_ticket.py
1 ### $Id$
2 ### $URL$
3 import time
4 from sfa.util.faults import *
5 from sfa.util.namespace import *
6 from sfa.util.method import Method
7 from sfa.util.parameter import Parameter, Mixed
8 from sfa.trust.auth import Auth
9 from sfa.util.config import Config
10 from sfa.trust.credential import Credential
11 from sfa.util.table import SfaTable
12 from sfa.util.sfaticket import SfaTicket
13 from sfa.plc.slices import Slices
14 from sfatables.runtime import SFATablesRules
15 from sfa.util.rspec import *
16
17 class get_ticket(Method):
18     """
19     Retrieve a ticket. This operation is currently implemented on PLC
20     only (see SFA, engineering decisions); it is not implemented on
21     components.
22     
23     The ticket is filled in with information from the PLC database. This
24     information includes resources, and attributes such as user keys and
25     initscripts.
26     
27     @param cred credential string
28     @param name name of the slice to retrieve a ticket for (hrn or urn)
29     @param rspec resource specification dictionary
30     
31     @return the string representation of a ticket object
32     """
33
34     interfaces = ['aggregate', 'slicemgr']
35     
36     accepts = [
37         Parameter(str, "Credential string"),
38         Parameter(str, "Human readable name of slice to retrive a ticket for (hrn or urn)"),
39         Parameter(str, "Resource specification (rspec)"),
40         Mixed(Parameter(str, "Human readable name of the original caller"),
41               Parameter(None, "Origin hrn not specified"))
42         ]
43
44     returns = Parameter(str, "String represeneation of a ticket object")
45     
46     def call(self, cred, xrn, rspec, origin_hrn=None):
47         hrn, type = urn_to_hrn(xrn)
48         user_cred = Credential(string=cred)
49
50         #log the call
51         if not origin_hrn:
52             origin_hrn = user_cred.get_gid_caller().get_hrn()
53         self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))
54
55         # validate the cred
56         self.api.auth.check(cred, "getticket")
57         
58         # set the right outgoing rules
59         manager_base = 'sfa.managers'
60         if self.api.interface in ['aggregate']:
61             outgoing_rules = SFATablesRules('OUTGOING')
62             mgr_type = self.api.config.SFA_AGGREGATE_TYPE
63             manager_module = manager_base + ".aggregate_manager_%s" % mgr_type
64             manager = __import__(manager_module, fromlist=[manager_base])
65         elif self.api.interface in ['slicemgr']:
66             outgoing_rules = SFATablesRules('FORWARD-OUTGOING')
67             mgr_type = self.api.config.SFA_SM_TYPE
68             manager_module = manager_base + ".slice_manager_%s" % mgr_type
69             manager = __import__(manager_module, fromlist=[manager_base])
70
71         # Filter the incoming rspec using sfatables
72         incoming_rules = SFATablesRules('INCOMING')
73         #incoming_rules.set_slice(hrn) # This is a temporary kludge. Eventually, we'd like to fetch the context requested by the match/target
74         contexts = incoming_rules.contexts
75         caller_hrn = Credential(string=cred).get_gid_caller().get_hrn()
76         request_context = manager.fetch_context(hrn, caller_hrn, contexts)
77         incoming_rules.set_context(request_context)
78         rspec = incoming_rules.apply(rspec)
79         # remove nodes that are not available at this interface from the rspec
80         valid_rspec = RSpec(xml=manager.get_rspec(self.api, None, origin_hrn))
81         valid_nodes = valid_rspec.getDictsByTagName('NodeSpec')
82         valid_hostnames = [node['name'] for node in valid_nodes]
83         rspec_object = RSpec(xml=rspec)
84         rspec_object.filter(tagname='NodeSpec', attribute='name', whitelist=valid_hostnames)
85         rspec = rspec_object.toxml() 
86         ticket = manager.get_ticket(self.api, xrn, rspec, origin_hrn)
87         
88         return ticket
89