From: Chang Liu Date: Thu, 14 Dec 2017 09:11:11 +0000 (+0800) Subject: mgr/dashboard: create RGW page X-Git-Tag: v13.0.2~667^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=10578ba6c9bfe907b36fbd78cf8f45cde8eebac1;p=ceph.git mgr/dashboard: create RGW page Signed-off-by: Chang Liu --- diff --git a/src/pybind/mgr/dashboard/base.html b/src/pybind/mgr/dashboard/base.html index 742327079fc..72266fa5566 100644 --- a/src/pybind/mgr/dashboard/base.html +++ b/src/pybind/mgr/dashboard/base.html @@ -413,6 +413,13 @@ Failed to load data from server None found + +
  • + + + RGW +
  • + diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index e141d54bf32..d48f599373c 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -37,6 +37,7 @@ import rbd_iscsi import rbd_mirroring from rbd_ls import RbdLs, RbdPoolLs from cephfs_clients import CephFSClients +from rgw import RGWDaemons log = logging.getLogger("dashboard") @@ -142,6 +143,9 @@ class Module(MgrModule): # Stateful instances of CephFSClients, hold cached results. Key to # dict is FSCID self.cephfs_clients = {} + + # Stateful instance of RGW + self.rgw_daemons = RGWDaemons(self) # A short history of pool df stats self.pool_stats = defaultdict(lambda: defaultdict( @@ -1113,8 +1117,75 @@ class Module(MgrModule): content_data=json.dumps(content_data, indent=2) ) + class RGWEndpoint(EndPoint): + + @cherrypy.expose + def index(self): + """ List all RGW servers """ + + template = env.get_template("rgw.html") + toplevel_data = self._toplevel_data() + + content_data = self._rgw_daemons() + + return template.render( + url_prefix = global_instance().url_prefix, + ceph_version=global_instance().version, + path_info='/rgw' + cherrypy.request.path_info, + toplevel_data=json.dumps(toplevel_data, indent=2), + content_data=json.dumps(content_data, indent=2) + ) + + def _rgw_daemons(self): + status, data = global_instance().rgw_daemons.get() + if data is None: + log.warning("Failed to get RGW status") + return {} + return data + + @cherrypy.expose + @cherrypy.tools.json_out() + def rgw_daemons_data(self): + return self._rgw_daemons() + + + def _rgw(self, rgw_id): + daemons = self.rgw_daemons_data() + rgw_metadata = {} + rgw_status = {} + + for daemon in daemons["daemons"]: + if daemon["id"] != rgw_id: + continue + + rgw_metadata = daemon["metadata"] + rgw_status = daemon["status"] + + return { + "rgw_id": rgw_id, + "rgw_metadata": rgw_metadata, + "rgw_status": rgw_status, + } + + @cherrypy.expose + def detail(self, rgw_id): + template = env.get_template("rgw_detail.html") + toplevel_data = self._toplevel_data() + return template.render( + url_prefix=global_instance().url_prefix, + ceph_version=global_instance().version, + path_info='/rgw' + cherrypy.request.path_info, + toplevel_data=json.dumps(toplevel_data, indent=2), + content_data=json.dumps(self.rgw_data(rgw_id), indent=2) + ) + @cherrypy.expose + @cherrypy.tools.json_out() + def rgw_data(self, rgw_id): + return self._rgw(rgw_id) + cherrypy.tree.mount(Root(), get_prefixed_url("/"), conf) cherrypy.tree.mount(OSDEndpoint(), get_prefixed_url("/osd"), conf) + cherrypy.tree.mount(RGWEndpoint(), get_prefixed_url("/rgw"), conf) log.info("Starting engine on {0}:{1}...".format( server_addr, server_port)) diff --git a/src/pybind/mgr/dashboard/rgw.html b/src/pybind/mgr/dashboard/rgw.html new file mode 100644 index 00000000000..b7b2c3faabc --- /dev/null +++ b/src/pybind/mgr/dashboard/rgw.html @@ -0,0 +1,61 @@ +{% extends "base.html" %} + +{% block content %} + + + +
    +

    + RGW daemons +

    +
    + +
    +
    +
    + + + + + + + + + + + +
    + ID + + Hostname + + Version +
    + {rgwdaemon.id} + + {rgwdaemon.server_hostname} + + {rgwdaemon.version | short_version} +
    +
    +
    +
    + + +{% endblock %} diff --git a/src/pybind/mgr/dashboard/rgw.py b/src/pybind/mgr/dashboard/rgw.py new file mode 100644 index 00000000000..3482163914c --- /dev/null +++ b/src/pybind/mgr/dashboard/rgw.py @@ -0,0 +1,45 @@ +# -*- code: utf-8 -*- + +import json +import re +import rados +from remote_view_cache import RemoteViewCache + +import logging + +log = logging.getLogger("dashboard") + +class RGWDaemons(RemoteViewCache): + + def _get(self): + daemons = self.get_daemons() + return { + 'daemons': daemons, + } + + def get_daemons(self): + daemons = [] + for server in self._module.list_servers(): + for service in server['services']: + if service['type'] == 'rgw': + metadata = self._module.get_metadata('rgw', service['id']) + status = self._module.get_daemon_status('rgw', service['id']) + try: + status = json.loads(status['json']) + except: + status = {} + + # extract per-daemon service data and health + daemon = { + 'id': service['id'], + 'version': metadata['ceph_version'], + 'server_hostname': server['hostname'], + 'service': service, + 'server': server, + 'metadata': metadata, + 'status': status, + 'url': "/rgw/detail/{0}".format(service['id']) + } + + daemons.append(daemon) + return sorted(daemons, key=lambda k: k['id']) diff --git a/src/pybind/mgr/dashboard/rgw_detail.html b/src/pybind/mgr/dashboard/rgw_detail.html new file mode 100644 index 00000000000..f367c4d77c3 --- /dev/null +++ b/src/pybind/mgr/dashboard/rgw_detail.html @@ -0,0 +1,101 @@ +{% extends "base.html" %} + +{% block content %} + + + +
    +

    + rgw.{rgw_id} +

    +
    + +
    +
    +

    Status

    +
    +
    + + + + + + + + + + + + + +
    KeyValue
    {meta_item.key}{meta_item.value}
    +
    +
    + + + +
    +
    +

    Metadata

    +
    +
    + + + + + + + + + + + + + +
    KeyValue
    {meta_item.key}{meta_item.value}
    +
    +
    + + + + +{% endblock %}