]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
MonCommands: add new fields: modulename, perms, availability
authorDan Mick <dan.mick@inktank.com>
Wed, 10 Jul 2013 23:12:56 +0000 (16:12 -0700)
committerDan Mick <dan.mick@inktank.com>
Thu, 11 Jul 2013 02:02:30 +0000 (19:02 -0700)
To help optimize the REST API, we need to know whether the commands
are read (GET) or write (PUT/POST).  However, we also could use that
same info for permission/caps checking.  Add modulename/perms as
the required caps for each command to drive both needs.

The availability field is to control whether a command is displayed/
advertised through the CLI or REST interfaces; some commands aren't
really useful for REST, and we may want to invent REST-only commands;
also, this gives us a way to deprecate commands quickly and leave the
code, should that be desirable.  Make the CLI display only commands
marked with the 'CLI' marker.

Also stop renaming 'help' to 'helptext' in the client.

Signed-off-by: Dan Mick <dan.mick@inktank.com>
src/ceph.in
src/common/cmdparse.cc
src/common/cmdparse.h
src/mon/MonCommands.h
src/mon/Monitor.cc
src/pybind/ceph_argparse.py

index 78dde742b3fb7664f77d57b9e03b340514bab1a7..be0a512dd7d92de8baa30db1fc5e5dbaa253a331 100755 (executable)
@@ -167,7 +167,8 @@ def do_help(parser, args, help_all = False):
                 "couldn't get command descriptions for {0}: {1}".\
                 format(target, outs)
         else:
-            sys.stdout.write(format_help(parse_json_funcsigs(outbuf), partial))
+            sys.stdout.write(format_help(parse_json_funcsigs(outbuf, 'cli'),
+                             partial))
 
     parser.print_help()
     print '\n'
@@ -183,21 +184,21 @@ def do_help(parser, args, help_all = False):
             help_for_target(target=('osd', osdids()[0]))
 
             print '\nOSD daemon commands:\n\n'
-            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'osd.' + firstosd), ['get_command_descriptions']))))
+            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'osd.' + firstosd), ['get_command_descriptions']), 'cli')))
         except:
             pass
 
         try:
             firstmon = monids()[0]
             print '\nmon.{0} daemon commands:\n\n'.format(firstmon)
-            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mon.' + firstmon), ['get_command_descriptions']))))
+            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mon.' + firstmon), ['get_command_descriptions']), 'cli')))
         except:
             pass
 
         try:
             firstmds = mdsids()[0]
             print '\nmds.{0} daemon commands:\n\n'.format(firstmds)
-            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mds.' + firstmds), ['get_command_descriptions']))))
+            sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mds.' + firstmds), ['get_command_descriptions']), 'cli')))
         except:
             pass
 
@@ -274,13 +275,13 @@ def format_help(cmddict, partial=None):
     fullusage = ''
     for cmd in sorted(cmddict.itervalues(), cmp=descsort):
 
-        if not cmd['helptext']:
+        if not cmd['help']:
             continue
         concise = concise_sig(cmd['sig'])
         if partial and not concise.startswith(partial):
             continue
         siglines = [l for l in wrap(concise, 40, 1)]
-        helplines = [l for l in wrap(cmd['helptext'], 39, 1)]
+        helplines = [l for l in wrap(cmd['help'], 39, 1)]
 
         # make lists the same length
         maxlen = max(len(siglines), len(helplines))
@@ -693,7 +694,7 @@ def main():
             if ret < 0:
                 outs = 'problem getting command descriptions from {0}.{1}'.format(*target)
         else:
-            sigdict = parse_json_funcsigs(outbuf)
+            sigdict = parse_json_funcsigs(outbuf, 'cli')
 
             if parsed_args.completion:
                 return complete(sigdict, childargs, target)
index 23e67f6de1b37e8c4b89bee9256fbe76cd5d35ee..26bcde3fdac7effb28ed0bdc8af3ddd1541bc6b7 100644 (file)
@@ -90,6 +90,26 @@ dump_cmd_and_help_to_json(JSONFormatter *jf,
       jf->close_section(); // cmd
 }
 
