Changeset 72ed6e4
- Timestamp:
- Oct 20, 2008 1:33:21 PM (16 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
- Children:
- f4f4117
- Parents:
- 4700b3b
- Location:
- fedd
- Files:
-
- 1 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd.py
r4700b3b r72ed6e4 23 23 from time import sleep 24 24 import logging 25 from ConfigParser import * 25 26 26 27 # The SSL server here is based on the implementation described at … … 29 30 # Turn off the matching of hostname to certificate ID 30 31 SSL.Connection.clientPostConnectionCheck = None 32 33 class fedd_config_parser(SafeConfigParser): 34 """ 35 A SafeConfig parser with a more forgiving get attribute 36 """ 37 def get(self, sect, opt, default=None): 38 """ 39 This returns the requested option or a given default. 40 41 It's more like getattr than get. 42 """ 43 if self.has_option(sect, opt): 44 return SafeConfigParser.get(self, sect, opt) 45 else: 46 return default 31 47 32 48 class fedd_server(ThreadingSSLServer): … … 302 318 flog.addHandler(fh) 303 319 320 321 304 322 # Initialize the implementation 305 323 if opts.configfile != None: 306 324 try: 307 impl = new_feddservice(opts.configfile) 308 except RuntimeError, e: 309 str = getattr(e, 'desc', None) or getattr(e,'message', None) or \ 310 "No message" 311 sys.exit("Error configuring fedd: %s" % str) 325 config= fedd_config_parser() 326 config.read(opts.configfile) 327 except e: 328 sys.exit("Cannot parse confgi file: %s" % e) 312 329 else: 313 330 sys.exit("--configfile is required") 331 332 try: 333 impl = new_feddservice(config) 334 except RuntimeError, e: 335 str = getattr(e, 'desc', None) or getattr(e,'message', None) or \ 336 "No message" 337 sys.exit("Error configuring fedd: %s" % str) 314 338 315 339 if impl.cert_file == None: -
fedd/fedd_access.py
r4700b3b r72ed6e4 15 15 import copy 16 16 17 from fedd_config_file import config_file18 17 from fedd_access_project import access_project 19 18 from fedd_services import * … … 40 39 """ 41 40 41 bool_attrs = ("dynamic_projects", "project_priority") 42 emulab_attrs = ("boss", "ops", "domain", "fileserver", "eventserver") 43 id_attrs = ("testbed", "proxy", 44 "proxy_cert_file", "proxy_cert_pwd", "proxy_trusted_certs", 45 "dynamic_projects_url", "dynamic_projects_cert_file", 46 "dynamic_projects_cert_pwd", "dynamic_projects_trusted_certs") 47 id_list_attrs = ("restricted",) 48 49 def read_trust(self, trust): 50 """ 51 Read a trust file that splits fedids into testbeds, users or projects 52 53 Format is: 54 55 [type] 56 fedid 57 fedid 58 default: type 59 """ 60 lineno = 0; 61 cat = None 62 cat_re = re.compile("\[(user|testbed|project)\]$", re.IGNORECASE) 63 fedid_re = re.compile("[" + string.hexdigits + "]+$") 64 default_re = re.compile("default:\s*(user|testbed|project)$", 65 re.IGNORECASE) 66 67 f = open(trust, "r") 68 for line in f: 69 lineno += 1 70 line = line.strip() 71 if len(line) == 0 or line.startswith("#"): 72 continue 73 # Category line 74 m = cat_re.match(line) 75 if m != None: 76 cat = m.group(1).lower() 77 continue 78 # Fedid line 79 m = fedid_re.match(line) 80 if m != None: 81 if cat != None: 82 self.fedid_category[fedid(hexstr=m.string)] = cat 83 else: 84 raise parse_error(\ 85 "Bad fedid in trust file (%s) line: %d" % \ 86 (trust, lineno)) 87 continue 88 # default line 89 m = default_re.match(line) 90 if m != None: 91 self.fedid_default = m.group(1).lower() 92 continue 93 # Nothing matched - bad line, raise exception 94 f.close() 95 raise parse_error(\ 96 "Unparsable line in trustfile %s line %d" % (trust, lineno)) 97 f.close() 98 99 def read_access(self, config): 100 """ 101 Read a configuration file and set internal parameters. 102 103 The format is more complex than one might hope. The basic format is 104 attribute value pairs separated by colons(:) on a signle line. The 105 attributes in bool_attrs, emulab_attrs and id_attrs can all be set 106 directly using the name: value syntax. E.g. 107 boss: hostname 108 sets self.boss to hostname. In addition, there are access lines of the 109 form (tb, proj, user) -> (aproj, auser) that map the first tuple of 110 names to the second for access purposes. Names in the key (left side) 111 can include "<NONE> or <ANY>" to act as wildcards or to require the 112 fields to be empty. Similarly aproj or auser can be <SAME> or 113 <DYNAMIC> indicating that either the matching key is to be used or a 114 dynamic user or project will be created. These names can also be 115 federated IDs (fedid's) if prefixed with fedid:. Finally, the aproj 116 can be followed with a colon-separated list of node types to which that 117 project has access (or will have access if dynamic). 118 Testbed attributes outside the forms above can be given using the 119 format attribute: name value: value. The name is a single word and the 120 value continues to the end of the line. Empty lines and lines startin 121 with a # are ignored. 122 123 Parsing errors result in a parse_error exception being raised. 124 """ 125 lineno=0 126 name_expr = "["+string.ascii_letters + string.digits + "\.\-_]+" 127 fedid_expr = "fedid:[" + string.hexdigits + "]+" 128 key_name = "(<ANY>|<NONE>|"+fedid_expr + "|"+ name_expr + ")" 129 access_proj = "(<DYNAMIC>(?::" + name_expr +")*|"+ \ 130 "<SAME>" + "(?::" + name_expr + ")*|" + \ 131 fedid_expr + "(?::" + name_expr + ")*|" + \ 132 name_expr + "(?::" + name_expr + ")*)" 133 access_name = "(<DYNAMIC>|<SAME>|" + fedid_expr + "|"+ name_expr + ")" 134 135 restricted_re = re.compile("restricted:\s*(.*)", re.IGNORECASE) 136 attr_re = re.compile('attribute:\s*([\._\-a-z0-9]+)\s+value:\s*(.*)', 137 re.IGNORECASE) 138 access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+ 139 key_name+'\s*\)\s*->\s*\('+access_proj + '\s*,\s*' + 140 access_name + '\s*\)', re.IGNORECASE) 141 142 def parse_name(n): 143 if n.startswith('fedid:'): return fedid(n[len('fedid:'):]) 144 else: return n 145 146 f = open(config, "r"); 147 for line in f: 148 lineno += 1 149 line = line.strip(); 150 if len(line) == 0 or line.startswith('#'): 151 continue 152 153 # Extended (attribute: x value: y) attribute line 154 m = attr_re.match(line) 155 if m != None: 156 attr, val = m.group(1,2) 157 self.attrs[attr] = val 158 continue 159 160 # Restricted entry 161 m = restricted_re.match(line) 162 if m != None: 163 val = m.group(1) 164 self.restricted.append(val) 165 continue 166 167 # Access line (t, p, u) -> (ap, au) line 168 m = access_re.match(line) 169 if m != None: 170 access_key = tuple([ parse_name(x) for x in m.group(1,2,3)]) 171 aps = m.group(4).split(":"); 172 if aps[0] == 'fedid:': 173 del aps[0] 174 aps[0] = fedid(hexstr=aps[0]) 175 176 au = m.group(5) 177 if au.startswith("fedid:"): 178 au = fedid(hexstr=aus[len("fedid:"):]) 179 180 access_val = (access_project(aps[0], aps[1:]), au) 181 182 self.access[access_key] = access_val 183 continue 184 185 # Nothing matched to here: unknown line - raise exception 186 f.close() 187 raise parse_error("Unknown statement at line %d of %s" % \ 188 (lineno, config)) 189 f.close() 190 191 42 192 def __init__(self, config=None): 43 193 """ 44 Initializer. Parses a configuration if one is given. 45 """ 46 47 # Read the configuration 48 if not config: raise RunTimeError("No config to fedd_allocate") 194 Initializer. Pulls parameters out of the ConfigParser's access section. 195 """ 196 197 # Make sure that the configuration is in place 198 if config: 199 if not config.has_section("access"): 200 config.add_section("access") 201 if not config.has_section("globals"): 202 config.add_section("globals") 203 else: 204 raise RunTimeError("No config to fedd_access") 205 49 206 50 207 # Create instance attributes from the static lists 51 for a in config_file.bool_attrs: 52 setattr(self, a, getattr(config, a, False)) 53 54 for a in config_file.emulab_attrs + config_file.id_attrs: 55 setattr(self, a, getattr(config, a, None)) 56 57 58 self.attrs = copy.deepcopy(config.attrs); 59 self.access = copy.deepcopy(config.access); 60 self.fedid_category = copy.deepcopy(config.fedid_category) 61 self.fedid_default = config.fedid_default 62 self.restricted = copy.copy(config.restricted) 208 for a in fedd_access.bool_attrs: 209 if config.has_option("access", a): 210 setattr(self, a, config.get("access", a)) 211 else: 212 setattr(self, a, False) 213 214 for a in fedd_access.emulab_attrs + fedd_access.id_attrs: 215 if config.has_option("access", a): 216 setattr(self, a, config.get("access",a)) 217 else: 218 setattr(self, a, None) 219 220 self.attrs = { } 221 self.access = { } 222 self.restricted = [ ] 223 self.fedid_category = { } 224 self.fedid_default = "testbed" 225 if config.has_option("access", "accessdb"): 226 self.read_access(config.get("access", "accessdb")) 227 if config.has_option("access", "trustdb"): 228 self.read_trust(config.get("access", "trustdb")) 63 229 64 230 self.log = logging.getLogger("fedd.access") … … 69 235 # proxy certs are used, and if none of those the main certs. 70 236 71 if config. proxy_cert_file:237 if config.has_option("globals", "proxy_cert_file"): 72 238 if not self.dynamic_projects_cert_file: 73 self.dynamic_projects_cert_file = config.proxy_cert_file 74 self.dynamic_projects_cert_pwd = config.proxy_cert_pwd 75 76 if config.proxy_trusted_certs: 239 self.dynamic_projects_cert_file = \ 240 config.get("globals", "proxy_cert_file") 241 if config.has_option("globals", "porxy_cert_pwd"): 242 self.dynamic_projects_cert_pwd = \ 243 config.get("globals", "proxy_cert_pwd") 244 245 if config.has_option("globals", "proxy_trusted_certs"): 77 246 if not self.dynamic_projects_trusted_certs: 78 247 self.dynamic_projects_trusted_certs =\ 79 config.proxy_trusted_certs 80 81 if config.cert_file: 248 config.get("globals", proxy_trusted_certs) 249 250 if config.has_option("globals", "cert_file"): 251 has_pwd = config.has_option("globals", "cert_pwd") 82 252 if not self.dynamic_projects_cert_file: 83 self.dynamic_projects_cert_file = config.cert_file 84 self.dynamic_projects_cert_pwd = config.cert_pwd 253 self.dynamic_projects_cert_file = \ 254 config.get("globals", "cert_file") 255 if has_pwd: 256 self.dynamic_projects_cert_pwd = \ 257 config.get("globals", "cert_pwd") 85 258 if not self.proxy_cert_file: 86 self.proxy_cert_file = config.cert_file 87 self.proxy_cert_pwd = config.cert_pwd 88 89 if config.trusted_certs: 259 self.proxy_cert_file = config.get("globals", "cert_file") 260 if has_pwd: 261 self.proxy_cert_pwd = config.get("globals", "cert_pwd") 262 263 if config.get("globals", "trusted_certs"): 90 264 if not self.proxy_trusted_certs: 91 self.proxy_trusted_certs = config.trusted_certs 265 self.proxy_trusted_certs = \ 266 config.get("globals", "trusted_certs") 92 267 if not self.dynamic_projects_trusted_certs: 93 self.dynamic_projects_trusted_certs = config.trusted_certs 268 self.dynamic_projects_trusted_certs = \ 269 config.get("globals", "trusted_certs") 94 270 95 271 proj_certs = (self.dynamic_projects_cert_file, … … 109 285 110 286 111 if config.dynamic_projects_url == None:287 if not config.has_option("access", "dynamic_projects_url"): 112 288 self.allocate_project = \ 113 fedd_allocate_project_local( config.dynamic_projects,114 config.dynamic_projects_url, proj_certs)289 fedd_allocate_project_local(self.dynamic_projects, 290 None, proj_certs) 115 291 else: 116 292 self.allocate_project = \ 117 fedd_allocate_project_remote(config.dynamic_projects, 118 config.dynamic_projects_url, proj_certs) 293 fedd_allocate_project_remote(self.dynamic_projects, 294 config.get("access", "dynamic_projects_url"), 295 proj_certs) 119 296 120 297 # If the project allocator exports services, put them in this object's … … 127 304 Dump the state read from a configuration file. Mostly for debugging. 128 305 """ 129 for a in fedd_ proj.bool_attrs:306 for a in fedd_access.bool_attrs: 130 307 print "%s: %s" % (a, getattr(self, a )) 131 for a in fedd_ proj.emulab_attrs + fedd_proj.id_attrs:308 for a in fedd_access.emulab_attrs + fedd_access.id_attrs: 132 309 print "%s: %s" % (a, getattr(self, a)) 133 310 for k, v in self.attrs.iteritems(): -
fedd/fedd_client.py
r4700b3b r72ed6e4 656 656 'allocID': pack_id('test alloc'), 657 657 'destinationTestbed': pack_id(opts.testbed), 658 'access' : [ { a.type: a.buf } for a in access_keys ], 658 'serviceAccess' : [ { a.type: a.buf } for a in access_keys ], 659 'createAccess' : [ { a.type: a.buf } for a in access_keys ], 659 660 } 660 661 -
fedd/fedd_deter_impl.py
r4700b3b r72ed6e4 3 3 from fedd_access import * 4 4 from fedd_experiment_control import * 5 from fedd_config_file import *6 5 7 6 class fedd_deter_impl: … … 16 15 'http://www.isi.edu/faber/fedd_internal.wsdl') 17 16 18 def __init__(self, config _path=None):17 def __init__(self, config=None): 19 18 """ 20 19 Initializer. Parses a configuration if one is given. 21 20 """ 22 if config_path: 23 self.soap_services = { } 24 self.xmlrpc_services = { } 25 config = config_file(config_path) 21 self.soap_services = { } 22 self.xmlrpc_services = { } 26 23 27 self.cert_file = config.cert_file; 28 self.cert_pwd = config.cert_pwd; 29 self.trusted_certs = config.trusted_certs; 24 if config: 25 self.cert_file = config.get("globals", "cert_file"); 26 self.cert_pwd = config.get("globals", "cert_pwd"); 27 self.trusted_certs = config.get("globals", "trusted_certs"); 30 28 31 self.access = fedd_access(config) 32 self.experiment = fedd_experiment_control_local(config) 29 if config.has_section("access"): 30 self.access = fedd_access(config) 31 self.soap_services.update(self.access.soap_services) 32 self.xmlrpc_services.update(self.access.xmlrpc_services) 33 33 34 self.soap_services.update(self.access.soap_services) 35 self.soap_services.update(self.experiment.soap_services) 34 if config.has_section("experiment_control"): 35 self.experiment = fedd_experiment_control_local(config) 36 self.soap_services.update(self.experiment.soap_services) 37 self.xmlrpc_services.update(self.experiment.xmlrpc_services) 36 38 37 self.xmlrpc_services.update(self.access.xmlrpc_services) 38 self.xmlrpc_services.update(self.experiment.xmlrpc_services) 39 40 def new_feddservice(configfile): 41 return fedd_deter_impl(configfile) 39 def new_feddservice(config): 40 return fedd_deter_impl(config) -
fedd/fedd_experiment_control.py
r4700b3b r72ed6e4 163 163 # attributes until the local certificate attributes can be resolved. 164 164 # The walk is from most specific to most general specification. 165 for p in ("create_experiment_", "proxy_", ""): 166 filen = "%scert_file" % p 167 pwn = "%scert_pwd" % p 168 trustn = "%strusted_certs" % p 169 170 if getattr(config, filen, None): 171 if not self.cert_file: 172 self.cert_file = getattr(config, filen, None) 173 self.cert_pwd = getattr(config, pwn, None) 174 175 if getattr(config, trustn, None): 176 if not self.trusted_certs: 177 self.trusted_certs = getattr(config, trustn, None) 165 for s in ("experiment_control", "globals"): 166 if config.has_section(s): 167 if config.has_option(s, "cert_file"): 168 if not self.cert_file: 169 self.cert_file = config.get(s, "cert_file") 170 self.cert_pwd = config.get(s, "cert_pwd") 171 172 if config.has_option(s, "trusted_certs"): 173 if not self.trusted_certs: 174 self.trusted_certs = config.get(s, "trusted_certs") 178 175 179 176 self.exp_stem = "fed-stem" 180 self.debug = config.create_debug181 177 self.log = logging.getLogger("fedd.experiment_control") 182 178 self.muxmax = 2 183 179 self.nthreads = 2 184 180 self.randomize_experiments = False 181 185 182 self.scp_exec = "/usr/bin/scp" 186 self.scripts_dir = "/users/faber/testbed/federation"187 183 self.splitter = None 188 184 self.ssh_exec="/usr/bin/ssh" 189 185 self.ssh_keygen = "/usr/bin/ssh-keygen" 190 186 self.ssh_identity_file = None 187 188 if config.has_section("experiment_control"): 189 self.debug = config.get("experiment_control", "create_debug") 190 self.state_filename = config.get("experiment_control", 191 "experiment_state_file") 192 self.scripts_dir = config.get("experiment_control", 193 "federation_script_dir") 194 else: 195 self.debug = False 196 self.state_filename = None 197 self.scripts_dir = "/users/faber/testbed/federation" 198 191 199 # XXX 192 200 self.ssh_pubkey_file = "/users/faber/.ssh/id_rsa.pub" 193 201 self.ssh_type = "rsa" 194 202 self.state = { } 195 self.state_filename = config.experiment_state_file196 203 self.state_lock = Lock() 197 204 self.tclsh = "/usr/local/bin/otclsh" … … 227 234 # hand finds the logging level constant corrersponding to the string. 228 235 # We're a little paranoid to avoid user mayhem. 229 if config. experiment_log:236 if config.has_option("experiment_control", "log_level"): 230 237 try: 231 level = int(getattr(logging, config.experiment_log.upper(),-1)) 238 level = int(getattr(logging, 239 config.get("experiment_control", "log_level").upper(),-1)) 232 240 233 241 if logging.DEBUG <= level <= logging.CRITICAL: … … 235 243 else: 236 244 self.log.error("Bad experiment_log value: %s" % \ 237 config. experiment_log)245 config.get("experiment_control", "log_level")) 238 246 239 247 except ValueError:
Note: See TracChangeset
for help on using the changeset viewer.