source: fedd/fedd_allocate_project.py @ 7da9da6

axis_examplecompt_changesinfo-opsversion-1.30version-2.00version-3.01version-3.02
Last change on this file since 7da9da6 was 7da9da6, checked in by Ted Faber <faber@…>, 16 years ago

split out project creation. Local project creation works

  • Property mode set to 100644
File size: 4.6 KB
Line 
1#!/usr/local/bin/python
2
3import os,sys
4
5from BaseHTTPServer import BaseHTTPRequestHandler
6from ZSI import *
7from M2Crypto import SSL
8from M2Crypto.m2xmlrpclib import SSL_Transport
9from M2Crypto.SSL.SSLServer import SSLServer
10import M2Crypto.httpslib
11import xmlrpclib
12
13import re
14import random
15import string
16import subprocess
17import tempfile
18import copy
19
20from fedd_services import *
21from fedd_util import *
22import parse_detail
23
24class fedd_allocate_project_local:
25    def __init__(self, dp=False, url=None):
26        """
27        Initializer.  Parses a configuration if one is given.
28        """
29
30        self.dynamic_projects = dp
31        self.wap = '/usr/testbed/sbin/wap'
32        self.newproj = '/usr/testbed/sbin/newproj'
33        self.mkproj = '/usr/testbed/sbin/mkproj'
34        self.grantnodetype = '/usr/testbed/sbin/grantnodetype'
35
36    def random_string(self, s, n=3):
37        """Append n random ASCII characters to s and return the string"""
38        rv = s
39        for i in range(0,n):
40            rv += random.choice(string.ascii_letters)
41        return rv
42
43    def write_attr_xml(self, file, root, lines):
44        """
45        Write an emulab config file for a dynamic project.
46
47        Format is <root><attribute name=lines[0]>lines[1]</attribute></root>
48        """
49        # Convert a pair to an attribute line
50        out_attr = lambda a,v : \
51                '<attribute name="%s"><value>%s</value></attribute>' % (a, v)
52
53        f = os.fdopen(file, "w")
54        f.write("<%s>\n" % root)
55        f.write("\n".join([out_attr(*l) for l in lines]))
56        f.write("</%s>\n" % root)
57        f.close()
58
59
60    def dynamic_project(self, req):
61        """
62        Create a dynamic project with ssh access
63
64        Req includes the project and resources as a dictionary
65        """
66        # tempfiles for the parameter files
67        uf, userfile = tempfile.mkstemp(prefix="usr", suffix=".xml",
68                dir="/tmp")
69        pf, projfile = tempfile.mkstemp(prefix="proj", suffix=".xml",
70                dir="/tmp")
71
72        print userfile
73        proj = req['project']
74        # Take the first user and ssh key
75        name = proj.get('name', None) or self.random_string("proj",4)
76        user = proj.get('user', None)
77        if user != None:
78            user = user[0]      # User is a list, take the first entry
79            if not user.has_key("userID"):
80                uname = self.random_string("user", 3)
81            else:
82                uid = proj['userID']
83                # XXX: fedid
84                uname = uid.get('username', None) or \
85                        uid.get('kerberosUsername', None) or \
86                        uid.get('uri', None)
87                if uname == None:
88                    raise fedd_proj.service_error(fedd_proj.service_error.req, 
89                            "No ID for user");
90
91            access = user.get('access', None)
92            if access != None:
93                ssh = access.get('sshPubkey', None)
94                if ssh == None:
95                    raise fedd_proj.service_error(fedd_proj.service_error.req, 
96                            "No ssh key for user");
97        else:
98            raise fedd_proj.service_error(fedd_proj.service_error.req, 
99                    "No access information for project");
100
101        # uname, name and ssh are set
102        user_fields = [
103                ("name", "Federation User %s" % uname),
104                ("email", "%s-fed@isi.deterlab.net" % uname),
105                ("password", self.random_string("", 8)),
106                ("login", uname),
107                ("address", "4676 Admiralty"),
108                ("city", "Marina del Rey"),
109                ("state", "CA"),
110                ("zip", "90292"),
111                ("country", "USA"),
112                ("phone", "310-448-9190"),
113                ("title", "None"),
114                ("affiliation", "USC/ISI"),
115                ("pubkey", ssh)
116        ]
117
118        proj_fields = [
119                ("name", name),
120                ("short description", "dynamic federated project"),
121                ("URL", "http://www.isi.edu/~faber"),
122                ("funders", "USC/USU"),
123                ("long description", "Federation access control"),
124                ("public", "1"),
125                ("num_pcs", "100"),
126                ("linkedtous", "1"),
127                ("newuser_xml", userfile)
128        ]
129       
130
131        # Write out the files
132        self.write_attr_xml(uf, "user", user_fields)
133        self.write_attr_xml(pf, "project", proj_fields)
134
135        # Generate the commands (only grantnodetype's are dynamic)
136        cmds = [
137                (self.wap, self.newproj, projfile),
138                (self.wap, self.mkproj, name)
139                ]
140
141        # Add commands to grant access to any resources in the request.
142        for nt in [ h for r in req.get('resources', []) \
143                if r.has_key('node') and r['node'].has_key('hardware')\
144                    for h in r['node']['hardware'] ] :
145            cmds.append((self.wap, self.grantnodetype, '-p', name, nt))
146
147        # Create the projects
148        rc = 0
149        for cmd in cmds:
150            if self.dynamic_projects:
151                try:
152                    rc = subprocess.call(cmd)
153                except OSerror, e:
154                    raise fedd_proj.service_error(\
155                            fedd_proj.service_error.internal,
156                            "Dynamic project subprocess creation error "+ \
157                                    "[%s] (%s)" %  (cmd[1], e.strerror))
158            else:
159                print >>sys.stdout, str(" ").join(cmd)
160
161            if rc != 0: 
162                raise fedd_proj.service_error(\
163                        fedd_proj.service_error.internal,
164                        "Dynamic project subprocess error " +\
165                                "[%s] (%d)" % (cmd[1], rc))
166        # Clean up tempfiles
167        os.unlink(userfile)
168        os.unlink(projfile)
169        rv = {\
170            'project': {\
171                'name': { 'username': name }, 
172                'user' : [ {\
173                    'userID': { 'username' : uname },
174                    'access': [ { 'sshPubkey' : ssh } ],
175                } ]\
176            }\
177        }
178        return rv
Note: See TracBrowser for help on using the repository browser.