+void
+dump_cmddesc_to_json(JSONFormatter *jf,
+                    const string& secname,
+                    const string& cmdsig,
+                    const string& helptext,
+                    const string& module,
+                    const string& perm,
+                    const string& avail)
+{
+      jf->open_object_section(secname.c_str());
+      jf->open_array_section("sig");
+      dump_cmd_to_json(jf, cmdsig);
+      jf->close_section(); // sig array
+      jf->dump_string("help", helptext.c_str());
+      jf->dump_string("module", module.c_str());
+      jf->dump_string("perm", perm.c_str());
+      jf->dump_string("avail", avail.c_str());
+      jf->close_section(); // cmd
+}
+
 /** Parse JSON in vector cmd into a map from field to map of values
  * (use mValue/mObject)
  * 'cmd' should not disappear over lifetime of map
index df8f570c46b7f264aeff80c4ee82481cac8f3daa..f258969fb687434f1244f7b26bc39510d6b118ab 100644 (file)
@@ -24,6 +24,13 @@ void dump_cmd_and_help_to_json(ceph::JSONFormatter *f,
                               const std::string& secname,
                               const std::string& cmd,
                               const std::string& helptext);
+void dump_cmddesc_to_json(JSONFormatter *jf,
+                         const std::string& secname,
+                         const std::string& cmdsig,
+                         const std::string& helptext,
+                         const std::string& module,
+                         const std::string& perm,
+                         const std::string& avail);
 bool cmdmap_from_json(std::vector<std::string> cmd, cmdmap_t *mapp,
                      std::stringstream &ss);
 void handle_bad_get(CephContext *cct, std::string k, const char *name);
index 93c3801fb0b58e147e487f9c7f0b4bc32ffb8316..74f52bad87dedd97149254dd051f4be5a847f645 100644 (file)
  * frontend 'ceph' (and perhaps by other frontends, such as a RESTful
  * server). The format is:
  *
- * COMMAND(signature, helpstring)
+ * COMMAND(signature, helpstring, modulename, req perms, availability)
+ * where:
+ * signature:  describes the command and its parameters (more below)
+ * helpstring: displays in CLI help, API help (nice if it refers to
+ *             parameter names from signature, 40-a few hundred chars)
+ * modulename: the monitor module or daemon this applies to:
+ *             mds, osd, pg (osd), mon, auth, log, config-key
+ * req perms:  required permission in that modulename space to execute command
+ *             this also controls what type of REST command is accepted
+ * availability: cli, rest, or both
  *
  * The commands describe themselves completely enough for the separate
  * frontend(s) to be able to accept user input and validate it against
  * pg commands PgMonitor.cc
  */
 
-COMMAND("pg stat", "show placement group status.")
-COMMAND("pg getmap", "get binary pg map to -o/stdout")
-COMMAND("pg send_pg_creates", "trigger pg creates to be issued")
+COMMAND("pg stat", "show placement group status.", "pg", "r", "cli,rest")
+COMMAND("pg getmap", "get binary pg map to -o/stdout", "pg", "r", "cli,rest")
+COMMAND("pg send_pg_creates", "trigger pg creates to be issued",\
+       "pg", "rw", "cli,rest")
 COMMAND("pg dump " \
        "name=dumpcontents,type=CephChoices,strings=all|summary|sum|pools|osds|pgs,n=N,req=false", \
-       "show human-readable versions of pg map")
+       "show human-readable versions of pg map", "pg", "r", "cli,rest")
 COMMAND("pg dump_json " \
        "name=dumpcontents,type=CephChoices,strings=all|summary|sum|pools|osds|pgs,n=N,req=false", \
-       "show human-readable version of pg map in json only")
-COMMAND("pg dump_pools_json", "show pg pools info in json only")
+       "show human-readable version of pg map in json only",\
+       "pg", "r", "cli,rest")
+COMMAND("pg dump_pools_json", "show pg pools info in json only",\
+       "pg", "r", "cli,rest")
 COMMAND("pg dump_stuck " \
        "name=stuckops,type=CephChoices,strings=inactive|unclean|stale,n=N,req=false " \
        "name=threshold,type=CephInt,req=false",
-       "show information about stuck pgs [--threshold=seconds to consider stuck]")
-COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds")
-COMMAND("pg scrub name=pgid,type=CephPgid", "start scrub on <pgid>")
-COMMAND("pg deep-scrub name=pgid,type=CephPgid", "start deep-scrub on <pgid>")
-COMMAND("pg repair name=pgid,type=CephPgid", "start repair on <pgid>")
+       "show information about stuck pgs [--threshold=seconds to consider stuck]",\
+       "pg", "r", "cli,rest")
+COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds", \
+       "pg", "r", "cli,rest")
+COMMAND("pg scrub name=pgid,type=CephPgid", "start scrub on <pgid>", \
+       "pg", "rw", "cli,rest")
+COMMAND("pg deep-scrub name=pgid,type=CephPgid", "start deep-scrub on <pgid>", \
+       "pg", "rw", "cli,rest")
+COMMAND("pg repair name=pgid,type=CephPgid", "start repair on <pgid>", \
+       "pg", "rw", "cli,rest")
 COMMAND("pg debug " \
        "name=debugop,type=CephChoices,strings=unfound_objects_exist|degraded_pgs_exist", \
-       "show debug info about pgs")
+       "show debug info about pgs", "pg", "r", "cli,rest")
 COMMAND("pg force_create_pg name=pgid,type=CephPgid", \
-       "force creation of pg <pgid>")
+       "force creation of pg <pgid>", "pg", "rw", "cli,rest")
 COMMAND("pg set_full_ratio name=ratio,type=CephFloat,range=0.0|1.0", \
-       "set ratio at which pgs are considered full")
+       "set ratio at which pgs are considered full", "pg", "rw", "cli,rest")
 COMMAND("pg set_nearfull_ratio name=ratio,type=CephFloat,range=0.0|1.0", \
-       "set ratio at which pgs are considered nearly full")
+       "set ratio at which pgs are considered nearly full", \
+       "pg", "rw", "cli,rest")
 
 /*
  * auth commands AuthMonitor.cc
  */
 
 COMMAND("auth export name=entity,type=CephString,req=false", \
-               "write keyring for requested entity, or master keyring if none given")
+               "write keyring for requested entity, or master keyring if none given", \
+       "auth", "r", "cli,rest")
 COMMAND("auth get name=entity,type=CephString", \
-       "write keyring file with requested key")
-COMMAND("auth get-key name=entity,type=CephString", "display requested key")
-COMMAND("auth print-key name=entity,type=CephString", "display requested key")
-COMMAND("auth print_key name=entity,type=CephString", "display requested key")
-COMMAND("auth list", "list authentication state")
-COMMAND("auth import", "auth import: read keyring file from input")
+       "write keyring file with requested key", "auth", "r", "cli,rest")
+COMMAND("auth get-key name=entity,type=CephString", "display requested key", \
+       "auth", "r", "cli,rest")
+COMMAND("auth print-key name=entity,type=CephString", "display requested key", \
+       "auth", "r", "cli,rest")
+COMMAND("auth print_key name=entity,type=CephString", "display requested key", \
+       "auth", "r", "cli,rest")
+COMMAND("auth list", "list authentication state", "auth", "r", "cli,rest")
+COMMAND("auth import", "auth import: read keyring file from input", \
+       "auth", "rw", "cli,rest")
 COMMAND("auth add " \
        "name=entity,type=CephString " \
        "name=caps,type=CephString,n=N,req=false", \
-       "add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command")
+       "add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command",
+       "auth", "rw", "cli,rest")
 COMMAND("auth get-or-create-key " \
        "name=entity,type=CephString " \
        "name=caps,type=CephString,n=N,req=false", \
-       "get, or add, key for <name> from system/caps pairs specified in the command.  If key already exists, any given caps must match the existing caps for that key.")
+       "get, or add, key for <name> from system/caps pairs specified in the command.  If key already exists, any given caps must match the existing caps for that key.", \
+       "auth", "rw", "cli,rest")
 COMMAND("auth get-or-create " \
        "name=entity,type=CephString " \
        "name=caps,type=CephString,n=N,req=false", \
-       "add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command")
+       "add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command", \
+       "auth", "rw", "cli,rest")
 COMMAND("auth caps " \
        "name=entity,type=CephString " \
        "name=caps,type=CephString,n=N", \
-       "update caps for <name> from caps specified in the command")
+       "update caps for <name> from caps specified in the command", \
+       "auth", "rw", "cli,rest")
 COMMAND("auth del " \
        "name=entity,type=CephString", \
-       "delete all caps for <name>")
+       "delete all caps for <name>", \
+       "auth", "rw", "cli,rest")
 
 /*
  * Monitor commands (Monitor.cc)
  */
