]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: add configuration setting browser 23479/head
authorRubab-Syed <rubab.syed21@gmail.com>
Mon, 22 Jan 2018 02:54:11 +0000 (07:54 +0500)
committerErnesto Puerta <epuertat@redhat.com>
Wed, 8 Aug 2018 05:10:04 +0000 (10:40 +0530)
Signed-off-by: Rubab Syed<rubab.syed21@gmail.com>
(cherry picked from commit 14bb815060a4d156bb5f7cc5d66e77466cba4351)
Signed-off-by: Ernesto Puerta <epuertat@redhat.com>
Conflicts:
      src/pybind/mgr/dashboard/base.html
      src/pybind/mgr/dashboard/monitors.html
      src/pybind/mgr/dashboard/osd_perf.html
      src/pybind/mgr/dashboard/rgw_detail.html

Conflict resolution:
- Keep config references while removing references to new monitor and
rgw endpoints and pages.

src/common/config.cc
src/common/config.h
src/mgr/ActivePyModules.cc
src/pybind/mgr/dashboard/base.html
src/pybind/mgr/dashboard/config_options.html [new file with mode: 0644]
src/pybind/mgr/dashboard/module.py
src/pybind/mgr/dashboard/osd_perf.html

index 3cbb27e3484c043788d3412786c7a48b9908cea8..88e3da9b50aae824ebf5dd51a4ed81f68e50f38d 100644 (file)
@@ -391,6 +391,17 @@ void md_config_t::show_config(Formatter *f)
   _show_config(NULL, f);
 }
 
+void md_config_t::config_options(Formatter *f)
+{
+  Mutex::Locker l(lock);
+  f->open_array_section("options");
+  for (const auto& i: schema) {
+    const Option &opt = i.second;
+    opt.dump(f);
+  }
+  f->close_section();
+}
+
 void md_config_t::_show_config(std::ostream *out, Formatter *f)
 {
   if (out) {
index 1e573f5e11b28832ee77b3cb3b1fb5cd29a1d573..612f083d89cfe06ee536fb2b8e6803fc4b9c085f 100644 (file)
@@ -180,6 +180,9 @@ public:
   void show_config(std::ostream& out);
   /// dump all config values to a formatter
   void show_config(Formatter *f);
+  
+  /// dump all config settings to a formatter
+  void config_options(Formatter *f);
 
   /// obtain a diff between our config values and another md_config_t values
   void diff(const md_config_t *other,
index 0694d23082e4f511a6a0f782352a1582ea58fec2..a7f5839ba85720e03d894fe2897b38553489199d 100644 (file)
@@ -187,9 +187,13 @@ PyObject *ActivePyModules::get_python(const std::string &what)
       }
     });
     return f.get();
