From a18ffe8018646bd3811c379f8ae27f16a54d29c2 Mon Sep 17 00:00:00 2001 From: Volker Theile Date: Mon, 9 Apr 2018 15:26:26 +0200 Subject: [PATCH] mgr/dashboard: Takeover PR #20799 and adapt comments. Signed-off-by: Volker Theile --- src/pybind/mgr/dashboard/controllers/rgw.py | 23 ++----- src/pybind/mgr/dashboard/rest_client.py | 3 +- .../mgr/dashboard/services/rgw_client.py | 61 ++++++++++++++++--- src/pybind/mgr/dashboard/tests/test_tools.py | 1 - src/pybind/mgr/dashboard/tools.py | 6 +- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/rgw.py b/src/pybind/mgr/dashboard/controllers/rgw.py index ad4f4c2cc1c..d43e9e476b9 100644 --- a/src/pybind/mgr/dashboard/controllers/rgw.py +++ b/src/pybind/mgr/dashboard/controllers/rgw.py @@ -2,12 +2,11 @@ from __future__ import absolute_import import json - import cherrypy +from . import ApiController, BaseController, RESTController, AuthRequired from .. import logger from ..services.ceph_service import CephService -from ..tools import ApiController, RESTController, AuthRequired from ..services.rgw_client import RgwClient from ..rest_client import RequestException from ..exceptions import NoCredentialsException @@ -22,20 +21,12 @@ class Rgw(RESTController): @ApiController('rgw/daemon') @AuthRequired() class RgwDaemon(RESTController): + def list(self): daemons = [] for hostname, server in CephService.get_service_map('rgw').items(): for service in server['services']: metadata = service['metadata'] - status = service['status'] - if 'json' in status: - try: - status = json.loads(status['json']) - except ValueError: - logger.warning("%s had invalid status json", service['id']) - status = {} - else: - logger.warning('%s has no key "json" in status', service['id']) # extract per-daemon service data and health daemon = { @@ -71,25 +62,23 @@ class RgwDaemon(RESTController): daemon['rgw_metadata'] = metadata daemon['rgw_status'] = status - return daemon -@ApiController('rgw/proxy') +@ApiController('rgw/proxy/{path:.*}') @AuthRequired() -class RgwProxy(RESTController): +class RgwProxy(BaseController): @cherrypy.expose - def default(self, *vpath, **params): + def __call__(self, path, **params): try: rgw_client = RgwClient.admin_instance() except NoCredentialsException as e: cherrypy.response.headers['Content-Type'] = 'application/json' cherrypy.response.status = 401 - return json.dumps({'message': e.message}) + return json.dumps({'message': str(e)}).encode('utf-8') method = cherrypy.request.method - path = '/'.join(vpath) data = None if cherrypy.request.body.length: diff --git a/src/pybind/mgr/dashboard/rest_client.py b/src/pybind/mgr/dashboard/rest_client.py index cf339ef97b6..3105545fc3b 100644 --- a/src/pybind/mgr/dashboard/rest_client.py +++ b/src/pybind/mgr/dashboard/rest_client.py @@ -15,7 +15,6 @@ from __future__ import absolute_import from .tools import build_url import inspect -import itertools import re import requests from requests.exceptions import ConnectionError, InvalidURL @@ -474,7 +473,7 @@ class RestClient(object): method = api_kwargs.get('method', None) resp_structure = api_kwargs.get('resp_structure', None) args_name = inspect.getargspec(func).args - args_dict = dict(itertools.izip(args_name[1:], args)) + args_dict = dict(zip(args_name[1:], args)) for key, val in kwargs: args_dict[key] = val return func( diff --git a/src/pybind/mgr/dashboard/services/rgw_client.py b/src/pybind/mgr/dashboard/services/rgw_client.py index 405e0b0b5c6..0089e9f006f 100644 --- a/src/pybind/mgr/dashboard/services/rgw_client.py +++ b/src/pybind/mgr/dashboard/services/rgw_client.py @@ -11,21 +11,64 @@ from .. import mgr, logger def _determine_rgw_addr(): + """ + Get a RGW daemon to determine the configured host (IP address) and port. + Note, the service id of the RGW daemons may differ depending on the setup. + Example 1: + { + ... + 'services': { + 'rgw': { + 'daemons': { + 'summary': '', + '0': { + ... + 'metadata': { + 'frontend_config#0': 'civetweb port=7280', + } + ... + } + } + } + } + } + Example 2: + { + ... + 'services': { + 'rgw': { + 'daemons': { + 'summary': '', + 'rgw': { + ... + 'metadata': { + 'frontend_config#0': 'civetweb port=8000', + } + ... + } + } + } + } + } + """ service_map = mgr.get('service_map') + if not dict_contains_path(service_map, ['services', 'rgw', 'daemons']): + raise LookupError('No RGW found.') + daemon = None + daemons = service_map['services']['rgw']['daemons'] + for key in daemons.keys(): + if dict_contains_path(daemons[key], ['metadata', 'frontend_config#0']): + daemon = daemons[key] + break + if daemon is None: + raise LookupError('No RGW daemon found.') - if not dict_contains_path(service_map, ['services', 'rgw', 'daemons', 'rgw']): - msg = 'No RGW found.' - raise LookupError(msg) - - daemon = service_map['services']['rgw']['daemons']['rgw'] addr = daemon['addr'].split(':')[0] - match = re.search(r'port=(\d+)', - daemon['metadata']['frontend_config#0']) + match = re.search(r'port=(\d+)', daemon['metadata']['frontend_config#0']) if match: port = int(match.group(1)) else: - msg = 'Failed to determine RGW port' - raise LookupError(msg) + raise LookupError('Failed to determine RGW port') return addr, port diff --git a/src/pybind/mgr/dashboard/tests/test_tools.py b/src/pybind/mgr/dashboard/tests/test_tools.py index 7c82ea2136c..4ec6ce943fb 100644 --- a/src/pybind/mgr/dashboard/tests/test_tools.py +++ b/src/pybind/mgr/dashboard/tests/test_tools.py @@ -153,5 +153,4 @@ class TestFunctions(unittest.TestCase): self.assertTrue(dict_contains_path(x, ['a', 'b', 'c'])) self.assertTrue(dict_contains_path(x, ['a'])) self.assertFalse(dict_contains_path(x, ['a', 'c'])) - self.assertTrue(dict_contains_path(x, [])) diff --git a/src/pybind/mgr/dashboard/tools.py b/src/pybind/mgr/dashboard/tools.py index 802fd8af4de..1e99dd7a78b 100644 --- a/src/pybind/mgr/dashboard/tools.py +++ b/src/pybind/mgr/dashboard/tools.py @@ -8,10 +8,10 @@ import fnmatch import time import threading import socket +from six.moves import urllib import cherrypy from . import logger -from six.moves import urllib class RequestLoggingTool(cherrypy.Tool): @@ -673,13 +673,15 @@ def build_url(host, scheme=None, port=None): def dict_contains_path(dct, keys): """ - Tests wheter the keys exist recursively in `dictionary`. + Tests whether the keys exist recursively in `dictionary`. :type dct: dict :type keys: list :rtype: bool """ if keys: + if not isinstance(dct, dict): + return False key = keys.pop(0) if key in dct: dct = dct[key] -- 2.39.5