]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph.in: admin_socket() now validates command and passes format
authorDan Mick <dan.mick@inktank.com>
Thu, 18 Jul 2013 21:43:37 +0000 (14:43 -0700)
committerDan Mick <dan.mick@inktank.com>
Fri, 26 Jul 2013 20:51:09 +0000 (13:51 -0700)
Signed-off-by: Dan Mick <dan.mick@inktank.com>
src/ceph.in

index 90795058127cab3fd91462a58563871d63af21d4..a72761216bd52634e6976b8eea8bff928b34d9c3 100755 (executable)
@@ -285,26 +285,57 @@ def format_help(cmddict, partial=None):
 
     return fullusage
 
-def admin_socket(asok_path, cmd):
-    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+def admin_socket(asok_path, cmd, format=''):
+    """
+    Send a daemon (--admin-daemon) command 'cmd'.  asok_path is the
+    path to the admin socket; cmd is a list of strings; format may be
+    set to one of the formatted forms to get output in that form
+    (daemon commands don't support 'plain' output).
+    """
+
+    def do_sockio(path, cmd):
+        """ helper: do all the actual low-level stream I/O """
+        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        sock.connect(path)
+        try:
+            sock.sendall(cmd + '\0')
+            len_str = sock.recv(4)
+            if len(len_str) < 4:
+                raise RuntimeError("no data returned from admin socket")
+            l, = struct.unpack(">I", len_str)
+            ret = ''
+
+            got = 0
+            while got < l:
+                bit = sock.recv(l - got)
+                ret += bit
+                got += len(bit)
+
+        except Exception as e:
+            raise RuntimeError('exception: ' + str(e))
+        return ret
+
     try:
-        sock.connect(asok_path)
-        sock.sendall(' '.join(cmd) + '\0')
+        cmd_json = do_sockio(asok_path,
+            json.dumps({"prefix":"get_command_descriptions"}))
+    except Exception as e:
+        raise RuntimeError('exception getting command descriptions: ' + str(e))
+
+    if cmd[0] == 'get_command_descriptions':
+        return cmd_json
 
-        len_str = sock.recv(4)
-        if len(len_str) < 4:
-            raise RuntimeError("no data returned from admin socket")
-        l, = struct.unpack(">I", len_str)
-        ret = ''
+    sigdict = parse_json_funcsigs(cmd_json, 'cli')
+    valid_dict = validate_command(sigdict, cmd)
+    if not valid_dict:
+        return -errno.EINVAL
 
-        got = 0
-        while got < l:
-            bit = sock.recv(l - got)
-            ret += bit
-            got += len(bit)
+    if format:
+        valid_dict['format'] = format
 
+    try:
+        ret = do_sockio(asok_path, json.dumps(valid_dict))
     except Exception as e:
-        raise RuntimeError('exception: {0}'.format(e))
+        raise RuntimeError('exception: ' + str(e))
 
     return ret
 
@@ -473,9 +504,12 @@ def main():
         conffile = parsed_args.cephconf
     # For now, --admin-daemon is handled as usual.  Try it
     # first in case we can't connect() to the cluster
+
+    format = parsed_args.output_format
+
     if parsed_args.admin_socket:
         try:
-            print admin_socket(parsed_args.admin_socket, childargs)
+            print admin_socket(parsed_args.admin_socket, childargs, format)
         except Exception as e:
             print >> sys.stderr, 'admin_socket: {0}'.format(e)
         return 0
@@ -484,7 +518,7 @@ def main():
         if len(childargs) > 2:
             if childargs[1].find('/') >= 0:
                 try:
-                    print admin_socket(childargs[1], childargs[2:])
+                    print admin_socket(childargs[1], childargs[2:], format)
                 except Exception as e:
                     print >> sys.stderr, 'admin_socket: {0}'.format(e)
                 return 0
@@ -492,7 +526,7 @@ def main():
                 # try resolve daemon name
                 path = ceph_conf('admin_socket', childargs[1])
                 try:
-                    print admin_socket(path, childargs[2:])
+                    print admin_socket(path, childargs[2:], format)
                 except Exception as e:
                     print >> sys.stderr, 'admin_socket: {0}'.format(e)
                 return 0