-COMMAND("compact", "cause compaction of monitor's leveldb storage")
-COMMAND("scrub", "scrub the monitor stores")
-COMMAND("fsid", "show cluster FSID/UUID")
+COMMAND("compact", "cause compaction of monitor's leveldb storage", \
+       "mon", "rw", "cli,rest")
+COMMAND("scrub", "scrub the monitor stores", "mon", "rw", "cli,rest")
+COMMAND("fsid", "show cluster FSID/UUID", "mon", "r", "cli,rest")
 COMMAND("log name=logtext,type=CephString,n=N", \
-       "log supplied text to the monitor log")
+       "log supplied text to the monitor log", "mon", "rw", "cli,rest")
 COMMAND("injectargs " \
        "name=injected_args,type=CephString,n=N", \
-       "inject config arguments into monitor")
-COMMAND("status", "show cluster status")
+       "inject config arguments into monitor", "mon", "rw", "cli,rest")
+COMMAND("status", "show cluster status", "mon", "r", "cli,rest")
 COMMAND("health name=detail,type=CephChoices,strings=detail,req=false", \
-       "show cluster health")
+       "show cluster health", "mon", "r", "cli,rest")
 COMMAND("df name=detail,type=CephChoices,strings=detail,req=false", \
-       "show cluster free space stats")
+       "show cluster free space stats", "mon", "r", "cli,rest")
 COMMAND("report name=tags,type=CephString,n=N,req=false", \
-       "report full status of cluster, optional title tag strings")
-COMMAND("quorum_status", "report status of monitor quorum")
-COMMAND("mon_status", "report status of monitors")
-COMMAND("sync status", "report status of monitors")
+       "report full status of cluster, optional title tag strings", \
+       "mon", "r", "cli,rest")
+COMMAND("quorum_status", "report status of monitor quorum", \
+       "mon", "r", "cli,rest")
+COMMAND("mon_status", "report status of monitors", "mon", "r", "cli,rest")
+COMMAND("sync status", "report status of monitors", "mon", "r", "cli,rest")
 COMMAND("sync force " \
        "name=validate1,type=CephChoices,strings=--yes-i-really-mean-it " \
        "name=validate2,type=CephChoices,strings=--i-know-what-i-am-doing", \
-       "force sync of and clear monitor store")
+       "force sync of and clear monitor store", "mon", "rw", "cli,rest")
 COMMAND("heap " \
        "name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \
-       "show heap usage info (available only if compiled with tcmalloc)")
+       "show heap usage info (available only if compiled with tcmalloc)", \
+       "mon", "rw", "cli,rest")
 COMMAND("quorum name=quorumcmd,type=CephChoices,strings=enter|exit,n=1", \
-       "enter or exit quorum")
+       "enter or exit quorum", "mon", "rw", "cli,rest")
 COMMAND("tell " \
        "name=target,type=CephName " \
        "name=args,type=CephString,n=N", \
-       "send a command to a specific daemon")
+       "send a command to a specific daemon", "mon", "rw", "cli,rest")
 
 /*
  * MDS commands (MDSMonitor.cc)
  */
 
