Index: fedd/fedd_to_abac.py
===================================================================
--- fedd/fedd_to_abac.py	(revision 62f3dd9d96f5443be02f059e213f4d3f2b67d2e0)
+++ fedd/fedd_to_abac.py	(revision e65150a65448346cf2a8672b39c30e8089a5fde7)
@@ -7,7 +7,9 @@
 import os.path
 import subprocess
+from tempfile import mkdtemp
 
 from string import join
 
+from federation.authorizer import abac_authorizer
 from federation.util import abac_pem_type, abac_split_cert, file_expanding_opts
 
@@ -28,4 +30,11 @@
 	self.add_option('--debug', action='store_true', dest='debug',
 		default=False, help='Just print the creddy commands')
+	self.add_option('--policy_only', action='store_const', const=False,
+		dest='make_authorizer', default=True, 
+		help='Only create the directory of certs, " + \
+			"do not create an authorizer')
+	self.add_option('--update', action='store_const', const=True,
+		dest='update_authorizer', default=False, 
+		help='Add the generated policy to an existing authorizer')
 
 class identity:
@@ -40,11 +49,74 @@
 	return "%s: %s" % (self.name, join(self.roles, ', '))
 
-comment_re = re.compile('^\s*#|^$')
-fedid_str = 'fedid:([0-9a-fA-F]{40})'
-id_str = '[a-zA-Z][\w_-]*'
-single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str))
-double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \
-	(fedid_str, id_str, id_str))
-bad_role = re.compile('[^a-zA-Z0-9_]+')
+def clear_dir(dir):
+    for path, dirs, files in os.walk(dir, topdown=False):
+	for f in files: os.unlink(os.path.join(path, f))
+	for d in dirs: os.rmdir(os.path.join(path, d))
+
+def parse_configs(files):
+    """
+    Step through each file pulling the roles out of the database lines, if any,
+    and creating (or appending to) identity objects, one identity in a dict for
+    each  fedid.  Return that dict.  May raise an exception when file
+    difficulties occur.
+    """
+    comment_re = re.compile('^\s*#|^$')
+    fedid_str = 'fedid:([0-9a-fA-F]{40})'
+    id_str = '[a-zA-Z][\w_-]*'
+    single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str))
+    double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \
+	    (fedid_str, id_str, id_str))
+    bad_role = re.compile('[^a-zA-Z0-9_]+')
+
+    roles = { }
+
+    for fn in files:
+	f = open(fn, "r")
+	for l in f:
+	    id = None
+	    for r in (comment_re, single_re, double_re):
+		m = r.match(l)
+		if m: 
+		    # NB, the comment_re has no groups
+		    if m.groups():
+			g = m.groups()
+			id = g[0]
+			r = [ bad_role.sub('_', x) for x in g[1:] ]
+		    break
+	    else:
+		print 'Unmatched line: %s' % l 
+
+	    if id:
+		# New and create are implicit.  >sigh<
+		r.extend(('new', 'create'))
+		if id in roles: roles[id].add_roles(r)
+		else: roles[id] = identity(r[0], r)
+
+    return roles
+
+def make_credentials(roles, cert, key, creds_dir, debug):
+    """
+    From the dict of identities, indexed by fedid, call creddy to create the
+    ABAC certificates.  Return a list of the created files.  If debug is true,
+    just print the creddy commands.
+    """
+    credfiles = []
+    for k, id in roles.items():
+	for i, r in enumerate(id.roles):
+	    cf = '%s/%s%03d_attr.der' % \
+		    (creds_dir or 'new_cert_dir', id.name, i)
+	    cmd = ['creddy', '--attribute', 
+		    '--issuer=%s' % (cert or 'cert_file'),
+		    '--key=%s' % (key or 'key_file'), '--role=%s' % r,
+		    '--subject-id=%s' % k, '--out=%s' % cf ]
+	    if debug:
+		print join(cmd)
+	    else:
+		rv =  subprocess.call(cmd)
+		if rv != 0:
+		    raise RuntimeError('%s failed: %d' % (join(cmd), rv))
+		else:
+		    credfiles.append(cf)
+    return credfiles
 
 parser = Parser()
@@ -53,5 +125,6 @@
 delete_certs = False
 
-
+if not opts.make_authorizer and opts.update_authorizer:
+    sys.exit('--policy_only and --update are in conflict.  Pick one.')
 
 if opts.key:
@@ -72,4 +145,11 @@
 	    sys.exit('%s is not writable' % opts.dir)
 
+if opts.make_authorizer:
+    creds_dir = mkdtemp()
+    delete_creds = True
+else:
+    creds_dir = opts.dir
+    delete_creds = False
+
 if opts.cert:
     if os.access(opts.cert, os.R_OK):
@@ -90,50 +170,38 @@
     debug = opts.debug
 
-roles = { }
 try:
-    for fn in args:
-	try:
-	    f = open(fn, "r")
-	    for l in f:
-		id = None
-		for r in (comment_re, single_re, double_re):
-		    m = r.match(l)
-		    if m: 
-			if m.groups():
-			    g = m.groups()
-			    id = g[0]
-			    r = [ bad_role.sub('_', x) for x in g[1:] ]
-			break
-		else:
-		    print 'Unmatched line: %s' % l 
-		if id:
-		    # New and create are implicit.  >sigh<
-		    r.extend(('new', 'create'))
-		    if id in roles: roles[id].add_roles(r)
-		    else: roles[id] = identity(r[0], r)
-
-	except EnvironmentError, e:
-	    print >>sys.stderr, 'Cannot open file (%s): %s' % \
-		    (e.filename, e.strerror)
-
+    roles = parse_configs(args)
     if not roles:
 	print >>sys.stderr, "No roles found.  Did you specify a configuration?"
 
-    for k, id in roles.items():
-	for i, r in enumerate(id.roles):
-	    cmd = ['creddy', '--attribute', 
-		    '--issuer=%s' % (cert or 'cert_file'),
-		    '--key=%s' % (key or 'key_file'), '--role=%s' % r,
-		    '--subject-id=%s' % k,
-		    '--out=%s/%s%03d_attr.der' % \
-			    (opts.dir or 'new_cert_dir', id.name, i)]
+    try:
+	credfiles = make_credentials(roles, cert, key, creds_dir, debug)
+
+	if opts.make_authorizer:
 	    if debug:
-		print join(cmd)
+		print >>sys.stderr, 'Debug mode, no authorizer created'
+	    elif opts.update_authorizer:
+		operation = 'updat'
+		a = abac_authorizer(load=opts.dir)
+		a.import_credentials(file_list=credfiles)
+		a.save()
 	    else:
-		rv =  subprocess.call(cmd)
-		if rv != 0:
-		    sys.exit('%s failed: %d' % (join(cmd), rv))
+		operation = 'creat'
+		a = abac_authorizer(key=opts.key, me=opts.cert, 
+			certs=creds_dir, save=opts.dir)
+		a.save()
+    except EnvironmentError, e:
+	sys.exit("Can't create or write %s: %s" % (e.filename, 
+	    e.strerror))
+    except abac_authorizer.bad_cert_error, e:
+	sys.exit("Error %sing authorizer: %s" % (op, e))
+    except RuntimeError, e:
+	sys.exit('%s' % e)
+
 finally:
     if delete_certs:
 	if cert: os.unlink(cert)
 	if key: os.unlink(key)
+    if delete_creds:
+	clear_dir(creds_dir)
+	os.rmdir(creds_dir)
