This is an automated email from the ASF dual-hosted git repository. csantanapr pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push: new 0f679ad Enhance wskadmin to list all spaces for a subject and add README (#3012) 0f679ad is described below commit 0f679adcf8cf1f29fde8f99c16f66a98e3ec021f Author: rodric rabbah <rod...@gmail.com> AuthorDate: Mon Nov 27 17:06:36 2017 -0500 Enhance wskadmin to list all spaces for a subject and add README (#3012) * Add flag to list all namespaces for a subject. * Add README for wskadmin. --- .../scala/whisk/core/admin/WskAdminTests.scala | 19 +++++ tools/admin/README.md | 82 ++++++++++++++++++++++ tools/admin/wskadmin | 33 ++++++--- tools/vagrant/README.md | 2 +- 4 files changed, 125 insertions(+), 11 deletions(-) diff --git a/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala b/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala index b2bc3b4..482bb5c 100644 --- a/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala +++ b/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala @@ -84,6 +84,25 @@ class WskAdminTests extends TestHelpers with Matchers { } } + it should "list all namespaces for a subject" in { + val wskadmin = new RunWskAdminCmd {} + val auth = AuthKey() + val subject = Subject().asString + try { + println(s"CRD subject: $subject") + val first = wskadmin.cli(Seq("user", "create", subject, "-ns", s"$subject.space1")) + val second = wskadmin.cli(Seq("user", "create", subject, "-ns", s"$subject.space2")) + wskadmin.cli(Seq("user", "get", subject, "--all")).stdout.trim should be { + s""" + |$subject.space1\t${first.stdout.trim} + |$subject.space2\t${second.stdout.trim} + |""".stripMargin.trim + } + } finally { + wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted") + } + } + it should "verify guest account installed correctly" in { val wskadmin = new RunWskAdminCmd {} implicit val wskprops = WskProps() diff --git a/tools/admin/README.md b/tools/admin/README.md new file mode 100644 index 0000000..912522e --- /dev/null +++ b/tools/admin/README.md @@ -0,0 +1,82 @@ +## Administrative Operations + +The `wskadmin` utility is handy for performing various administrative operations against an OpenWhisk deployment. +It allows you to create a new subject, manage their namespaces, to block a subject or delete their record entirely. +It also offers a convenient way to dump the asset, activation or subject databases and query their views. This is useful for debugging local deployments. +Lastly, it is a convenient way to inspect the system logs, or retrieve logs specific to a component or transaction id. + +### Managing Users (subjects) + +The `wskadmin user -h` command will print the help message for working with subject records. You can create and delete a new user, list all their namespaces or keys for a specific namespace, identify a user by their key, block/unblock a subject, and list all keys that have access to a particular namespace. + +Some examples: +```bash +# create a new user +$ wskadmin user create userA +<prints key> + +# add user to a specific namespace +$ wskadmin user create userA -ns space1 +<prints new key specific to userA and space1> + +# add second user to same space +$ wskadmin user create userB -ns space1 +<prints new key specific to userB and space1> + +# list all users sharing a space +$ wskadmin user list space1 -a +<key for userA> userA +<key for userB> userB + +# remove user access to a namespace +$ wskadmin user delete userB -ns space1 +Namespace deleted + +# get key for userA default namespaces +$ wskadmin user get userA +<prints key specific to userA default namespace> + +# block a user +$ wskadmin user block userA +"userA" blocked successfully + +# unblock a user +$ wskadmin user unblock userA +"userA" unblocked successfully + +# delete user +$ wskadmin user delete userB +Subject deleted +``` + +The `wskadmin limits` commands allow you set action and trigger throttles per namespace. + +```bash +# see if custom limits are set for a namespace +$ wskadmin limits get space1 +No limits found, default system limits apply + +# set limits +$ wskadmin limits set space1 --invocationsPerMinute 1 +Limits successfully set for "space1" +``` + +Note that limits apply to a namespace and will survive even if all users that share a namespace are deleted. You must manually delete them. +```bash +$ wskadmin limits delete space1 +Limits deleted +``` + +### Inspecting the Databases + +It is sometimes handy to inspect the database form the command line. The `wskadmin db get -h` command will print the help message for available utilities. +You can read the entire database with `wskadmin db get whisks`. Add `--docs` to include the full documents. To list specific views, use the `--view` option. +For example `wskadmin db get whisks --view whisks.v2/actions` will list the actions view only. + +### Inspecting System Logs + +For debugging a local deployment, `wskadmin syslog get` will show you the controller and invoker logs available. You can use `--grep` to grep the logs for specific patterns, or `--tid` to isolate logs specific to a specific transaction in the system. It is possible to isolate logs to a specific component (e.g., `controller0`). By default, logs are fetched from all available components. + + + + diff --git a/tools/admin/wskadmin b/tools/admin/wskadmin index 2dcdc7f..c23a7a9 100755 --- a/tools/admin/wskadmin +++ b/tools/admin/wskadmin @@ -103,6 +103,7 @@ def parseArgs(): subcmd = subparser.add_parser('get', help='get authorization key for user') subcmd.add_argument('subject', help='the subject to get key for') subcmd.add_argument('-ns', '--namespace', help='the namespace to get the key for, defaults to subject id') + subcmd.add_argument('-a', '--all', help='list all namespaces and their keys', action='store_true') subcmd = subparser.add_parser('whois', help='identify user from an authorization key') subcmd.add_argument('authkey', help='the credentials to look up') @@ -116,6 +117,7 @@ def parseArgs(): subcmd = subparser.add_parser('list', help='list authorization keys associated with a namespace') subcmd.add_argument('namespace', help='the namespace to lookup') subcmd.add_argument('-p', '--pick', metavar='N', help='show no more than N identities', type=int, default=1) + subcmd.add_argument('-a', '--all', help='show all identities', action='store_true') subcmd.add_argument('-k', '--key', help='show only the keys', action='store_true') propmenu = subparsers.add_parser('limits', help='manage namespace-specific limits') @@ -269,16 +271,23 @@ def getUserCmd(args, props): (doc, res) = getSubjectFromDb(args, props) if doc is not None: - # try default namespace if no namespace provided - namespaceName = args.namespace if args.namespace is not None else args.subject - namespaces = filter(lambda ns: ns['name'] == namespaceName, doc['namespaces']) - if len(namespaces) == 1: - ns = namespaces[0] - print('%s:%s' % (ns['uuid'], ns['key'])) + if args.all is True: + # tabulate name of each space and its key + for ns in doc['namespaces']: + print('%s\t%s:%s' % (ns['name'], ns['uuid'], ns['key'])) return 0 else: - print('namespace "%s" not found for "%s"' % (namespaceName, args.subject)) - return 1 + # if requesting key for specific namespace, report only that key; + # use default namespace if no namespace provided + namespaceName = args.namespace if args.namespace is not None else args.subject + namespaces = filter(lambda ns: ns['name'] == namespaceName, doc['namespaces']) + if len(namespaces) == 1: + ns = namespaces[0] + print('%s:%s' % (ns['uuid'], ns['key'])) + return 0 + else: + print('namespace "%s" not found for "%s"' % (namespaceName, args.subject)) + return 1 else: print('Failed to get subject (%s)' % res.read().strip()) return 1 @@ -291,7 +300,7 @@ def listUserCmd(args, props): return 2 if nslist is not None: - nslist = nslist[:args.pick] + nslist = nslist if args.all is True else nslist[:args.pick] if len(nslist) > 0: for p in nslist: print('%s:%s%s' % (p['uuid'], p['key'], "\t%s" % p['subject'] if not args.key else "")) @@ -522,7 +531,11 @@ def getLimitsCmd(args, props): if givenLimit != None: print('%s = %s' % (limit, givenLimit)) else: - print('Failed to get limits (%s)' % res.read().strip()) + error = json.loads(res.read()) + if error['reason'] == 'missing': + print('No limits found, default system limits apply') + else: + print('Failed to get limits (%s)' % res.read().strip()) return 1 def deleteLimitsCmd(args, props): diff --git a/tools/vagrant/README.md b/tools/vagrant/README.md index 2cb0767..e80a6d9 100644 --- a/tools/vagrant/README.md +++ b/tools/vagrant/README.md @@ -174,7 +174,7 @@ You can check that containers are running by using the docker cli with the comma An OpenWhisk user, also known as a *subject*, requires a valid authorization key. OpenWhisk is preconfigured with a guest key located in `ansible/files/auth.guest`. -You may use this key if you like, or use `wskadmin` inside the VM to create a new key. +You may use this key if you like, or use [`wskadmin`](../admin) inside the VM to create a new key. ``` vagrant ssh -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].