-  } else if (what == "config") {
+  } else if (what.substr(0, 6) == "config") {
     PyFormatter f;
-    g_conf->show_config(&f);
+    if (what == "config_options") {
+      g_conf->config_options(&f);  
+    } else if (what == "config") {
+      g_conf->show_config(&f);
+    }
     return f.get();
   } else if (what == "mon_map") {
     PyFormatter f;
index 9936eaeca37967f03d2c1870cbc279e15bed9f98..6debffa5ce74e1a6e661fe26e1ed630c585191ef 100644 (file)
             <i class="fa fa-heartbeat" rv-style="health_status | health_color"></i>
             <span>Cluster health</span></a>
         </li>
-        <li class="treeview{%if path_info.startswith(('/server', '/osd'))%} active{%endif%}">
+        <li class="treeview{%if path_info.startswith(('/server', '/osd','/config_options'))%} active{%endif%}">
           <a href="#"><i class="fa fa-server"></i> <span>Cluster</span>
             <span class="pull-right-container">
               <i class="fa fa-angle-left pull-right"></i>
             <li>
                 <a href="{{ url_prefix }}/osd">OSDs</a>
             </li>
+           <li>
+              <a href="{{ url_prefix }}/config_options">Configuration</a>
+            </li>
           </ul>
         </li>
         <li class="treeview{%if path_info.startswith('/rbd')%} active{%endif%}">
diff --git a/src/pybind/mgr/dashboard/config_options.html b/src/pybind/mgr/dashboard/config_options.html
new file mode 100644 (file)
index 0000000..e8367a0
--- /dev/null
@@ -0,0 +1,120 @@
+
+{% extends "base.html" %}
+
+{% block content %}
+
+
+<script>
+  $(document).ready(function(){
+             // Pre-populated initial data at page load
+            var content_data = {{ content_data }};
+           
+            rivets.formatters.display_arrays = function(arr) {
+                result = arr.join().replace(/,/g, "<br/>");
+                return "<div style='width:90px;word-break:break-all'>" + result + "</div>";
+             };
+
+             str_to_level = function(str) {
+                 if (str == "basic")
+                     return "0"
+                 else if (str == "advanced")
+                     return "1"
+                 else if (str == "developer")
+                     return "2" 
+             };
+  
+             apply_filters = function() {
+                 content_data.options_list = [];
+                 var selection = "#" + content_data.service;
+                 $(selection).attr('selected','selected');
+                 var level = $("#level").val();
+                 var service = $("#service").val();
+                 if (level == "developer" && service == "any") {
+                     content_data.options_list = content_data.options.options;
+                 }
+                 for (var opt of content_data.options.options) {
+                     if (service == "any" && str_to_level(opt.level) <= level) {
+                         content_data.options_list.push(opt); 
+                     } else if (opt.services.includes(service) && str_to_level(opt.level) <= level) {
+                         content_data.options_list.push(opt);
+                     }
+                 }
+         
+             };
+             
+             rivets.bind($("#content"), content_data);         
+             apply_filters();
+
+         });
+</script>
+
+<!-- Page Header -->
+<section class="content-header">
+    <h1 style="font-weight:bold">
+      Configuration Options
+      <div class="pull-right" style="font-size:17px">
+       <label>Services:</label>
+       <select id="service" style="color:grey" onchange="apply_filters()">
+         <option id="mon">mon</option>
+         <option id="mgr">mgr</option>
+         <option id="osd">osd</option>
+         <option id="mds">mds</option>
+         <option id="common">common</option>
+         <option id="mds_client">mds_client</option>
+         <option id="rgw">rgw</option>
+         <option id="any">any</option>
+       </select>
+       <label>Level:</label>
+       <select id="level" style="color:grey" onchange="apply_filters()">
+         <option value="0">basic</option>
+         <option value="1">advanced</option>
+         <option value="2">developer</option>
+       </select>
+      </div>
+    </h1>
+</section>
+       
+<!-- Main content -->
+<section class="content">
+    <div class="box" style="overflow:auto">
+      <div class="box-body">
+           <table class="table table-bordered">
+               <thead>
+                   <tr>
+                       <th>Name</th>
+                       <th>Description</th>
+                       <th>Long description</th>
+                       <th>Type</th>
+                       <th>Level</th>
+                       <th>Default</th>
+                       <th>Daemon default</th>
+                       <th>Tags</th>
+                       <th>Services</th>
+                       <th>See_also</th>
+                       <th>Max</th>
+                       <th>Min</th>
+                   </tr>
+               </thead>
+               <tbody>
+                   <tr rv-each-opt="options_list">
+                       <td><div style="width:120px;word-break:break-all">{opt.name}</div></td>
+                       <td><div style="width:80px;word-break:break-all">{opt.desc}</td>
+                       <td><div style="width:120px;word-break:break-all">{opt.long_desc}</div></td>
+                       <td><div style="width:70px;word-break:break-all">{opt.type}<div></td>
+                       <td>{opt.level}</td>
+                       <td><div style="width:80px;word-break:break-all">{opt.default}<div></td>
+                       <td><div style="width:120px;word-break:break-all">{opt.daemon_default}</div></td>
+                       <td rv-html="opt.tags | display_arrays"</td>
+                       <td rv-html="opt.services |  display_arrays"></td>
+                       <td rv-html="opt.see_also | display_arrays"</td>
+                       <td>{opt.max}</td>
+                       <td>{opt.min}</td>    
+                   </tr>
+               </tbody>
+           </table>
+       </div>  
+    </div>
+</section>
+
+{% endblock %}
index 3d5e3191aa654415cce5684e5e0fa0227d63e1a9..abe8f19450efcceafa2695a7298ee393706585ab 100644 (file)
@@ -750,6 +750,28 @@ class Module(MgrModule):
                     toplevel_data=json.dumps(self._toplevel_data(), indent=2),
                     content_data=json.dumps(self._servers(), indent=2)
                 )
+            
+            @cherrypy.expose
+            def config_options(self, service="any"):
+                template = env.get_template("config_options.html")
+                return template.render(
+                    url_prefix = global_instance().url_prefix,
+                    ceph_version=global_instance().version,
+                    path_info=cherrypy.request.path_info,
+                    toplevel_data=json.dumps(self._toplevel_data(), indent=2),
+                    content_data=json.dumps(self.config_options_data(service), indent=2)
+                )
+
+            @cherrypy.expose
+            @cherrypy.tools.json_out()
+            def config_options_data(self, service):
+                options = {}
+                options = global_instance().get("config_options")
+
+                return {
+                    'options': options,
+                    'service': service,
+                }
 
             def _servers(self):
                 return {
index b13ad17e1fd7ba0791ca12afa59f8ce1d11b940a..0ebe3d08943877a641ad500313f5f93e3fdddc43 100644 (file)
 <section class="content-header">
     <h1>
         osd.{osd.osd}
+        <button class="pull-right btn btn-default" style="margin-right:5px"><a href="{{url_prefix}}/config_options/osd">Configuration</a></button>
     </h1>
 </section>