- Timestamp:
- Jul 30, 2008 3:48:02 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:
- ef36c1e
- Parents:
- 21a1c30
- Location:
- fedd
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd_messages.wsdl
r21a1c30 r7da9da6 20 20 21 21 <message name="AllocateProjectRequestMessage"> 22 <part name="AllocateProjectRequestBody" type="xsd1:project Type"/>22 <part name="AllocateProjectRequestBody" type="xsd1:projectAllocType"/> 23 23 </message> 24 24 25 25 <message name="AllocateProjectResponseMessage"> 26 26 <part name="AllocateProjectResponseBody" type="xsd1:projectType"/> 27 </message>28 29 <message name="AllocateProjectFaultMessage">30 <part name="AllocateProjectFaultBody" type="xsd1:faultType"/>31 27 </message> 32 28 … … 39 35 <output message="tns:RequestAccessResponseMessage"/> 40 36 <fault name="RequestAccessFault" 41 message="tns: RequestAccessFaultMessage"/>37 message="tns:FaultMessage"/> 42 38 </operation> 43 39 … … 46 42 <output message="tns:AllocateProjectResponseMessage"/> 47 43 <fault name="AllocateProjectFault" 48 message="tns: AllocateProjectFaultMessage"/>44 message="tns:FaultMessage"/> 49 45 </operation> 50 46 </portType> -
fedd/fedd_proj.py
r21a1c30 r7da9da6 12 12 13 13 import re 14 import random15 14 import string 16 15 import subprocess … … 20 19 from fedd_services import * 21 20 from fedd_util import * 21 from fedd_allocate_project import * 22 22 import parse_detail 23 from service_error import * 23 24 24 25 class fedd_proj: … … 58 59 return "access_proj('%s', [])" % self.name 59 60 60 # This is used to make the service error reporting independent of the61 # transport. The XMLRPC and SOAP dispatchers will convert it into62 # transport-specific errors63 class service_error(RuntimeError):64 access = 165 proxy= 266 req = 367 server_config = 468 internal = 569 code_str = {70 access : "Access Denied",71 proxy : "Proxy Error",72 req : "Badly Formed Request",73 server_config: "Server Configuration Error",74 internal : "Internal Error"75 }76 str_code = dict([ (v, k) for k, v in code_str.iteritems() ])77 client_errors = ( req )78 server_errors = ( access, proxy, server_config, internal)79 80 def __init__(self, code=None, desc=None, from_string=None):81 self.code = code82 self.desc = desc83 if code == None:84 self.set_code_from_string(from_string)85 RuntimeError.__init__(self, desc)86 87 def code_string(self, code=None):88 code = code or self.code89 return fedd_proj.service_error.code_str.get(code)90 91 def set_code_from_string(self, errstr):92 self.code = fedd_proj.service_error.str_code.get(errstr,93 fedd_proj. service_error.internal)94 return self.code95 96 def is_client_error(self):97 return self.code in fedd_proj.service_error.client_errors98 99 def is_server_error(self):100 return self.code in fedd_proj.service_error.server_errors101 102 61 # Used to report errors parsing the configuration files, not in providing 103 62 # service … … 123 82 self.fedid_default = "user" 124 83 self.restricted = [] 84 85 # Delete these 125 86 self.wap = '/usr/testbed/sbin/wap' 126 87 self.newproj = '/usr/testbed/sbin/newproj' … … 131 92 if config != None: 132 93 self.read_config(config) 94 self.allocate_project = \ 95 fedd_allocate_project_local(self.dynamic_projects) 133 96 134 97 def dump_state(self): … … 150 113 print "Restricted: %s" % str(',').join(sorted(self.restricted)) 151 114 152 def get_id(self, id):153 """154 Utility to get an object from the polymorphic IDType.155 156 Only fedids and usernames are currently understood. If neither is157 present None is returned. If both are present (which is a bug) the158 fedid is returned.159 """160 if id == None:161 return None162 elif getattr(id, "get_element_fedid", None) != None:163 return fedid(id.get_element_fedid())164 elif getattr(id, "get_element_username", None) != None:165 return id.get_element_username()166 else:167 return None168 169 115 def get_users(self, obj): 170 116 """ … … 177 123 return None 178 124 179 def random_string(self, s, n=3):180 """Append n random ASCII characters to s and return the string"""181 rv = s182 for i in range(0,n):183 rv += random.choice(string.ascii_letters)184 return rv185 186 def write_attr_xml(self, file, root, lines):187 """188 Write an emulab config file for a dynamic project.189 190 Format is <root><attribute name=lines[0]>lines[1]</attribute></root>191 """192 # Convert a pair to an attribute line193 out_attr = lambda a,v : \194 '<attribute name="%s"><value>%s</value></attribute>' % (a, v)195 196 f = os.fdopen(file, "w")197 f.write("<%s>\n" % root)198 f.write("\n".join([out_attr(*l) for l in lines]))199 f.write("</%s>\n" % root)200 f.close()201 202 203 def dynamic_project(self, found, ssh):204 """Create a dynamic project with ssh access"""205 user_fields = [206 ("name", "Federation User %s" % found[1]),207 ("email", "%s-fed@isi.deterlab.net" % found[1]),208 ("password", self.random_string("", 8)),209 ("login", found[1]),210 ("address", "4676 Admiralty"),211 ("city", "Marina del Rey"),212 ("state", "CA"),213 ("zip", "90292"),214 ("country", "USA"),215 ("phone", "310-448-9190"),216 ("title", "None"),217 ("affiliation", "USC/ISI")218 ]219 220 proj_fields = [221 ("name", found[0].name),222 ("short description", "dynamic federated project"),223 ("URL", "http://www.isi.edu/~faber"),224 ("funders", "USC/USU"),225 ("long description", "Federation access control"),226 ("public", "1"),227 ("num_pcs", "100"),228 ("linkedtous", "1")229 ]230 231 # tempfiles for the parameter files232 uf, userfile = tempfile.mkstemp(prefix="usr", suffix=".xml",233 dir="/tmp")234 pf, projfile = tempfile.mkstemp(prefix="proj", suffix=".xml",235 dir="/tmp")236 237 # A few more dynamic fields238 for s in ssh:239 user_fields.append(("pubkey", s))240 proj_fields.append(("newuser_xml", userfile))241 242 # Write out the files243 self.write_attr_xml(uf, "user", user_fields)244 self.write_attr_xml(pf, "project", proj_fields)245 246 # Generate the commands (only grantnodetype's are dynamic)247 cmds = [248 (self.wap, self.newproj, projfile),249 (self.wap, self.mkproj, found[0].name)250 ]251 for nt in found[0].node_types:252 cmds.append((self.wap, self.grantnodetype, '-p', found[0].name, nt))253 254 # Create the projects255 rc = 0256 for cmd in cmds:257 if self.dynamic_projects:258 try:259 rc = subprocess.call(cmd)260 except OSerror, e:261 raise fedd_proj.service_error(\262 fedd_proj.service_error.internal,263 "Dynamic project subprocess creation error "+ \264 "[%s] (%s)" % (cmd[1], e.strerror))265 else:266 print >>sys.stdout, str(" ").join(cmd)267 268 if rc != 0:269 raise fedd_proj.service_error(\270 fedd_proj.service_error.internal,271 "Dynamic project subprocess error " +\272 "[%s] (%d)" % (cmd[1], rc))273 # Clean up tempfiles274 os.unlink(userfile)275 os.unlink(projfile)276 277 278 125 def strip_unicode(self, obj): 279 126 """Loosly de-unicode an object""" … … 298 145 ctx = fedd_ssl_context(self.cert_file, tc, password=self.cert_pwd) 299 146 except SSL.SSLError: 300 raise fedd_proj.service_error(fedd_proj.service_error.server_config,147 raise service_error(service_error.server_config, 301 148 "Server certificates misconfigured") 302 149 … … 320 167 resp, method = xmlrpclib.loads(resp) 321 168 except xmlrpclib.Fault, f: 322 se = fedd_proj.service_error(None, f.faultString, f.faultCode)169 se = service_error(None, f.faultString, f.faultCode) 323 170 raise se 324 171 except xmlrpclib.Error, e: 325 raise fedd_proj.service_error(fedd_proj.service_error.proxy,172 raise service_error(service_error.proxy, 326 173 "Remote XMLRPC Fault: %s" % e) 327 174 … … 329 176 return resp[0]['RequestAccessResponseBody'] 330 177 else: 331 raise fedd_proj.service_error(fedd_proj.service_error.proxy,178 raise service_error(service_error.proxy, 332 179 "Bad proxy response") 333 180 … … 346 193 ctx = fedd_ssl_context(self.cert_file, tc, password=self.cert_pwd) 347 194 except SSL.SSLError: 348 raise fedd_proj.service_error(fedd_proj.service_error.server_config,195 raise service_error(service_error.server_config, 349 196 "Server certificates misconfigured") 350 197 … … 361 208 resp = port.RequestAccess(msg) 362 209 except ZSI.ParseException, e: 363 raise fedd_proj.service_error(fedd_proj.service_error.proxy,210 raise service_error(service_error.proxy, 364 211 "Bad format message (XMLRPC??): %s" % 365 212 str(e)) … … 369 216 return r['RequestAccessResponseBody'] 370 217 else: 371 raise fedd_proj.service_error(fedd_proj.service_error.proxy,218 raise service_error(service_error.proxy, 372 219 "Bad proxy response") 373 220 … … 439 286 fedids = [ u for u in user if isinstance(u, type(fid))] 440 287 if len(fedids) > 1: 441 raise fedd_proj.service_error(service_error.req,288 raise service_error(service_error.req, 442 289 "User asserting multiple fedids") 443 290 elif len(fedids) == 1 and fedids[0] != fid: 444 raise fedd_proj.service_error(service_error.req,291 raise service_error(service_error.req, 445 292 "User asserting different fedid") 446 293 project = None … … 448 295 elif principal_type == "project": 449 296 if isinstance(project, type(fid)) and fid != project: 450 raise fedd_proj.service_error(service_error.req,297 raise service_error(service_error.req, 451 298 "Project asserting different fedid") 452 299 tb = None 453 300 454 301 # Ready to look up access 455 print "Lookup %s %s %s: " % (tb, project, user)456 302 found, user_match = self.find_access((tb, project, user)) 457 print "Found: ", found458 303 459 304 if found == None: 460 raise fedd_proj.service_error(fedd_proj.service_error.access,305 raise service_error(service_error.access, 461 306 "Access denied") 462 307 … … 469 314 found[0].name = project 470 315 else : 471 raise fedd_proj.service_error(\472 fedd_proj.service_error.server_config,316 raise service_error(\ 317 service_error.server_config, 473 318 "Project matched <same> when no project given") 474 319 elif found[0].name == "<dynamic>": 475 found[0].name = self.random_string("project", 3)320 found[0].name = None 476 321 dyn_proj = True 477 322 … … 479 324 if user_match == "<any>": 480 325 if user != None: found = (found[0], user[0]) 481 else: raise fedd_proj.service_error(\482 fedd_proj.service_error.server_config,326 else: raise service_error(\ 327 service_error.server_config, 483 328 "Matched <same> on anonymous request") 484 329 else: 485 330 found = (found[0], user_match) 486 331 elif found[1] == "<dynamic>": 487 found = (found[0], self.random_string("user", 4))332 found = (found[0], None) 488 333 dyn_user = True 489 334 490 335 return found, (dyn_user, dyn_proj) 491 336 492 def build_response(self, alloc_id, ap , ssh):337 def build_response(self, alloc_id, ap): 493 338 """ 494 339 Create the SOAP response. … … 496 341 Build the dictionary description of the response and use 497 342 fedd_utils.pack_soap to create the soap message. NB that alloc_id is 498 a fedd_services_types.IDType_Holder pulled from the incoming message 343 a fedd_services_types.IDType_Holder pulled from the incoming message. 344 ap is the allocate project message returned from a remote project 345 allocation (even if that allocation was done locally). 499 346 """ 500 347 # Because alloc_id is already a fedd_services_types.IDType_Holder, … … 508 355 'fileServer': self.fileserver, 509 356 'eventServer': self.eventserver, 510 'project': { 511 'name': pack_id(ap[0].name), 512 'user': [ { 513 'userID': pack_id(ap[1]), 514 'access' : [ { 'sshPubkey': x } for x in ssh ], 515 } 516 ] 517 } 357 'project': ap['project'] 518 358 }, 519 359 } … … 529 369 req = req['RequestAccessRequestBody'] 530 370 else: 531 raise fedd_proj.service_error(service_error.req, "No request!?")371 raise service_error(service_error.req, "No request!?") 532 372 533 373 if req.has_key('destinationTestbed'): … … 537 377 # Request for this fedd 538 378 found, dyn = self.lookup_access(req, fid) 379 restricted = None 380 ap = None 539 381 540 382 # Check for access to restricted nodes 541 383 if req.has_key('resources') and req['resources'].has_key('node'): 542 384 resources = req['resources'] 543 inaccessible= [ t for n in resources['node'] \544 if n.has_key('hardware') != None\385 restricted = [ t for n in resources['node'] \ 386 if n.has_key('hardware') \ 545 387 for t in n['hardware'] \ 546 if t in self.restricted and \ 547 t not in found[0].node_types] 388 if t in self.restricted ] 389 inaccessible = [ t for t in restricted \ 390 if t not in found[0].node_types] 548 391 if len(inaccessible) > 0: 549 raise fedd_proj.service_error(fedd_proj.service_error.access,392 raise service_error(service_error.access, 550 393 "Access denied (nodetypes %s)" % \ 551 394 str(', ').join(inaccessible)) … … 555 398 556 399 if len(ssh) > 0: 557 if dyn[1]: self.dynamic_project(found, ssh) 400 if dyn[1]: 401 # Compose the dynamic project request 402 # (only dynamic, dynamic currently allowed) 403 preq = { 'project' : {\ 404 'user': [ \ 405 { 'access': { 'sshPubkey': s } } \ 406 for s in ssh ] \ 407 }\ 408 } 409 if restricted != None and len(restricted) > 0: 410 preq['resources'] = [ {'node': { 'hardware' : [ h ]\ 411 } } for h in restricted ] 412 413 414 #self.dynamic_project(found, ssh) 415 ap = self.allocate_project.dynamic_project(preq) 416 # XXX: fill in response values into the real response 558 417 else: pass # SSH key additions 559 418 else: 560 raise fedd_proj.service_error(service_error.req,419 raise service_error(service_error.req, 561 420 "SSH access parameters required") 562 421 563 resp = self.build_response(req['allocID'], found, ssh)422 resp = self.build_response(req['allocID'], ap) 564 423 return resp 565 424 else: … … 568 427 # Proxy the request using SOAP 569 428 return self.proxy_request(dt, req) 570 except fedd_proj.service_error, e:571 if e.code == fedd_proj.service_error.proxy: p_fault = None429 except service_error, e: 430 if e.code == service_error.proxy: p_fault = None 572 431 else: raise 573 432 except ZSI.FaultException, f: … … 584 443 body = p_fault.get_element_RequestAccessFaultBody() 585 444 if body != None: 586 raise fedd_proj.service_error(body.get_element_code(),445 raise service_error(body.get_element_code(), 587 446 body.get_element_desc()); 588 447 else: 589 raise fedd_proj.service_error(\590 fedd_proj.service_error.proxy,448 raise service_error(\ 449 service_error.proxy, 591 450 "Undefined fault from proxy??"); 592 451 … … 595 454 596 455 msg = self.RequestAccess(unpack_soap(req), fedid) 597 456 598 457 resp = RequestAccessResponseMessage() 599 458 resp.set_element_RequestAccessResponseBody( … … 608 467 return xmlrpclib.dumps(({ "RequestAccessResponseBody": msg },)) 609 468 else: 610 raise service_error( fedd_proj.service_error.internal,469 raise service_error(service_error.internal, 611 470 "No response generated?!"); 612 471 … … 782 641 try: 783 642 return getattr(self, fedd_proj.soap_methods[method])(req, fid) 784 except fedd_proj.service_error, e:643 except service_error, e: 785 644 de = ns0.faultType_Def( 786 645 (ns0.faultType_Def.schema, … … 800 659 try: 801 660 return getattr(self, fedd_proj.xmlrpc_methods[method])(req, fid) 802 except fedd_proj.service_error, e:661 except service_error, e: 803 662 raise xmlrpclib.Fault(e.code_string(), e.desc) 804 663 else: -
fedd/fedd_types.xsd
r21a1c30 r7da9da6 139 139 <xsd:element name="fedAttr" type="tns:fedAttrType" minOccurs="0" 140 140 maxOccurs="unbounded"/> 141 </xsd:sequence> 142 </xsd:complexType> 143 144 <xsd:complexType name="projectAllocType"> 145 <xsd:annotation> 146 <xsd:documentation> 147 The information needed to create a dynamic project 148 </xsd:documentation> 149 </xsd:annotation> 150 <xsd:sequence> 151 <xsd:element name="project" type="tns:projectType"/> 152 <xsd:element name="resources" type="tns:resourcesType" 153 minOccurs="0" maxOccurs="1"/> 141 154 </xsd:sequence> 142 155 </xsd:complexType>
Note: See TracChangeset
for help on using the changeset viewer.