Author: tmckay
Date: 2011-02-25 20:10:28 +0000 (Fri, 25 Feb 2011)
New Revision: 4560
Modified:
trunk/cumin/bin/cumin-admin
Log:
Add export-users and import-users commands to cumin-admin.
BZ680260
Modified: trunk/cumin/bin/cumin-admin
===================================================================
--- trunk/cumin/bin/cumin-admin 2011-02-25 14:24:52 UTC (rev 4559)
+++ trunk/cumin/bin/cumin-admin 2011-02-25 20:10:28 UTC (rev 4560)
@@ -2,6 +2,7 @@
import os
import sys
+import csv
from psycopg2 import IntegrityError
@@ -70,6 +71,9 @@
finally:
cursor.close()
+def warn(msg):
+ print "Warning: %s" % msg
+
def error(msg):
print "Error: %s" % msg
sys.exit(1)
@@ -88,6 +92,8 @@
lines.append(" change-password USER Change USER's password")
lines.append(" list-users List users")
lines.append(" list-roles List roles")
+ lines.append(" export-users FILE Export user list to file")
+ lines.append(" import-users FILE Import user list from file")
lines.append("")
lines.append("Schema commands:")
lines.append("")
@@ -119,7 +125,7 @@
print "The schema is dropped"
-def handle_list_users(app, cursor, opts, args):
+def get_users(app, cursor):
user_cls = app.model.com_redhat_cumin.User
role_cls = app.model.com_redhat_cumin.Role
mapping_cls = app.model.com_redhat_cumin.UserRoleMapping
@@ -143,9 +149,15 @@
for id, name in cursor.fetchall():
roles_by_user_id[id].append(name)
+ return users, roles_by_user_id
+
+def handle_list_users(app, cursor, opts, args):
+
print " ID Name Roles"
print "---- -------------------- --------------------"
+ users, roles_by_user_id = get_users(app, cursor)
+
for user in users:
try:
roles = ", ".join(roles_by_user_id[user._id])
@@ -183,6 +195,80 @@
print "User '%s' is added" % name
+def handle_export_users(app, cursor, opts, args):
+
+ try:
+ fname = args[0]
+ except IndexError:
+ error("Export file name is required")
+
+ try:
+ f = open(fname,"wb")
+ except:
+ error("Failed to open file " + fname)
+
+ users, roles_by_user_id = get_users(app, cursor)
+
+ w = csv.writer(f)
+ for user in users:
+ w.writerow([user.name, user.password] + roles_by_user_id[user._id])
+
+def handle_import_users(app, cursor, opts, args):
+
+ try:
+ fname = args[0]
+ except IndexError:
+ error("Import file name is required")
+
+ try:
+ f = open(fname,"rb")
+ except:
+ error("Failed to open file " + fname)
+
+ user_data = csv.reader(f)
+
+ # Before we make any changes, check the format to be nice
+ line = 0
+ for info in user_data:
+ line += 1
+
+ for field in info:
+ # Don't suppose it's possible for data to be anything other than
+ # strings from csv, but this is where such type checking goes
+ if type(field) != str:
+ error("Data error, line %u, fields must be strings" % line)
+ if len(field) == 0:
+ error("Data error, line %u, importer "\
+ "does not allow empty fields" % line)
+
+ if len(info) < 2:
+ error("Data error, line %u, not enough fields. "\
+ " User and password are required" % (line))
+
+ # Reset the reader
+ f.seek(0)
+ for info in user_data:
+ #name, password, [role, ...]
+ if app.admin.get_user(cursor, info[0]):
+ # Well, we might be extending an existing user database
+ # and there *might* be overlap between the two. Check first
+ # before we get an integrity error
+ warn("A user called '%s' already exists, skipping" %
info[0])
+ continue
+
+ try:
+ user = app.admin.add_user(cursor, info[0], info[1])
+ except IntegrityError:
+ error("Unable to add user")
+
+ for role_name in info[2:]:
+ role = app.admin.get_role(cursor, role_name)
+ if role != None:
+ app.admin.add_assignment(cursor, user, role)
+ else:
+ warn("Role '%s' does not exist, "\
+ "skipping this role for user '%s'" % (role_name,
info[0]))
+
def handle_remove_user(app, cursor, opts, args):
try:
name = args[0]