-COMMAND("mds stat", "show MDS status")
-COMMAND("mds dump " \
+COMMAND("mds stat", "show MDS status", "mds", "r", "cli,rest")
+COMMAND("mds dump " 
        "name=epoch,type=CephInt,req=false,range=0", \
-       "dump info, optionally from epoch")
+       "dump info, optionally from epoch", "mds", "r", "cli,rest")
 COMMAND("mds getmap " \
        "name=epoch,type=CephInt,req=false,range=0", \
-       "get MDS map, optionally from epoch")
+       "get MDS map, optionally from epoch", "mds", "r", "cli,rest")
 COMMAND("mds tell " \
        "name=who,type=CephString " \
        "name=args,type=CephString,n=N", \
-       "send command to particular mds")
-COMMAND("mds compat show", "show mds compatibility settings")
-COMMAND("mds stop name=who,type=CephString", "stop mds")
-COMMAND("mds deactivate name=who,type=CephString", "stop mds")
+       "send command to particular mds", "mds", "rw", "cli,rest")
+COMMAND("mds compat show", "show mds compatibility settings", \
+       "mds", "r", "cli,rest")
+COMMAND("mds stop name=who,type=CephString", "stop mds", \
+       "mds", "rw", "cli,rest")
+COMMAND("mds deactivate name=who,type=CephString", "stop mds", \
+       "mds", "rw", "cli,rest")
 COMMAND("mds set_max_mds " \
        "name=maxmds,type=CephInt,range=0", \
-       "set max MDS index")
+       "set max MDS index", "mds", "rw", "cli,rest")
 COMMAND("mds setmap " \
        "name=epoch,type=CephInt,range=0", \
-       "set mds map; must supply correct epoch number")
+       "set mds map; must supply correct epoch number", "mds", "rw", "cli,rest")
 // arbitrary limit 0-20 below; worth standing on head to make it
 // relate to actual state definitions?
 // #include "include/ceph_fs.h"
 COMMAND("mds set_state " \
        "name=gid,type=CephInt,range=0 " \
        "name=state,type=CephInt,range=0|20", \
-       "set mds state of <gid> to <numeric-state>")
+       "set mds state of <gid> to <numeric-state>", "mds", "rw", "cli,rest")
 COMMAND("mds fail name=who,type=CephString", \
-       "force mds to status failed")
+       "force mds to status failed", "mds", "rw", "cli,rest")
 COMMAND("mds rm " \
        "name=gid,type=CephInt,range=0 " \
        "name=who,type=CephName", \
-       "remove nonactive mds")
-COMMAND("mds rmfailed name=who,type=CephInt,range=0", "remove failed mds")
-COMMAND("mds cluster_down", "take MDS cluster down")
-COMMAND("mds cluster_up", "bring MDS cluster up")
+       "remove nonactive mds", "mds", "rw", "cli,rest")
+COMMAND("mds rmfailed name=who,type=CephInt,range=0", "remove failed mds", \
+       "mds", "rw", "cli,rest")
+COMMAND("mds cluster_down", "take MDS cluster down", "mds", "rw", "cli,rest")
+COMMAND("mds cluster_up", "bring MDS cluster up", "mds", "rw", "cli,rest")
 COMMAND("mds compat rm_compat " \
        "name=feature,type=CephInt,range=0", \
-       "remove compatible feature")
+       "remove compatible feature", "mds", "rw", "cli,rest")
 COMMAND("mds compat rm_incompat " \
        "name=feature,type=CephInt,range=0", \
-       "remove incompatible feature")
+       "remove incompatible feature", "mds", "rw", "cli,rest")
 COMMAND("mds add_data_pool " \
        "name=poolid,type=CephInt,range=0", \
-       "add data pool <poolid>")
+       "add data pool <poolid>", "mds", "rw", "cli,rest")
 COMMAND("mds remove_data_pool " \
        "name=poolid,type=CephInt,range=0", \
-       "remove data pool <poolid>")
+       "remove data pool <poolid>", "mds", "rw", "cli,rest")
 COMMAND("mds newfs " \
        "name=metadata,type=CephInt,range=0 " \
        "name=data,type=CephInt,range=0 " \
        "name=sure,type=CephChoices,strings=--yes-i-really-mean-it", \
-       "make new filesystom using pools <metadata> and <data>")
+       "make new filesystom using pools <metadata> and <data>", \
+       "mds", "rw", "cli,rest")
 /*
  * Monmap commands
  */
 COMMAND("mon dump " \
        "name=epoch,type=CephInt,req=false", \
-       "dump formatted monmap (optionally from epoch)")
-COMMAND("mon stat", "summarize monitor status")
+       "dump formatted monmap (optionally from epoch)", \
+       "mon", "r", "cli,rest")
+COMMAND("mon stat", "summarize monitor status", "mon", "r", "cli,rest")
 COMMAND("mon getmap " \
        "name=epoch,type=CephInt,range=0,req=false", \
-       "get monmap")
+       "get monmap", "mon", "r", "cli,rest")
 COMMAND("mon add " \
        "name=name,type=CephString " \
        "name=addr,type=CephIPAddr", \
-       "add new monitor named <name> at <addr>")
+       "add new monitor named <name> at <addr>", "mon", "rw", "cli,rest")
 COMMAND("mon remove " \
        "name=name,type=CephString", \
-       "remove monitor named <name>")
+       "remove monitor named <name>", "mon", "rw", "cli,rest")
+
 
 /*
  * OSD commands
  */
