source: fedd/federation/ns2topdl.py @ c167378

compt_changesinfo-ops
Last change on this file since c167378 was 454f398, checked in by Ted Faber <faber@…>, 13 years ago

Add abac to ns2topdl

  • Property mode set to 100644
File size: 4.4 KB
Line 
1#!/usr/local/bin/python
2
3import os,sys
4import subprocess
5import tempfile
6import logging
7import topdl
8
9from util import *
10from fedid import fedid
11from remote_service import xmlrpc_handler, soap_handler
12from service_error import *
13from authorizer import authorizer, abac_authorizer
14
15
16class nullHandler(logging.Handler):
17    def emit(self, record): pass
18
19fl = logging.getLogger("fedd.splitter")
20fl.addHandler(nullHandler())
21
22class ns2topdl_local:
23    def __init__(self, config=None, auth=None):
24        """
25        Intialize the various attributes, most from the config object
26        """
27        self.debug = config.getboolean("ns2topdl", "debug")
28        self.muxmax = config.getint("ns2topdl", "muxmax", 3)
29        self.tclsh = config.get("ns2topdl", "tclsh", 
30                "/usr/local/bin/otclsh")
31        self.tcl_splitter = config.get("ns2topdl", "tcl_splitter",
32                "/usr/testbed/lib/ns2ir/parse.tcl")
33        self.auth_type = config.get('ns2topdl', 'auth_type') or 'legacy'
34        access_db = config.get("ns2topdl", "accessdb", None)
35        self.allow_any = config.getboolean("ns2topdl", "allow_any", False)
36        auth_dir = config.get('ns2topdl', 'auth_dir')
37
38        self.log = logging.getLogger("fedd.ns2topdl")
39        set_log_level(config, "ns2topdl", self.log)
40        self.trace_file = sys.stderr
41
42        set_log_level(config, "ns2topdl", self.log)
43
44        if auth:
45            self.auth= auth
46        else:
47            self.auth = authorizer()
48            self.log.warning("[ns2topdl] No authorizer passed in, " +\
49                    "using local one")
50
51
52        if self.auth_type == 'legacy':
53            if access_db and self.allow_any: 
54                raise service_error(service_error.internal, 
55                        "Cannot specify both an access database and " + 
56                        "allow_any for ns2topdl")
57           
58            if access_db:
59                try:
60                    read_simple_accessdb(access_db, self.auth, 'ns2topdl')
61                except EnvironmentError, e:
62                    raise service_error(service_error.internal,
63                            "Error reading accessDB %s: %s" % (access_db, e))
64                except ValueError:
65                    raise service_error(service_error.internal, "%s" % e)
66            elif self.allow_any:
67                auth.set_global_attribute("ns2topdl")
68        elif self.auth_type == 'abac':
69            self.auth = abac_authorizer(load=auth_dir)
70        else:
71            raise service_error(service_error.internal, 
72                    "Unknown auth_type: %s" % self.auth_type)
73
74
75        # Dispatch tables
76        self.soap_services = {\
77                'Ns2Topdl': soap_handler("Ns2Topdl", self.run_ns2topdl),
78        }
79
80        self.xmlrpc_services = {\
81                'Ns2Topdl': xmlrpc_handler('Ns2Topdl', self.run_ns2topdl),
82        }
83
84    def run_ns2topdl(self, req, fid):
85        """
86        The external interface to tcl to topdl translation.
87
88        Creates a working directory, translates the incoming description using
89        the tcl script.
90        """
91
92        if self.allow_any:
93            self.auth.set_attribute(fid, 'ns2topdl')
94
95        access_ok, proof = self.auth.check_attribute(fid, 'ns2topdl',
96            with_proof=True)
97
98        if not access_ok:
99            raise service_error(service_error.access, "Access Denied", 
100                proof=proof)
101
102        try:
103            tmpdir = tempfile.mkdtemp(prefix="ns2topdl-")
104        except EnvironmentError:
105            raise service_error(service_error.internal, "Cannot create tmp dir")
106
107        tclfile = tmpdir + "/experiment.tcl"
108        pid = "dummy"
109        gid = "dummy"
110        eid = "dummy"
111        master = "dummy"
112
113        req = req.get('Ns2TopdlRequestBody', None)
114        if not req:
115            raise service_error(service_error.req,
116                    "Bad request format (no Ns2TopdlRequestBody)")
117        # The tcl parser needs to read a file so put the content into that file
118        descr=req.get('description', None)
119        if descr:
120            file_content=descr.get('ns2description', None)
121            if file_content:
122                try:
123                    f = open(tclfile, 'w')
124                    f.write(file_content)
125                    f.close()
126                except EnvironmentError:
127                    raise service_error(service_error.internal,
128                            "Cannot write temp experiment description")
129            else:
130                raise service_error(service_error.req, 
131                        "Only ns2descriptions supported")
132        else:
133            raise service_error(service_error.req, "No description")
134
135       
136        tclcmd = [self.tclsh, self.tcl_splitter, '-t', '-x', 
137            str(self.muxmax), '-m', master]
138        tclcmd.extend([pid, gid, eid, tclfile])
139        self.log.debug("Calling splitter %s" % " ".join(tclcmd))
140        tclparser = subprocess.Popen(tclcmd, stdout=subprocess.PIPE)
141
142        top = topdl.topology_from_xml(file=tclparser.stdout, top="experiment")
143
144        # Walk up tmpdir, deleting as we go
145        for path, dirs, files in os.walk(tmpdir, topdown=False):
146            for f in files:
147                os.remove(os.path.join(path, f))
148            for d in dirs:
149                os.rmdir(os.path.join(path, d))
150        os.rmdir(tmpdir)
151
152        resp = { 
153                'experimentdescription':  { 
154                    'topdldescription': top.to_dict(),
155                    },
156                'proof': proof.to_dict(),
157                }
158
159        return resp
160
161
Note: See TracBrowser for help on using the repository browser.