]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/pybind/mgr/restful/module.py
import ceph 16.2.6
[ceph.git] / ceph / src / pybind / mgr / restful / module.py
index a2d6793eaf2d1fae8da7c61c2e50c8458172d8d4..4d3f1355286b13998acd375ebd2defac1a02e2e1 100644 (file)
@@ -11,8 +11,8 @@ import inspect
 import tempfile
 import threading
 import traceback
-import six
 import socket
+import fcntl
 
 from . import common
 from . import context
@@ -21,11 +21,11 @@ from uuid import uuid4
 from pecan import jsonify, make_app
 from OpenSSL import crypto
 from pecan.rest import RestController
-from six import iteritems
 from werkzeug.serving import make_server, make_ssl_devcert
 
 from .hooks import ErrorHook
 from mgr_module import MgrModule, CommandResult
+from mgr_util import build_url
 
 
 class CannotServe(Exception):
@@ -79,16 +79,16 @@ class CommandsRequest(object):
 
         # Gather the results (in parallel)
         results = []
-        for index in range(len(commands)):
+        for index, command in enumerate(commands):
             tag = '%s:%s:%d' % (__name__, self.id, index)
 
             # Store the result
             result = CommandResult(tag)
-            result.command = common.humanify_command(commands[index])
+            result.command = common.humanify_command(command)
             results.append(result)
 
             # Run the command
-            context.instance.send_command(result, 'mon', '', json.dumps(commands[index]), tag)
+            context.instance.send_command(result, 'mon', '', json.dumps(command), tag)
 
         return results
 
@@ -159,37 +159,31 @@ class CommandsRequest(object):
     def __json__(self):
         return {
             'id': self.id,
-            'running': map(
-                lambda x: {
+            'running': [
+                {
                     'command': x.command,
                     'outs': x.outs,
                     'outb': x.outb,
-                },
-                self.running
-            ),
-            'finished': map(
-                lambda x: {
+                } for x in self.running
+            ],
+            'finished': [
+                {
                     'command': x.command,
                     'outs': x.outs,
                     'outb': x.outb,
-                },
-                self.finished
-            ),
-            'waiting': map(
-                lambda x: map(
-                    lambda y: common.humanify_command(y),
-                    x
-                ),
-                self.waiting
-            ),
-            'failed': map(
-                lambda x: {
+                } for x in self.finished
+            ],
+            'waiting': [
+                [common.humanify_command(y) for y in x]
+                for x in self.waiting
+            ],
+            'failed': [
+                {
                     'command': x.command,
                     'outs': x.outs,
                     'outb': x.outb,
-                },
-                self.failed
-            ),
+                } for x in self.failed
+            ],
             'is_waiting': self.is_waiting(),
             'is_finished': self.is_finished(),
             'has_failed': self.has_failed(),
@@ -203,6 +197,7 @@ class Module(MgrModule):
         {'name': 'server_addr'},
         {'name': 'server_port'},
         {'name': 'key_file'},
+        {'name': 'enable_auth', 'type': 'bool', 'default': True},
     ]
 
     COMMANDS = [
@@ -241,7 +236,7 @@ class Module(MgrModule):
         self.requests_lock = threading.RLock()
 
         self.keys = {}
-        self.disable_auth = False
+        self.enable_auth = True
 
         self.server = None
 
@@ -250,23 +245,25 @@ class Module(MgrModule):
 
 
     def serve(self):
+        self.log.debug('serve enter')
         while not self.stop_server:
             try:
                 self._serve()
                 self.server.socket.close()
             except CannotServe as cs:
-                self.log.warn("server not running: %s", cs)
+                self.log.warning("server not running: %s", cs)
             except:
                 self.log.error(str(traceback.format_exc()))
 
             # Wait and clear the threading event
             self.serve_event.wait()
             self.serve_event.clear()
+        self.log.debug('serve exit')
 
     def refresh_keys(self):
         self.keys = {}
         rawkeys = self.get_store_prefix('keys/') or {}
-        for k, v in six.iteritems(rawkeys):
+        for k, v in rawkeys.items():
             self.keys[k[5:]] = v  # strip of keys/ prefix
 
     def _serve(self):
@@ -305,6 +302,8 @@ class Module(MgrModule):
         else:
             pkey_fname = self.get_localized_module_option('key_file')
 
+        self.enable_auth = self.get_localized_module_option('enable_auth', True)
+        
         if not cert_fname or not pkey_fname:
             raise CannotServe('no certificate configured')
         if not os.path.isfile(cert_fname):
@@ -314,10 +313,8 @@ class Module(MgrModule):
 
         # Publish the URI that others may use to access the service we're
         # about to start serving
-        self.set_uri("https://{0}:{1}/".format(
-            socket.gethostname() if server_addr == "::" else server_addr,
-            server_port
-        ))
+        addr = self.get_mgr_ip() if server_addr == "::" else server_addr
+        self.set_uri(build_url(scheme='https', host=addr, port=server_port, path='/'))
 
         # Create the HTTPS werkzeug server serving pecan app
         self.server = make_server(
@@ -329,19 +326,30 @@ class Module(MgrModule):
             ),
             ssl_context=(cert_fname, pkey_fname),
         )
-
-        self.server.serve_forever()
+        sock_fd_flag = fcntl.fcntl(self.server.socket.fileno(), fcntl.F_GETFD)
+        if not (sock_fd_flag & fcntl.FD_CLOEXEC):
+            self.log.debug("set server socket close-on-exec")
+            fcntl.fcntl(self.server.socket.fileno(), fcntl.F_SETFD, sock_fd_flag | fcntl.FD_CLOEXEC)
+        if self.stop_server:
+            self.log.debug('made server, but stop flag set')
+        else:
+            self.log.debug('made server, serving forever')
+            self.server.serve_forever()
 
 
     def shutdown(self):
+        self.log.debug('shutdown enter')
         try:
             self.stop_server = True
             if self.server:
+                self.log.debug('calling server.shutdown')
                 self.server.shutdown()
+                self.log.debug('called server.shutdown')
             self.serve_event.set()
         except:
             self.log.error(str(traceback.format_exc()))
             raise
+        self.log.debug('shutdown exit')
 
 
     def restart(self):
@@ -377,6 +385,9 @@ class Module(MgrModule):
             # the command was not issued by me
             pass
 
+    def config_notify(self):
+        self.enable_auth = self.get_localized_module_option('enable_auth', True)
+
 
     def create_self_signed_cert(self):
         # create a key pair
@@ -401,7 +412,7 @@ class Module(MgrModule):
 
 
     def handle_command(self, inbuf, command):
-        self.log.warn("Handling command: '%s'" % str(command))
+        self.log.warning("Handling command: '%s'" % str(command))
         if command['prefix'] == "restful create-key":
             if command['key_name'] in self.keys:
                 return 0, self.keys[command['key_name']], ""
@@ -432,7 +443,7 @@ class Module(MgrModule):
             self.refresh_keys()
             return (
                 0,
-                json.dumps(self.keys, indent=2),
+                json.dumps(self.keys, indent=4, sort_keys=True),
                 "",
             )