-COMMAND("osd stat", "print summary of OSD map")
+COMMAND("osd stat", "print summary of OSD map", "osd", "r", "cli,rest")
 COMMAND("osd dump " \
        "name=epoch,type=CephInt,range=0,req=false",
-       "print summary of OSD map")
+       "print summary of OSD map", "osd", "r", "cli,rest")
 COMMAND("osd tree " \
        "name=epoch,type=CephInt,range=0,req=false", \
-       "print OSD tree")
+       "print OSD tree", "osd", "r", "cli,rest")
 COMMAND("osd ls " \
        "name=epoch,type=CephInt,range=0,req=false", \
-       "show all OSD ids")
+       "show all OSD ids", "osd", "r", "cli,rest")
 COMMAND("osd getmap " \
        "name=epoch,type=CephInt,range=0,req=false", \
-       "get OSD map")
+       "get OSD map", "osd", "r", "cli,rest")
 COMMAND("osd getcrushmap " \
        "name=epoch,type=CephInt,range=0,req=false", \
-       "get CRUSH map")
-COMMAND("osd getmaxosd", "show largest OSD id")
+       "get CRUSH map", "osd", "r", "cli,rest")
+COMMAND("osd getmaxosd", "show largest OSD id", "osd", "r", "cli,rest")
 COMMAND("osd find " \
        "name=id,type=CephInt,range=0", \
-       "find osd <id> in the CRUSH map and show its location")
+       "find osd <id> in the CRUSH map and show its location", \
+       "osd", "r", "cli,rest")
 COMMAND("osd map " \
        "name=pool,type=CephPoolname " \
        "name=object,type=CephObjectname", \
-       "find pg for <object> in <pool>")
+       "find pg for <object> in <pool>", "osd", "r", "cli,rest")
 COMMAND("osd scrub " \
        "name=who,type=CephString", \
-       "initiate scrub on osd <who>")
+       "initiate scrub on osd <who>", "osd", "rw", "cli,rest")
 COMMAND("osd deep-scrub " \
        "name=who,type=CephString", \
-       "initiate deep scrub on osd <who>")
+       "initiate deep scrub on osd <who>", "osd", "rw", "cli,rest")
 COMMAND("osd repair " \
        "name=who,type=CephString", \
-       "initiate repair on osd <who>")
+       "initiate repair on osd <who>", "osd", "rw", "cli,rest")
 COMMAND("osd lspools " \
        "name=auid,type=CephInt,req=false", \
-       "list pools")
-COMMAND("osd blacklist ls", "show blacklisted clients")
-COMMAND("osd crush rule list", "list crush rules")
-COMMAND("osd crush rule ls", "list crush rules")
-COMMAND("osd crush rule dump", "dump crush rules")
-COMMAND("osd crush dump", "dump crush map")
-COMMAND("osd setcrushmap", "set crush map from input file")
-COMMAND("osd crush set", "set crush map from input file")
+       "list pools", "osd", "r", "cli,rest")
+COMMAND("osd blacklist ls", "show blacklisted clients", "osd", "r", "cli,rest")
+COMMAND("osd crush rule list", "list crush rules", "osd", "r", "cli,rest")
+COMMAND("osd crush rule ls", "list crush rules", "osd", "r", "cli,rest")
+COMMAND("osd crush rule dump", "dump crush rules", "osd", "r", "cli,rest")
+COMMAND("osd crush dump", "dump crush map", "osd", "r", "cli,rest")
+COMMAND("osd setcrushmap", "set crush map from input file", \
+       "osd", "rw", "cli,rest")
+COMMAND("osd crush set", "set crush map from input file", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush add-bucket " \
        "name=name,type=CephString " \
        "name=type,type=CephString", \
-       "add no-parent (probably root) crush bucket <name> of type <type>")
+       "add no-parent (probably root) crush bucket <name> of type <type>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush set " \
        "name=id,type=CephOsdName " \
        "name=weight,type=CephFloat,range=0.0 " \
        "name=args,type=CephString,n=N", \
-       "set crushmap entry for <name> to <weight> with location <args>")
+       "set crushmap entry for <name> to <weight> with location <args>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush add " \
        "name=id,type=CephOsdName " \
        "name=weight,type=CephFloat,range=0.0 " \
        "name=args,type=CephString,n=N", \
