Skip to content

Commit feffebe

Browse files
Merge pull request pandas-dev#22 from manahl/ceate_user_improvements
Enhance arctic_create_user
2 parents 4c94e75 + 4d5bd61 commit feffebe

File tree

3 files changed

+113
-145
lines changed

3 files changed

+113
-145
lines changed

arctic/scripts/arctic_create_user.py

+42-40
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,61 @@
1-
import optparse
2-
import pymongo
3-
import uuid
1+
import argparse
42
import base64
3+
from pymongo import MongoClient
4+
import uuid
5+
import logging
56

6-
from ..auth import get_auth, authenticate
77
from ..hooks import get_mongodb_uri
8-
from .utils import setup_logging
8+
from .utils import do_db_auth
9+
from arctic.arctic import Arctic
10+
11+
logger = logging.getLogger(__name__)
912

1013

1114
def main():
12-
usage = """usage: %prog [options] username ...
15+
usage = """arctic_create_user --host research [--db mongoose_user] [--write] user
1316
14-
Create the user's personal Arctic database, and adds them, read-only
15-
to the central admin database.
17+
Creates the user's personal Arctic mongo database
18+
Or add a user to an existing Mongo Database.
1619
"""
17-
setup_logging()
18-
parser = optparse.OptionParser(usage=usage)
19-
parser.add_option("--host", default='localhost', help="Hostname, or clustername. Default: localhost")
20-
parser.add_option("--password", dest="password", default=None, help="Password. Default: random")
21-
parser.add_option("--admin-write", dest="admin", action='store_false', default=True,
22-
help="Give write access to the admin DB. Default: False")
23-
parser.add_option("--dryrun", "-n", dest="dryrun", action="store_true", help="Don't really do anything", default=False)
24-
parser.add_option("--verbose", "-v", dest="verbose", action="store_true", help="Print some commentary", default=False)
25-
parser.add_option("--nodb", dest="nodb", help="Don't create a 'personal' database", action="store_true", default=False)
26-
27-
(opts, args) = parser.parse_args()
2820

29-
c = pymongo.MongoClient(get_mongodb_uri(opts.host))
30-
credentials = get_auth(opts.host, 'admin', 'admin')
31-
if not credentials:
32-
raise ValueError("You have no admin credentials for instance '%s'" % (opts.host))
21+
parser = argparse.ArgumentParser(usage=usage)
22+
parser.add_argument("--host", default='localhost', help="Hostname, or clustername. Default: localhost")
23+
parser.add_argument("--db", default=None, help="Database to add user on. Default: mongoose_<user>")
24+
parser.add_argument("--password", default=None, help="Password. Default: random")
25+
parser.add_argument("--write", action='store_true', default=False, help="Used for granting write access to someone else's DB")
26+
parser.add_argument("users", nargs='+', help="Users to add.")
3327

34-
if not authenticate(c.admin, credentials.user, credentials.password):
35-
raise ValueError("Failed to authenticate to '%s' as '%s'" % (opts.host, credentials.user))
28+
args = parser.parse_args()
3629

37-
for user in args:
30+
c = MongoClient(get_mongodb_uri(args.host))
3831

39-
p = opts.password
32+
if not do_db_auth(args.host, c, args.db if args.db else 'admin'):
33+
logger.error("Failed to authenticate to '%s'. Check your admin password!" % (args.host))
34+
return
4035

36+
for user in args.users:
37+
write_access = args.write
38+
p = args.password
4139
if p is None:
4240
p = base64.b64encode(uuid.uuid4().bytes).replace('/', '')[:12]
41+
db = args.db
42+
if not db:
43+
# Users always have write access to their database
44+
write_access = True
45+
db = Arctic.DB_PREFIX + '_' + user
46+
47+
# Add the user to the database
48+
c[db].add_user(user, p, read_only=not write_access)
49+
50+
logger.info("Granted: {user} [{permission}] to {db}".format(user=user,
51+
permission='WRITE' if write_access else 'READ',
52+
db=db))
53+
logger.info("User creds: {db}/{user}/{password}".format(user=user,
54+
host=args.host,
55+
db=db,
56+
password=p,
57+
))
4358

44-
if not opts.dryrun:
45-
if opts.verbose:
46-
print "Adding user %s to DB %s" % (user, opts.host)
47-
if not opts.nodb:
48-
if opts.verbose:
49-
print "Adding database arctic_%s to DB %s" % (user, opts.host)
50-
c['arctic_' + user].add_user(user, p)
51-
c.admin.add_user(user, p, read_only=opts.admin)
52-
else:
53-
print "DRYRUN: add user %s readonly %s nodb %s" % (user, opts.admin, opts.nodb)
54-
55-
if not opts.password:
56-
print "%-16s %s" % (user, p)
5759

5860
if __name__ == '__main__':
5961
main()

tests/integration/scripts/test_create_user.py

-105
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from mock import patch, sentinel, call, ANY
2+
3+
from arctic.scripts.arctic_create_user import main
4+
5+
from ...util import run_as_main
6+
7+
8+
def test_main_minimal():
9+
with patch('arctic.scripts.arctic_create_user.logger', autospec=True) as logger, \
10+
patch('arctic.scripts.arctic_create_user.MongoClient', autospec=True) as MC, \
11+
patch('arctic.scripts.arctic_create_user.get_mongodb_uri', autospec=True) as get_mongodb_uri, \
12+
patch('arctic.scripts.arctic_create_user.do_db_auth', autospec=True) as do_db_auth:
13+
run_as_main(main, '--host', 'some_host',
14+
'--password', 'asdf',
15+
'user')
16+
get_mongodb_uri.assert_called_once_with('some_host')
17+
MC.assert_called_once_with(get_mongodb_uri.return_value)
18+
assert do_db_auth.call_args_list == [call('some_host',
19+
MC.return_value,
20+
'admin')]
21+
assert MC.return_value.__getitem__.call_args_list == [call('arctic_user')]
22+
db = MC.return_value.__getitem__.return_value
23+
assert [call('user', ANY, read_only=False)] == db.add_user.call_args_list
24+
assert logger.info.call_args_list == [call('Granted: user [WRITE] to arctic_user'),
25+
call('User creds: arctic_user/user/asdf')]
26+
27+
28+
def test_main_with_db():
29+
with patch('arctic.scripts.arctic_create_user.MongoClient', autospec=True) as MC, \
30+
patch('arctic.scripts.arctic_create_user.get_mongodb_uri', autospec=True) as get_mongodb_uri, \
31+
patch('arctic.scripts.arctic_create_user.do_db_auth', autospec=True) as do_db_auth:
32+
run_as_main(main, '--host', 'some_host',
33+
'--db', 'some_db',
34+
'jblackburn')
35+
get_mongodb_uri.assert_called_once_with('some_host')
36+
MC.assert_called_once_with(get_mongodb_uri.return_value)
37+
assert do_db_auth.call_args_list == [call('some_host',
38+
MC.return_value,
39+
'some_db')]
40+
assert MC.return_value.__getitem__.call_args_list == [call('some_db')]
41+
db = MC.return_value.__getitem__.return_value
42+
assert [call('jblackburn', ANY, read_only=True)] == db.add_user.call_args_list
43+
44+
45+
def test_main_with_db_write():
46+
with patch('arctic.scripts.arctic_create_user.MongoClient', autospec=True) as MC, \
47+
patch('arctic.scripts.arctic_create_user.get_mongodb_uri', autospec=True) as get_mongodb_uri, \
48+
patch('arctic.scripts.arctic_create_user.do_db_auth', autospec=True) as do_db_auth:
49+
run_as_main(main, '--host', 'some_host',
50+
'--db', 'some_db',
51+
'--write',
52+
'jblackburn')
53+
get_mongodb_uri.assert_called_once_with('some_host')
54+
MC.assert_called_once_with(get_mongodb_uri.return_value)
55+
assert do_db_auth.call_args_list == [call('some_host',
56+
MC.return_value,
57+
'some_db')]
58+
assert MC.return_value.__getitem__.call_args_list == [call('some_db')]
59+
db = MC.return_value.__getitem__.return_value
60+
assert [call('jblackburn', ANY, read_only=False)] == db.add_user.call_args_list
61+
62+
63+
def test_no_auth():
64+
with patch('arctic.scripts.arctic_create_user.logger', autospec=True) as logger, \
65+
patch('arctic.scripts.arctic_create_user.MongoClient', autospec=True) as MC, \
66+
patch('arctic.scripts.arctic_create_user.get_mongodb_uri', autospec=True) as get_mongodb_uri, \
67+
patch('arctic.scripts.arctic_create_user.do_db_auth', autospec=True,
68+
return_value=False) as do_db_auth:
69+
run_as_main(main, '--host', 'some_host',
70+
'jblackburn')
71+
assert logger.error.call_args_list == [call("Failed to authenticate to 'some_host'. Check your admin password!")]

0 commit comments

Comments
 (0)