-       "add crushmap entry for <name> with <weight> and location <args>")
+       "add crushmap entry for <name> with <weight> and location <args>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush create-or-move " \
        "name=id,type=CephOsdName " \
        "name=weight,type=CephFloat,range=0.0 " \
        "name=args,type=CephString,n=N", \
-       "create entry or move existing entry for <name> <weight> at/to location <args>")
+       "create entry or move existing entry for <name> <weight> at/to location <args>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush move " \
        "name=id,type=CephOsdName " \
        "name=args,type=CephString,n=N", \
-       "move existing entry for <name> to location <args>")
+       "move existing entry for <name> to location <args>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush link " \
        "name=name,type=CephString " \
        "name=args,type=CephString,n=N", \
-       "link existing entry for <name> under location <args>")
+       "link existing entry for <name> under location <args>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush rm " \
        "name=name,type=CephString", \
-       "remove <name> from crush map")
+       "remove <name> from crush map", "osd", "rw", "cli,rest")
 COMMAND("osd crush remove " \
        "name=name,type=CephString", \
-       "remove <name> from crush map")
+       "remove <name> from crush map", "osd", "rw", "cli,rest")
 COMMAND("osd crush unlink " \
        "name=name,type=CephString " \
        "name=ancestor,type=CephString,req=false", \
-       "unlink <name> from crush map (everywhere, or just at <ancestor>")
+       "unlink <name> from crush map (everywhere, or just at <ancestor>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush reweight " \
        "name=name,type=CephString " \
        "name=weight,type=CephFloat,range=0.0", \
-       "change <name>'s weight to <weight> in crush map")
+       "change <name>'s weight to <weight> in crush map", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush tunables " \
        "name=profile,type=CephChoices,strings=legacy|argonaut|bobtail|optimal|default", \
-       "set crush tunables values to <profile>")
+       "set crush tunables values to <profile>", "osd", "rw", "cli,rest")
 COMMAND("osd crush rule create-simple " \
        "name=name,type=CephString " \
        "name=root,type=CephString " \
        "name=type,type=CephString", \
-       "create crush rule <name> in <root> of type <type>")
+       "create crush rule <name> in <root> of type <type>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush rule rm " \
        "name=name,type=CephString", \
-       "remove crush rule <name>")
+       "remove crush rule <name>", "osd", "rw", "cli,rest")
 COMMAND("osd setmaxosd " \
        "name=newmax,type=CephInt,range=0", \
-       "set new maximum osd value")
-COMMAND("osd pause", "pause osd")
-COMMAND("osd unpause", "unpause osd")
+       "set new maximum osd value", "osd", "rw", "cli,rest")
+COMMAND("osd pause", "pause osd", "osd", "rw", "cli,rest")
+COMMAND("osd unpause", "unpause osd", "osd", "rw", "cli,rest")
 COMMAND("osd set " \
        "name=key,type=CephChoices,strings=pause|noup|nodown|noout|noin|nobackfile|norecover", \
-       "set <key>")
+       "set <key>", "osd", "rw", "cli,rest")
 COMMAND("osd unset " \
        "name=key,type=CephChoices,strings=pause|noup|nodown|noout|noin|nobackfile|norecover", \
-       "unset <key>")
-COMMAND("osd cluster_snap", "take cluster snapshot (disabled)")
+       "unset <key>", "osd", "rw", "cli,rest")
+COMMAND("osd cluster_snap", "take cluster snapshot (disabled)", \
+       "osd", "r", "")
 COMMAND("osd down " \
        "type=CephString,name=ids,n=N", \
-       "set osd(s) <id> [<id>...] down")
+       "set osd(s) <id> [<id>...] down", "osd", "rw", "cli,rest")
 COMMAND("osd out " \
        "name=ids,type=CephString,n=N", \
-       "set osd(s) <id> [<id>...] out")
+       "set osd(s) <id> [<id>...] out", "osd", "rw", "cli,rest")
 COMMAND("osd in " \
        "name=ids,type=CephString,n=N", \
-       "set osd(s) <id> [<id>...] in")
+       "set osd(s) <id> [<id>...] in", "osd", "rw", "cli,rest")
 COMMAND("osd rm " \
        "name=ids,type=CephString,n=N", \
-       "remove osd(s) <id> [<id>...] in")
+       "remove osd(s) <id> [<id>...] in", "osd", "rw", "cli,rest")
 COMMAND("osd reweight " \
        "name=id,type=CephInt,range=0 " \
        "type=CephFloat,name=weight,range=0.0|1.0", \
-       "reweight osd to 0.0 < <weight> < 1.0")
+       "reweight osd to 0.0 < <weight> < 1.0", "osd", "rw", "cli,rest")
 COMMAND("osd lost " \
        "name=id,type=CephInt,range=0 " \
        "name=sure,type=CephChoices,strings=--yes-i-really-mean-it", \
-       "mark osd as permanently lost. THIS DESTROYS DATA IF NO MORE REPLICAS EXIST, BE CAREFUL")
+       "mark osd as permanently lost. THIS DESTROYS DATA IF NO MORE REPLICAS EXIST, BE CAREFUL", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd create " \
        "name=uuid,type=CephUUID,req=false", \
-       "create new osd (with optional UUID)")
+       "create new osd (with optional UUID)", "osd", "rw", "cli,rest")
 COMMAND("osd blacklist " \
        "name=blacklistop,type=CephChoices,strings=add|rm " \
        "name=addr,type=CephEntityAddr " \
        "name=expire,type=CephFloat,range=0.0,req=false", \
-       "add (optionally until <expire> seconds from now) or remove <addr> from blacklist")
+       "add (optionally until <expire> seconds from now) or remove <addr> from blacklist", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd pool mksnap " \
        "name=pool,type=CephPoolname " \
        "name=snap,type=CephString", \
-       "make snapshot <snap> in <pool>")
+       "make snapshot <snap> in <pool>", "osd", "rw", "cli,rest")
 COMMAND("osd pool rmsnap " \
        "name=pool,type=CephPoolname " \
        "name=snap,type=CephString", \
-       "remove snapshot <snap> from <pool>")
+       "remove snapshot <snap> from <pool>", "osd", "rw", "cli,rest")
 COMMAND("osd pool create " \
        "name=pool,type=CephPoolname " \
        "name=pg_num,type=CephInt,range=0 " \
        "name=pgp_num,type=CephInt,range=0,req=false", \
-       "create pool")
+       "create pool", "osd", "rw", "cli,rest")
 COMMAND("osd pool delete " \
        "name=pool,type=CephPoolname " \
        "name=pool2,type=CephPoolname " \
        "name=sure,type=CephChoices,strings=--yes-i-really-really-mean-it", \
-       "delete pool (say pool twice, add --yes-i-really-really-mean-it)")
+       "delete pool (say pool twice, add --yes-i-really-really-mean-it)", \
+       "osd", "r", "cli,rest")
 COMMAND("osd pool rename " \
        "name=srcpool,type=CephPoolname " \
        "name=destpool,type=CephPoolname", \
-       "rename <srcpool> to <destpool>")
+       "rename <srcpool> to <destpool>", "osd", "rw", "cli,rest")
 COMMAND("osd pool get " \
        "name=pool,type=CephPoolname " \
        "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset", \
-       "get pool parameter <var>")
+       "get pool parameter <var>", "osd", "r", "cli,rest")
 COMMAND("osd pool set " \
        "name=pool,type=CephPoolname " \
        "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset " \
        "name=val,type=CephInt " \
        "name=sure,type=CephChoices,strings=--allow-experimental-feature,req=false", \
-       "set pool parameter <var> to <val>")
+       "set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
 // 'val' is a CephString because it can include a unit.  Perhaps
 // there should be a Python type for validation/conversion of strings
 // with units.
@@ -445,13 +500,14 @@ COMMAND("osd pool set-quota " \
        "name=pool,type=CephPoolname " \
        "name=field,type=CephChoices,strings=max_objects|max_bytes " \
        "name=val,type=CephString",
-       "set object or byte limit on pool")
+       "set object or byte limit on pool", "osd", "rw", "cli,rest")
 COMMAND("osd reweight-by-utilization " \
        "name=oload,type=CephInt,range=100,req=false", \
-       "reweight OSDs by utilization [overload-percentage-for-consideration, default 120]")
+       "reweight OSDs by utilization [overload-percentage-for-consideration, default 120]", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd thrash " \
        "name=num_epochs,type=CephInt,range=0", \
-       "thrash OSDs for <num_epochs>")
+       "thrash OSDs for <num_epochs>", "osd", "rw", "cli,rest")
 
 /*
  * mon/ConfigKeyService.cc
@@ -459,15 +515,15 @@ COMMAND("osd thrash " \
 
 COMMAND("config-key get " \
        "name=key,type=CephString", \
-       "get <key>")
+       "get <key>", "config-key", "r", "cli,rest")
 COMMAND("config-key put " \
        "name=key,type=CephString " \
        "name=val,type=CephString,req=false", \
-       "put <key>, value <val>")
+       "put <key>, value <val>", "config-key", "rw", "cli,rest")
 COMMAND("config-key del " \
        "name=key,type=CephString", \
-       "delete <key>")
+       "delete <key>", "config-key", "rw", "cli,rest")
 COMMAND("config-key exists " \
        "name=key,type=CephString", \
-       "check for <key>'s existence")
-COMMAND("config-key list ", "list keys")
+       "check for <key>'s existence", "config-key", "r", "cli,rest")
+COMMAND("config-key list ", "list keys", "config-key", "r", "cli,rest")
index aef9acc0a179734a17097f6a537ec52136ee2e89..2aa2f8a6d6ea734354d75ee0c835d500dcb6929c 100644 (file)
@@ -1784,9 +1784,12 @@ void Monitor::get_status(stringstream &ss, Formatter *f)
 struct MonCommand {
   string cmdstring;
   string helpstring;
+  string module;
+  string req_perms;
+  string availability;
 } mon_commands[] = {
-#define COMMAND(parsesig, helptext) \
-  {parsesig, helptext},
+#define COMMAND(parsesig, helptext, modulename, req_perms, avail) \
+  {parsesig, helptext, modulename, req_perms, avail},
 #include <mon/MonCommands.h>
 };
 
@@ -1841,8 +1844,9 @@ void Monitor::handle_command(MMonCommand *m)
 
       ostringstream secname;
       secname << "cmd" << setfill('0') << std::setw(3) << cmdnum;
-      dump_cmd_and_help_to_json(f, secname.str(),
-                               cp->cmdstring, cp->helpstring);
+      dump_cmddesc_to_json(f, secname.str(),
+                          cp->cmdstring, cp->helpstring, cp->module,
+                          cp->req_perms, cp->availability);
       cmdnum++;
     }
     f->close_section();        // command_descriptions
index c6a5711057fb35c218cd788d61b1d1406f8241ad..856c041f3cb1c2bd7ea3ce61e3e7772151743f2d 100644 (file)
@@ -623,14 +623,12 @@ def parse_funcsig(sig):
     return newsig
 
 
-def parse_json_funcsigs(s):
+def parse_json_funcsigs(s, consumer):
     """
-    parse_json_funcsigs(s)
-
     A function signature is mostly an array of argdesc; it's represented
     in JSON as
     {
-      "cmd001": {"sig":[ "type": type, "name": name, "n": num, "req":true|false <other param>], "help":helptext}
+      "cmd001": {"sig":[ "type": type, "name": name, "n": num, "req":true|false <other param>], "help":helptext, "module":modulename, "perm":perms, "avail":availability}
        .
        .
        .
@@ -639,16 +637,22 @@ def parse_json_funcsigs(s):
     A set of sigs is in an dict mapped by a unique number:
     {
       "cmd1": {
-         "sig": ["type.. ], "help":{"text":helptext}
+         "sig": ["type.. ], "help":helptext...
       }
       "cmd2"{
-         "sig": [.. ], "help":{"text":helptext}
+         "sig": [.. ], "help":helptext...
       }
     }
 
-    Parse the string s and return an dict of dicts, keyed by opcode;
+    Parse the string s and return a dict of dicts, keyed by opcode;
     each dict contains 'sig' with the array of descriptors, and 'help'
-    with the helptext.
+    with the helptext, 'module' with the module name, 'perm' with a
+    string representing required permissions in that module to execute
+    this command (and also whether it is a read or write command from
+    the cluster state perspective), and 'avail' as a hint for
+    whether the command should be advertised by CLI, REST, or both.
+    If avail does not contain 'consumer', don't include the command
+    in the returned dict.
     """
     try:
         overall = json.loads(s)
@@ -657,14 +661,17 @@ def parse_json_funcsigs(s):
         raise e
     sigdict = {}
     for cmdtag, cmd in overall.iteritems():
-        helptext = cmd.get('help', 'no help available')
-        try:
-            sig = cmd['sig']
-        except KeyError:
+        if not 'sig' in cmd:
             s = "JSON descriptor {0} has no 'sig'".format(cmdtag)
             raise JsonFormat(s)
-        newsig = parse_funcsig(sig)
-        sigdict[cmdtag] = {'sig':newsig, 'helptext':helptext}
+        # check 'avail' and possibly ignore this command
+        if 'avail' in cmd:
+            if not consumer in cmd['avail']:
+                continue
+        # rewrite the 'sig' item with the argdesc-ized version, and...
+        cmd['sig'] = parse_funcsig(cmd['sig'])
+        # just take everything else as given
+        sigdict[cmdtag] = cmd
     return sigdict
 
 def validate_one(word, desc, partial=False):
@@ -812,7 +819,7 @@ def validate_command(parsed_args, sigdict, args, verbose=False):
         for cmdsig in bestcmds:
             for cmd in cmdsig.itervalues():
                 sig = cmd['sig']
-                helptext = cmd['helptext']
+                helptext = cmd['help']
                 try:
                     valid_dict = validate(args, sig, verbose)
                     found = sig