]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/restful: remove deprecated module
authorErnesto Puerta <epuertat@redhat.com>
Mon, 6 May 2024 16:48:38 +0000 (18:48 +0200)
committerErnesto Puerta <epuertat@redhat.com>
Mon, 28 Oct 2024 13:17:18 +0000 (14:17 +0100)
Detailed changes:
* Remove `restful` mgr module dir,
* Remove Python depedencies (`pecan`, `werkzeug`) from ceph.spec and
  debian control,
* Remove docs,
* Remove associated QA tests,
* Update vstart.

Fixes: https://tracker.ceph.com/issues/47066
Signed-off-by: Ernesto Puerta <epuertat@redhat.com>
40 files changed:
ceph.spec.in
debian/ceph-mgr-modules-core.install
debian/ceph-mgr-modules-core.requires
debian/control
doc/_ext/ceph_commands.py
doc/_ext/ceph_confval.py
doc/dev/developer_guide/dash-devel.rst
doc/mgr/administrator.rst
doc/mgr/index.rst
doc/mgr/restful.rst [deleted file]
install-deps.sh
qa/suites/ceph-ansible/smoke/basic/2-ceph/ceph_ansible.yaml
qa/suites/ceph-ansible/smoke/basic/4-tasks/rest.yaml [deleted file]
qa/suites/cephmetrics/2-ceph/ceph_ansible.yaml
qa/suites/rados/rest/% [deleted file]
qa/suites/rados/rest/.qa [deleted symlink]
qa/suites/rados/rest/mgr-restful.yaml [deleted file]
qa/suites/rados/rest/supported-random-distro$ [deleted symlink]
qa/tasks/mgr/mgr_test_case.py
qa/workunits/cephtool/test.sh
qa/workunits/rest/test-restful.sh [deleted file]
src/common/options/mgr.yaml.in
src/pybind/mgr/CMakeLists.txt
src/pybind/mgr/restful/__init__.py [deleted file]
src/pybind/mgr/restful/api/__init__.py [deleted file]
src/pybind/mgr/restful/api/config.py [deleted file]
src/pybind/mgr/restful/api/crush.py [deleted file]
src/pybind/mgr/restful/api/doc.py [deleted file]
src/pybind/mgr/restful/api/mon.py [deleted file]
src/pybind/mgr/restful/api/osd.py [deleted file]
src/pybind/mgr/restful/api/perf.py [deleted file]
src/pybind/mgr/restful/api/pool.py [deleted file]
src/pybind/mgr/restful/api/request.py [deleted file]
src/pybind/mgr/restful/api/server.py [deleted file]
src/pybind/mgr/restful/common.py [deleted file]
src/pybind/mgr/restful/context.py [deleted file]
src/pybind/mgr/restful/decorators.py [deleted file]
src/pybind/mgr/restful/hooks.py [deleted file]
src/pybind/mgr/restful/module.py [deleted file]
src/vstart.sh

index 14c1420af40f04287e77040e2555d92dfba13979..a82758bf4580dd09216b5c75b1ceaac757659c70 100644 (file)
@@ -336,7 +336,6 @@ BuildRequires:  hostname
 BuildRequires:  jq
 BuildRequires: libuuid-devel
 BuildRequires: python%{python3_pkgversion}-bcrypt
-BuildRequires: python%{python3_pkgversion}-pecan
 BuildRequires: python%{python3_pkgversion}-requests
 BuildRequires: python%{python3_pkgversion}-dateutil
 BuildRequires: python%{python3_pkgversion}-coverage
@@ -469,7 +468,6 @@ BuildRequires:      xmlsec1-openssl-devel
 BuildRequires: python%{python3_pkgversion}-cherrypy
 BuildRequires: python%{python3_pkgversion}-routes
 BuildRequires: python%{python3_pkgversion}-scipy
-BuildRequires: python%{python3_pkgversion}-werkzeug
 BuildRequires: python%{python3_pkgversion}-pyOpenSSL
 %endif
 BuildRequires: jsonnet
@@ -480,7 +478,6 @@ BuildRequires:      libxmlsec1-nss1
 BuildRequires: libxmlsec1-openssl1
 BuildRequires: python%{python3_pkgversion}-CherryPy
 BuildRequires: python%{python3_pkgversion}-Routes
-BuildRequires: python%{python3_pkgversion}-Werkzeug
 BuildRequires: python%{python3_pkgversion}-numpy-devel
 BuildRequires: xmlsec1-devel
 BuildRequires: xmlsec1-openssl-devel
@@ -705,7 +702,6 @@ Recommends:     python%{python3_pkgversion}-grpcio-tools
 %if 0%{?suse_version}
 Requires:       python%{python3_pkgversion}-CherryPy
 Requires:       python%{python3_pkgversion}-Routes
-Requires:       python%{python3_pkgversion}-Werkzeug
 Recommends:     python%{python3_pkgversion}-python3-saml
 %endif
 %description mgr-dashboard
@@ -738,7 +734,6 @@ Group:          System/Filesystems
 %endif
 Requires:       python%{python3_pkgversion}-bcrypt
 Requires:       python%{python3_pkgversion}-packaging
-Requires:       python%{python3_pkgversion}-pecan
 Requires:       python%{python3_pkgversion}-pyOpenSSL
 Requires:       python%{python3_pkgversion}-requests
 Requires:       python%{python3_pkgversion}-dateutil
@@ -746,12 +741,10 @@ Requires:       python%{python3_pkgversion}-setuptools
 %if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?openEuler}
 Requires:       python%{python3_pkgversion}-cherrypy
 Requires:       python%{python3_pkgversion}-pyyaml
-Requires:       python%{python3_pkgversion}-werkzeug
 %endif
 %if 0%{?suse_version}
 Requires:       python%{python3_pkgversion}-CherryPy
 Requires:       python%{python3_pkgversion}-PyYAML
-Requires:       python%{python3_pkgversion}-Werkzeug
 %endif
 # RHEL8 has python 3.6 and that lacks dataclasses in the stdlib, so pull in the
 # backport dataclasses module instead.
@@ -1996,7 +1989,6 @@ fi
 %{_datadir}/ceph/mgr/progress
 %{_datadir}/ceph/mgr/prometheus
 %{_datadir}/ceph/mgr/rbd_support
-%{_datadir}/ceph/mgr/restful
 %{_datadir}/ceph/mgr/rgw
 %{_datadir}/ceph/mgr/selftest
 %{_datadir}/ceph/mgr/smb
index f2ad7452ac3e006a66fdd1dd183874e9214255d4..40fbd6f0bf59e665640b62b498739647b78e9dd1 100644 (file)
@@ -15,8 +15,6 @@ usr/share/ceph/mgr/pg_autoscaler
 usr/share/ceph/mgr/progress
 usr/share/ceph/mgr/prometheus
 usr/share/ceph/mgr/rbd_support
-usr/share/ceph/mgr/rgw
-usr/share/ceph/mgr/restful
 usr/share/ceph/mgr/selftest
 usr/share/ceph/mgr/snap_schedule
 usr/share/ceph/mgr/stats
index eeeca20bcff5ad1999cee6c8645614a3ceb7e2e3..07769e866f88aba462d4ef0ce29f34f906aaf0b6 100644 (file)
@@ -1,7 +1,5 @@
 natsort
 CherryPy
 packaging
-pecan
-werkzeug
 requests
 python-dateutil
index 36da5efd69afeaf661979878b324d3844aaf959b..d31a82bbc759cb9f8fdd8a22a907b1a9fe5541ac 100644 (file)
@@ -94,7 +94,6 @@ Build-Depends: automake,
                python3-all-dev,
                python3-cherrypy3,
                python3-natsort,
-               python3-pecan <pkg.ceph.check>,
                python3-bcrypt <pkg.ceph.check>,
                tox <pkg.ceph.check>,
                python3-coverage <pkg.ceph.check>,
@@ -107,7 +106,6 @@ Build-Depends: automake,
                python3-setuptools,
                python3-sphinx,
                python3-venv,
-               python3-werkzeug <pkg.ceph.check>,
                python3-yaml,
                ragel <pkg.ceph.crimson>,
                socat <pkg.ceph.check>,
index 3822a879293877f635671b34d9a4bf83bcb51057..0697c71f0e1ca464303fba27db70715803d76ba2 100644 (file)
@@ -285,12 +285,6 @@ class CephMgrCommands(Directive):
         # make diskprediction_local happy
         mock_imports += ['numpy',
                          'scipy']
-        # make restful happy
-        mock_imports += ['pecan',
-                         'pecan.rest',
-                         'pecan.hooks',
-                         'werkzeug',
-                         'werkzeug.serving']
 
         for m in mock_imports:
             args = {}
index cde538b45c9a3687ab130a209d4210c4309da612..da93d1b415c4e5ded571d275dc8f5bf0ec263537 100644 (file)
@@ -289,12 +289,6 @@ class CephOption(ObjectDescription):
         # make diskprediction_local happy
         mock_imports += ['numpy',
                          'scipy']
-        # make restful happy
-        mock_imports += ['pecan',
-                         'pecan.rest',
-                         'pecan.hooks',
-                         'werkzeug',
-                         'werkzeug.serving']
 
         for m in mock_imports:
             args = {}
index 2285690e383cfd13ec4ec0e29226349e18aee59c..e65e846cb5d3247b1408a122b57d1c6067573d13 100644 (file)
@@ -161,8 +161,6 @@ dashboard and its URLs::
 
   dashboard urls: https://192.168.178.84:41259, https://192.168.178.84:43259, https://192.168.178.84:45259
     w/ user/pass: admin / admin
-  restful urls: https://192.168.178.84:42259, https://192.168.178.84:44259, https://192.168.178.84:46259
-    w/ user/pass: admin / 598da51f-8cd1-4161-a970-b2944d5ad200
 
 During development (especially in backend development), you also want to
 check on occasions if the dashboard manager module is still running. To do so
@@ -175,8 +173,7 @@ should look similar to the following output:
 
   $ ./bin/ceph mgr services
   {
-      "dashboard": "https://home:41931/",
-      "restful": "https://home:42931/"
+      "dashboard": "https://home:41931/"
   }
 
 By default, this environment uses a randomly chosen port for Ceph Dashboard
index d59b013aa57e52b51cc570613e1502ccbff60629..18f3f0f21908edc0f1ec1eca637290b06084d320 100644 (file)
@@ -100,7 +100,6 @@ Here is an example of enabling the :term:`Dashboard` module:
        $ ceph mgr module ls
        {
                "enabled_modules": [
-                       "restful",
                        "status"
                ],
                "disabled_modules": [
@@ -112,7 +111,6 @@ Here is an example of enabling the :term:`Dashboard` module:
        $ ceph mgr module ls
        {
                "enabled_modules": [
-                       "restful",
                        "status",
                        "dashboard"
                ],
@@ -122,8 +120,7 @@ Here is an example of enabling the :term:`Dashboard` module:
 
        $ ceph mgr services
        {
-               "dashboard": "http://myserver.com:7789/",
-               "restful": "https://myserver.com:8789/"
+               "dashboard": "http://myserver.com:7789/"
        }
 
 
index e74145d4f8e43f887d6133b98c2aab257169615e..1c47e3a8efcedffea53bd65af2bcff4c287f7c76 100644 (file)
@@ -33,7 +33,6 @@ sensible.
     Alerts module <alerts>
     DiskPrediction module <diskprediction>
     Local pool module <localpool>
-    RESTful module <restful>
     Zabbix module <zabbix>
     Prometheus module <prometheus>
     Influx module <influx>
diff --git a/doc/mgr/restful.rst b/doc/mgr/restful.rst
deleted file mode 100644 (file)
index c36f2cd..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-Restful Module
-==============
-
-RESTful module offers the REST API access to the status of the cluster
-over an SSL-secured connection.
-
-Enabling
---------
-
-The *restful* module is enabled with::
-
-  ceph mgr module enable restful
-
-You will also need to configure an SSL certificate below before the
-API endpoint is available.  By default the module will accept HTTPS
-requests on port ``8003`` on all IPv4 and IPv6 addresses on the host.
-
-Securing
---------
-
-All connections to *restful* are secured with SSL.  You can generate a
-self-signed certificate with the command::
-
-  ceph restful create-self-signed-cert
-
-Note that with a self-signed certificate most clients will need a flag
-to allow a connection and/or suppress warning messages.  For example,
-if the ``ceph-mgr`` daemon is on the same host,::
-
-  curl -k https://localhost:8003/
-
-To properly secure a deployment, a certificate that is signed by the
-organization's certificate authority should be used.  For example, a key pair
-can be generated with a command similar to::
-
-  openssl req -new -nodes -x509 \
-    -subj "/O=IT/CN=ceph-mgr-restful" \
-    -days 3650 -keyout restful.key -out restful.crt -extensions v3_ca
-
-The ``restful.crt`` should then be signed by your organization's CA
-(certificate authority).  Once that is done, you can set it with::
-
-  ceph config-key set mgr/restful/$name/crt -i restful.crt
-  ceph config-key set mgr/restful/$name/key -i restful.key
-
-where ``$name`` is the name of the ``ceph-mgr`` instance (usually the
-hostname). If all manager instances are to share the same certificate,
-you can leave off the ``$name`` portion::
-
-  ceph config-key set mgr/restful/crt -i restful.crt
-  ceph config-key set mgr/restful/key -i restful.key
-
-
-Configuring IP and port
------------------------
-
-Like any other RESTful API endpoint, *restful* binds to an IP and
-port.  By default, the currently active ``ceph-mgr`` daemon will bind
-to port 8003 and any available IPv4 or IPv6 address on the host.
-
-Since each ``ceph-mgr`` hosts its own instance of *restful*, it may
-also be necessary to configure them separately. The IP and port
-can be changed via the configuration key facility::
-
-  ceph config set mgr mgr/restful/$name/server_addr $IP
-  ceph config set mgr mgr/restful/$name/server_port $PORT
-
-where ``$name`` is the ID of the ceph-mgr daemon (usually the hostname).
-
-These settings can also be configured cluster-wide and not manager
-specific.  For example,::
-
-  ceph config set mgr mgr/restful/server_addr $IP
-  ceph config set mgr mgr/restful/server_port $PORT
-
-If the port is not configured, *restful* will bind to port ``8003``.
-If the address it not configured, the *restful* will bind to ``::``,
-which corresponds to all available IPv4 and IPv6 addresses.
-
-Configuring max_request
----------------------------
-
-The maximum request size can be configured via a central configuration
-option::
-
-  ceph config set mgr mgr/restful/$name/max_requests $NUM
-
-where ``$name`` is the ID of the ceph-mgr daemon (usually the hostname).
-
-.. mgr_module:: restful
-.. confval:: max_requests
-
-.. _creating-an-api-user:
-
-Creating an API User
------------------------
-
-To create an API user, please run the following command::
-
-  ceph restful create-key <username>
-
-Replace ``<username>`` with the desired name of the user. For example, to create a user named
-``api``::
-
-  $ ceph restful create-key api
-  52dffd92-a103-4a10-bfce-5b60f48f764e
-
-The UUID generated from ``ceph restful create-key api`` acts as the key for the user.
-
-To list all of your API keys, please run the following command::
-
-  ceph restful list-keys
-
-The ``ceph restful list-keys`` command will output in JSON::
-
-  {
-       "api": "52dffd92-a103-4a10-bfce-5b60f48f764e"
-  }
-
-You can use ``curl`` in order to test your user with the API. Here is an example::
-
-  curl -k https://api:52dffd92-a103-4a10-bfce-5b60f48f764e@<ceph-mgr>:<port>/server
-
-In the case above, we are using ``GET`` to fetch information from the ``server`` endpoint.
-
-Load balancer
--------------
-
-Please note that *restful* will *only* start on the manager which
-is active at that moment. Query the Ceph cluster status to see which
-manager is active (e.g., ``ceph mgr dump``).  In order to make the
-API available via a consistent URL regardless of which manager
-daemon is currently active, you may want to set up a load balancer
-front-end to direct traffic to whichever manager endpoint is
-available.
-
-Available methods
------------------
-
-You can navigate to the ``/doc`` endpoint for full list of available
-endpoints and HTTP methods implemented for each endpoint.
-
-For example, if you want to use the PATCH method of the ``/osd/<id>``
-endpoint to set the state ``up`` of the OSD id ``1``, you can use the
-following curl command::
-
-  echo -En '{"up": true}' | curl --request PATCH --data @- --silent --insecure --user <user> 'https://<ceph-mgr>:<port>/osd/1'
-
-or you can use python to do so::
-
-  $ python
-  >> import requests
-  >> result = requests.patch(
-         'https://<ceph-mgr>:<port>/osd/1',
-         json={"up": True},
-         auth=("<user>", "<password>")
-     )
-  >> print result.json()
-
-Some of the other endpoints implemented in the *restful* module include
-
-* ``/config/cluster``: **GET**
-* ``/config/osd``: **GET**, **PATCH**
-* ``/crush/rule``: **GET**
-* ``/mon``: **GET**
-* ``/osd``: **GET**
-* ``/pool``: **GET**, **POST**
-* ``/pool/<arg>``: **DELETE**, **GET**, **PATCH**
-* ``/request``: **DELETE**, **GET**, **POST**
-* ``/request/<arg>``: **DELETE**, **GET**
-* ``/server``: **GET**
-
-The ``/request`` endpoint
--------------------------
-
-You can use the ``/request`` endpoint to poll the state of a request
-you scheduled with any **DELETE**, **POST** or **PATCH** method. These
-methods are by default asynchronous since it may take longer for them
-to finish execution. You can modify this behaviour by appending
-``?wait=1`` to the request url. The returned request will then always
-be completed.
-
-The **POST** method of the ``/request`` method provides a passthrough
-for the ceph mon commands as defined in ``src/mon/MonCommands.h``.
-Let's consider the following command::
-
-  COMMAND("osd ls " \
-          "name=epoch,type=CephInt,range=0,req=false", \
-          "show all OSD ids", "osd", "r", "cli,rest")
-
-The **prefix** is **osd ls**. The optional argument's name is **epoch**
-and it is of type ``CephInt``, i.e. ``integer``. This means that you
-need to do the following **POST** request to schedule the command::
-
-  $ python
-  >> import requests
-  >> result = requests.post(
-         'https://<ceph-mgr>:<port>/request',
-         json={'prefix': 'osd ls', 'epoch': 0},
-         auth=("<user>", "<password>")
-     )
-  >> print result.json()
index d5eafba48cc0a08d3da216f9c9489e2f1e958e36..909e41957a9305a69d31c6610d1f2b8187255f98 100755 (executable)
@@ -374,10 +374,6 @@ if [ x$(uname)x = xFreeBSDx ]; then
         security/oath-toolkit \
         sysutils/flock \
         sysutils/fusefs-libs \
-
-        # Now use pip to install some extra python modules
-        pip install pecan
-
     exit
 else
     [ $WITH_SEASTAR ] && with_seastar=true || with_seastar=false
index 7e7ede3e3348fd5379cda876f3e87c4e88e60e4f..5be06bc6732806003a9d5c91cb2acd5793618093 100644 (file)
@@ -21,7 +21,6 @@ overrides:
         ceph_repository: dev
         ceph_mgr_modules:
           - status
-          - restful
         cephfs_pools:
           - name: "cephfs_data"
             pg_num: "64"
diff --git a/qa/suites/ceph-ansible/smoke/basic/4-tasks/rest.yaml b/qa/suites/ceph-ansible/smoke/basic/4-tasks/rest.yaml
deleted file mode 100644 (file)
index 8e38913..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-tasks:
-- exec:
-    mgr.x:
-      - systemctl stop ceph-mgr.target
-      - sleep 5
-      - ceph -s
-- exec:
-    mon.a:
-      - ceph restful create-key admin
-      - ceph restful create-self-signed-cert
-      - ceph restful restart
-- workunit:
-    clients:
-      client.0:
-        - rest/test-restful.sh
index 309f50600452a88e19be0bdb4ad587719a3286b3..53e2b7fdbc8d4d14dd90ede72eb85fe9e325add3 100644 (file)
@@ -20,7 +20,6 @@ overrides:
         ceph_repository: dev
         ceph_mgr_modules:
           - status
-          - restful
         cephfs_pools:
           - name: "cephfs_data"
             pg_num: "64"
diff --git a/qa/suites/rados/rest/% b/qa/suites/rados/rest/%
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/qa/suites/rados/rest/.qa b/qa/suites/rados/rest/.qa
deleted file mode 120000 (symlink)
index a602a03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../.qa/
\ No newline at end of file
diff --git a/qa/suites/rados/rest/mgr-restful.yaml b/qa/suites/rados/rest/mgr-restful.yaml
deleted file mode 100644 (file)
index 4901f40..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-openstack:
-- volumes: # attached to each instance
-    count: 3
-    size: 10 # GB
-roles:
-- [mon.a, mgr.x, osd.0, osd.1, osd.2, mds.a, client.a]
-tasks:
-- install:
-- ceph:
-    log-ignorelist:
-      - overall HEALTH_
-      - \(MGR_DOWN\)
-      - \(PG_
-      - \(OSD_
-      - \(OBJECT_
-      - \(OSDMAP_FLAGS\)
-      - \(POOL_APP_NOT_ENABLED\)
-- exec:
-    mon.a:
-      - ceph restful create-key admin
-      - ceph restful create-self-signed-cert
-      - ceph restful restart
-- workunit:
-    clients:
-      client.a:
-        - rest/test-restful.sh
-- exec:
-    mon.a:
-      - ceph restful delete-key admin
-      - ceph restful list-keys | jq ".admin" | grep null
-
diff --git a/qa/suites/rados/rest/supported-random-distro$ b/qa/suites/rados/rest/supported-random-distro$
deleted file mode 120000 (symlink)
index 7cef21e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../basic/supported-random-distro$
\ No newline at end of file
index 74b1e9d850cb468fd445cb78eb2f9a0931d78b79..9032e0e2658da3ad82c2b71e8a34ea1c3f3836a1 100644 (file)
@@ -108,7 +108,7 @@ class MgrTestCase(CephTestCase):
         # Unload all non-default plugins
         loaded = json.loads(cls.mgr_cluster.mon_manager.raw_cluster_cmd(
                    "mgr", "module", "ls", "--format=json-pretty"))['enabled_modules']
-        unload_modules = set(loaded) - {"cephadm", "restful"}
+        unload_modules = set(loaded) - {"cephadm"}
 
         for m in unload_modules:
             cls.mgr_cluster.mon_manager.raw_cluster_cmd(
@@ -137,7 +137,7 @@ class MgrTestCase(CephTestCase):
             raise SkipTest(
                 "Only have {0} manager daemons, {1} are required".format(
                     len(cls.mgr_cluster.mgr_ids), cls.MGRS_REQUIRED))
-        
+
         # We expect laggy OSDs in this testing environment so turn off this warning.
         # See https://tracker.ceph.com/issues/61907
         cls.mgr_cluster.mon_manager.raw_cluster_cmd('config', 'set', 'mds',
index cdfff17d837ef50b337fdced121c020268f1e864..ad5950367e9d9197aad1b3423deda8359049fe6d 100755 (executable)
@@ -63,7 +63,7 @@ function retry_eagain()
     for count in $(seq 1 $max) ; do
         status=0
         "$@" > $tmpfile 2>&1 || status=$?
-        if test $status = 0 || 
+        if test $status = 0 ||
             ! grep --quiet EAGAIN $tmpfile ; then
             break
         fi
@@ -108,7 +108,7 @@ function check_response()
                exit 1
        fi
 
-       if ! grep --quiet -- "$expected_string" $TMPFILE ; then 
+       if ! grep --quiet -- "$expected_string" $TMPFILE ; then
                echo "Didn't find $expected_string in output" >&2
                cat $TMPFILE >&2
                exit 1
@@ -696,7 +696,7 @@ function test_auth_profiles()
 
   ceph -n client.xx-profile-rd -k client.xx.keyring auth del client.xx-profile-ro
   ceph -n client.xx-profile-rd -k client.xx.keyring auth del client.xx-profile-rw
-  
+
   # add a new role-definer with the existing role-definer
   ceph -n client.xx-profile-rd -k client.xx.keyring \
     auth add client.xx-profile-rd2 mon 'allow profile role-definer'
@@ -730,7 +730,7 @@ function test_mon_caps()
   ceph-authtool -n client.bug --cap mon '' $TEMP_DIR/ceph.client.bug.keyring
   ceph auth add client.bug -i  $TEMP_DIR/ceph.client.bug.keyring
   rados lspools --no-mon-config --keyring $TEMP_DIR/ceph.client.bug.keyring -n client.bug >& $TMPFILE || true
-  check_response "Permission denied"  
+  check_response "Permission denied"
 }
 
 function test_mon_misc()
@@ -780,7 +780,6 @@ function test_mon_misc()
   ceph mgr dump
   ceph mgr dump | jq -e '.active_clients[0].name'
   ceph mgr module ls
-  ceph mgr module enable restful
   expect_false ceph mgr module enable foodne
   ceph mgr module enable foodne --force
   ceph mgr module disable foodne
@@ -1650,7 +1649,7 @@ function test_mon_osd()
   dump_json=$(ceph osd dump --format=json | \
          jq -cM '.osds[] | select(.osd == 0)')
   [[ "${info_json}" == "${dump_json}" ]]
-  
+
   info_plain="$(ceph osd info)"
   dump_plain="$(ceph osd dump | grep '^osd')"
   [[ "${info_plain}" == "${dump_plain}" ]]
@@ -2244,7 +2243,7 @@ function test_mon_pg()
   # tell osd version
   #
   ceph tell osd.0 version
-  expect_false ceph tell osd.9999 version 
+  expect_false ceph tell osd.9999 version
   expect_false ceph tell osd.foo version
 
   # back to pg stuff
@@ -2336,7 +2335,7 @@ function test_mon_osd_pool_set()
   ceph osd pool get $TEST_POOL_GETSET deep_scrub_interval | expect_false grep '.'
 
   ceph osd pool get $TEST_POOL_GETSET recovery_priority | expect_false grep '.'
-  ceph osd pool set $TEST_POOL_GETSET recovery_priority 5 
+  ceph osd pool set $TEST_POOL_GETSET recovery_priority 5
   ceph osd pool get $TEST_POOL_GETSET recovery_priority | grep 'recovery_priority: 5'
   ceph osd pool set $TEST_POOL_GETSET recovery_priority -5
   ceph osd pool get $TEST_POOL_GETSET recovery_priority | grep 'recovery_priority: -5'
@@ -2346,13 +2345,13 @@ function test_mon_osd_pool_set()
   expect_false ceph osd pool set $TEST_POOL_GETSET recovery_priority 11
 
   ceph osd pool get $TEST_POOL_GETSET recovery_op_priority | expect_false grep '.'
-  ceph osd pool set $TEST_POOL_GETSET recovery_op_priority 5 
+  ceph osd pool set $TEST_POOL_GETSET recovery_op_priority 5
   ceph osd pool get $TEST_POOL_GETSET recovery_op_priority | grep 'recovery_op_priority: 5'
   ceph osd pool set $TEST_POOL_GETSET recovery_op_priority 0
   ceph osd pool get $TEST_POOL_GETSET recovery_op_priority | expect_false grep '.'
 
   ceph osd pool get $TEST_POOL_GETSET scrub_priority | expect_false grep '.'
-  ceph osd pool set $TEST_POOL_GETSET scrub_priority 5 
+  ceph osd pool set $TEST_POOL_GETSET scrub_priority 5
   ceph osd pool get $TEST_POOL_GETSET scrub_priority | grep 'scrub_priority: 5'
   ceph osd pool set $TEST_POOL_GETSET scrub_priority 0
   ceph osd pool get $TEST_POOL_GETSET scrub_priority | expect_false grep '.'
@@ -2386,10 +2385,10 @@ function test_mon_osd_pool_set()
   ceph osd pool set $TEST_POOL_GETSET size 2
   wait_for_clean
   ceph osd pool set $TEST_POOL_GETSET min_size 2
-  
+
   expect_false ceph osd pool set $TEST_POOL_GETSET hashpspool 0
   ceph osd pool set $TEST_POOL_GETSET hashpspool 0 --yes-i-really-mean-it
-  
+
   expect_false ceph osd pool set $TEST_POOL_GETSET hashpspool 1
   ceph osd pool set $TEST_POOL_GETSET hashpspool 1 --yes-i-really-mean-it
 
@@ -2587,7 +2586,7 @@ function test_mon_osd_misc()
   ceph osd map 2>$TMPFILE; check_response 'pool' $? 22
 
   # expect error about unused argument foo
-  ceph osd ls foo 2>$TMPFILE; check_response 'unused' $? 22 
+  ceph osd ls foo 2>$TMPFILE; check_response 'unused' $? 22
 
   # expect "not in range" for invalid overload percentage
   ceph osd reweight-by-utilization 80 2>$TMPFILE; check_response 'higher than 100' $? 22
diff --git a/qa/workunits/rest/test-restful.sh b/qa/workunits/rest/test-restful.sh
deleted file mode 100755 (executable)
index fde0d10..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh -ex
-
-mydir=`dirname $0`
-
-secret=`ceph config-key get mgr/restful/keys/admin`
-url=$(ceph mgr dump|jq -r .services.restful|sed -e 's/\/$//')
-echo "url $url secret $secret"
-$mydir/test_mgr_rest_api.py $url $secret
-
-echo $0 OK
index 773b0d3659153e78ca121587e503b9704efc3676..5095710afdff9b4dd63594b3e229d23d8eb9303f 100644 (file)
@@ -152,7 +152,7 @@ options:
     first started after installation, to populate the list of enabled manager modules.  Subsequent
     updates are done using the 'mgr module [enable|disable]' commands.  List may be
     comma or space separated.
-  default: restful iostat nfs
+  default: iostat nfs
   services:
   - mon
   - common
index b2a8ac9a325dce92f8ce0bdb5aeef08b02d2f1e8..f95f10d1b2a2c211c7d80e4f0a664ca5bd8751f6 100644 (file)
@@ -42,7 +42,6 @@ set(mgr_modules
   progress
   prometheus
   rbd_support
-  restful
   rgw
   # rook (optional)
   selftest
diff --git a/src/pybind/mgr/restful/__init__.py b/src/pybind/mgr/restful/__init__.py
deleted file mode 100644 (file)
index 8f210ac..0000000
+++ /dev/null
@@ -1 +0,0 @@
-from .module import Module
diff --git a/src/pybind/mgr/restful/api/__init__.py b/src/pybind/mgr/restful/api/__init__.py
deleted file mode 100644 (file)
index a105dfe..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from pecan import expose
-from pecan.rest import RestController
-
-from .config import Config
-from .crush import Crush
-from .doc import Doc
-from .mon import Mon
-from .osd import Osd
-from .pool import Pool
-from .perf import Perf
-from .request import Request
-from .server import Server
-
-
-class Root(RestController):
-    config = Config()
-    crush = Crush()
-    doc = Doc()
-    mon = Mon()
-    osd = Osd()
-    perf = Perf()
-    pool = Pool()
-    request = Request()
-    server = Server()
-
-    @expose(template='json')
-    def get(self, **kwargs):
-        """
-        Show the basic information for the REST API
-        This includes values like api version or auth method
-        """
-        return {
-            'api_version': 1,
-            'auth':
-                'Use "ceph restful create-key <key>" to create a key pair, '
-                'pass it as HTTP Basic auth to authenticate',
-            'doc': 'See /doc endpoint',
-            'info': "Ceph Manager RESTful API server",
-        }
diff --git a/src/pybind/mgr/restful/api/config.py b/src/pybind/mgr/restful/api/config.py
deleted file mode 100644 (file)
index 5b0e0af..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-from pecan import expose, request
-from pecan.rest import RestController
-
-from restful import common, context
-from restful.decorators import auth
-
-
-class ConfigOsd(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show OSD configuration options
-        """
-        flags = context.instance.get("osd_map")['flags']
-
-        # pause is a valid osd config command that sets pauserd,pausewr
-        flags = flags.replace('pauserd,pausewr', 'pause')
-
-        return flags.split(',')
-
-
-    @expose(template='json')
-    @auth
-    def patch(self, **kwargs):
-        """
-        Modify OSD configuration options
-        """
-        args = request.json
-
-        commands = []
-
-        valid_flags = set(args.keys()) & set(common.OSD_FLAGS)
-        invalid_flags = list(set(args.keys()) - valid_flags)
-        if invalid_flags:
-            context.instance.log.warning("%s not valid to set/unset", invalid_flags)
-
-        for flag in list(valid_flags):
-            if args[flag]:
-                mode = 'set'
-            else:
-                mode = 'unset'
-
-            commands.append({
-                'prefix': 'osd ' + mode,
-                'key': flag,
-            })
-
-        return context.instance.submit_request([commands], **kwargs)
-
-
-
-class ConfigClusterKey(RestController):
-    def __init__(self, key):
-        self.key = key
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show specific configuration option
-        """
-        return context.instance.get("config").get(self.key, None)
-
-
-
-class ConfigCluster(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show all cluster configuration options
-        """
-        return context.instance.get("config")
-
-
-    @expose()
-    def _lookup(self, key, *remainder):
-        return ConfigClusterKey(key), remainder
-
-
-
-class Config(RestController):
-    cluster = ConfigCluster()
-    osd = ConfigOsd()
diff --git a/src/pybind/mgr/restful/api/crush.py b/src/pybind/mgr/restful/api/crush.py
deleted file mode 100644 (file)
index 79f9007..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from pecan import expose
-from pecan.rest import RestController
-
-from restful import common, context
-
-from restful.decorators import auth
-
-
-class CrushRule(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show crush rules
-        """
-        crush = context.instance.get('osd_map_crush')
-        rules = crush['rules']
-
-        for rule in rules:
-            rule['osd_count'] = len(common.crush_rule_osds(crush['buckets'], rule))
-
-        return rules
-
-class Crush(RestController):
-    rule = CrushRule()
diff --git a/src/pybind/mgr/restful/api/doc.py b/src/pybind/mgr/restful/api/doc.py
deleted file mode 100644 (file)
index f1038c2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from pecan import expose
-from pecan.rest import RestController
-
-from restful import context
-
-import restful
-
-
-class Doc(RestController):
-    @expose(template='json')
-    def get(self, **kwargs):
-        """
-        Show documentation information
-        """
-        return context.instance.get_doc_api(restful.api.Root)
diff --git a/src/pybind/mgr/restful/api/mon.py b/src/pybind/mgr/restful/api/mon.py
deleted file mode 100644 (file)
index 20d0336..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from pecan import expose, response
-from pecan.rest import RestController
-
-from restful import context
-from restful.decorators import auth
-
-
-class MonName(RestController):
-    def __init__(self, name):
-        self.name = name
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for the monitor name
-        """
-        mon = [x for x in context.instance.get_mons()
-               if x['name'] == self.name]
-        if len(mon) != 1:
-            response.status = 500
-            return {'message': 'Failed to identify the monitor node "{}"'.format(self.name)}
-        return mon[0]
-
-
-
-class Mon(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for all the monitors
-        """
-        return context.instance.get_mons()
-
-
-    @expose()
-    def _lookup(self, name, *remainder):
-        return MonName(name), remainder
diff --git a/src/pybind/mgr/restful/api/osd.py b/src/pybind/mgr/restful/api/osd.py
deleted file mode 100644 (file)
index 8577fae..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-from pecan import expose, request, response
-from pecan.rest import RestController
-
-from restful import common, context
-from restful.decorators import auth
-
-
-class OsdIdCommand(RestController):
-    def __init__(self, osd_id):
-        self.osd_id = osd_id
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show implemented commands for the OSD id
-        """
-        osd = context.instance.get_osd_by_id(self.osd_id)
-
-        if not osd:
-            response.status = 500
-            return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)}
-
-        if osd['up']:
-            return common.OSD_IMPLEMENTED_COMMANDS
-        else:
-            return []
-
-
-    @expose(template='json')
-    @auth
-    def post(self, **kwargs):
-        """
-        Run the implemented command for the OSD id
-        """
-        command = request.json.get('command', None)
-
-        osd = context.instance.get_osd_by_id(self.osd_id)
-
-        if not osd:
-            response.status = 500
-            return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)}
-
-        if not osd['up'] or command not in common.OSD_IMPLEMENTED_COMMANDS:
-            response.status = 500
-            return {'message': 'Command "{}" not available'.format(command)}
-
-        return context.instance.submit_request([[{
-            'prefix': 'osd ' + command,
-            'who': str(self.osd_id)
-        }]], **kwargs)
-
-
-
-class OsdId(RestController):
-    def __init__(self, osd_id):
-        self.osd_id = osd_id
-        self.command = OsdIdCommand(osd_id)
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for the OSD id
-        """
-        osd = context.instance.get_osds(ids=[str(self.osd_id)])
-        if len(osd) != 1:
-            response.status = 500
-            return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)}
-
-        return osd[0]
-
-
-    @expose(template='json')
-    @auth
-    def patch(self, **kwargs):
-        """
-        Modify the state (up, in) of the OSD id or reweight it
-        """
-        args = request.json
-
-        commands = []
-
-        if 'in' in args:
-            if args['in']:
-                commands.append({
-                    'prefix': 'osd in',
-                    'ids': [str(self.osd_id)]
-                })
-            else:
-                commands.append({
-                    'prefix': 'osd out',
-                    'ids': [str(self.osd_id)]
-                })
-
-        if 'up' in args:
-            if args['up']:
-                response.status = 500
-                return {'message': "It is not valid to set a down OSD to be up"}
-            else:
-                commands.append({
-                    'prefix': 'osd down',
-                    'ids': [str(self.osd_id)]
-                })
-
-        if 'reweight' in args:
-            commands.append({
-                'prefix': 'osd reweight',
-                'id': self.osd_id,
-                'weight': args['reweight']
-            })
-
-        return context.instance.submit_request([commands], **kwargs)
-
-
-
-class Osd(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for all the OSDs
-        """
-        # Parse request args
-        # TODO Filter by ids
-        pool_id = kwargs.get('pool', None)
-
-        return context.instance.get_osds(pool_id)
-
-
-    @expose()
-    def _lookup(self, osd_id, *remainder):
-        return OsdId(int(osd_id)), remainder
diff --git a/src/pybind/mgr/restful/api/perf.py b/src/pybind/mgr/restful/api/perf.py
deleted file mode 100644 (file)
index c484ac5..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from pecan import expose, request, response
-from pecan.rest import RestController
-
-from restful import context
-from restful.decorators import auth, lock, paginate
-
-import re
-
-class Perf(RestController):
-    @expose(template='json')
-    @paginate
-    @auth
-    def get(self, **kwargs):
-        """
-        List all the available performance counters
-
-        Options:
-         - 'daemon' -- filter by daemon, accepts Python regexp
-        """
-
-        counters = context.instance.get_unlabeled_perf_counters()
-
-        if 'daemon' in kwargs:
-            _re = re.compile(kwargs['daemon'])
-            counters = {k: v for k, v in counters.items() if _re.match(k)}
-
-        return counters
diff --git a/src/pybind/mgr/restful/api/pool.py b/src/pybind/mgr/restful/api/pool.py
deleted file mode 100644 (file)
index 40de54e..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-from pecan import expose, request, response
-from pecan.rest import RestController
-
-from restful import common, context
-from restful.decorators import auth
-
-
-class PoolId(RestController):
-    def __init__(self, pool_id):
-        self.pool_id = pool_id
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for the pool id
-        """
-        pool = context.instance.get_pool_by_id(self.pool_id)
-
-        if not pool:
-            response.status = 500
-            return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)}
-
-        # pgp_num is called pg_placement_num, deal with that
-        if 'pg_placement_num' in pool:
-            pool['pgp_num'] = pool.pop('pg_placement_num')
-        return pool
-
-
-    @expose(template='json')
-    @auth
-    def patch(self, **kwargs):
-        """
-        Modify the information for the pool id
-        """
-        try:
-            args = request.json
-        except ValueError:
-            response.status = 400
-            return {'message': 'Bad request: malformed JSON or wrong Content-Type'}
-
-        # Get the pool info for its name
-        pool = context.instance.get_pool_by_id(self.pool_id)
-        if not pool:
-            response.status = 500
-            return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)}
-
-        # Check for invalid pool args
-        invalid = common.invalid_pool_args(args)
-        if invalid:
-            response.status = 500
-            return {'message': 'Invalid arguments found: "{}"'.format(invalid)}
-
-        # Schedule the update request
-        return context.instance.submit_request(common.pool_update_commands(pool['pool_name'], args), **kwargs)
-
-
-    @expose(template='json')
-    @auth
-    def delete(self, **kwargs):
-        """
-        Remove the pool data for the pool id
-        """
-        pool = context.instance.get_pool_by_id(self.pool_id)
-
-        if not pool:
-            response.status = 500
-            return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)}
-
-        return context.instance.submit_request([[{
-            'prefix': 'osd pool delete',
-            'pool': pool['pool_name'],
-            'pool2': pool['pool_name'],
-            'yes_i_really_really_mean_it': True
-        }]], **kwargs)
-
-
-
-class Pool(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for all the pools
-        """
-        pools = context.instance.get('osd_map')['pools']
-
-        # pgp_num is called pg_placement_num, deal with that
-        for pool in pools:
-            if 'pg_placement_num' in pool:
-                pool['pgp_num'] = pool.pop('pg_placement_num')
-
-        return pools
-
-
-    @expose(template='json')
-    @auth
-    def post(self, **kwargs):
-        """
-        Create a new pool
-        Requires name and pg_num dict arguments
-        """
-        args = request.json
-
-        # Check for the required arguments
-        pool_name = args.pop('name', None)
-        if pool_name is None:
-            response.status = 500
-            return {'message': 'You need to specify the pool "name" argument'}
-
-        pg_num = args.pop('pg_num', None)
-        if pg_num is None:
-            response.status = 500
-            return {'message': 'You need to specify the "pg_num" argument'}
-
-        # Run the pool create command first
-        create_command = {
-            'prefix': 'osd pool create',
-            'pool': pool_name,
-            'pg_num': pg_num
-        }
-
-        # Check for invalid pool args
-        invalid = common.invalid_pool_args(args)
-        if invalid:
-            response.status = 500
-            return {'message': 'Invalid arguments found: "{}"'.format(invalid)}
-
-        # Schedule the creation and update requests
-        return context.instance.submit_request(
-            [[create_command]] +
-            common.pool_update_commands(pool_name, args),
-            **kwargs
-        )
-
-
-    @expose()
-    def _lookup(self, pool_id, *remainder):
-        return PoolId(int(pool_id)), remainder
diff --git a/src/pybind/mgr/restful/api/request.py b/src/pybind/mgr/restful/api/request.py
deleted file mode 100644 (file)
index 67143ef..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-from pecan import expose, request, response
-from pecan.rest import RestController
-
-from restful import context
-from restful.decorators import auth, lock, paginate
-
-
-class RequestId(RestController):
-    def __init__(self, request_id):
-        self.request_id = request_id
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for the request id
-        """
-        request = [x for x in context.instance.requests
-                   if x.id == self.request_id]
-        if len(request) != 1:
-            response.status = 500
-            return {'message': 'Unknown request id "{}"'.format(self.request_id)}
-        return request[0]
-
-
-    @expose(template='json')
-    @auth
-    @lock
-    def delete(self, **kwargs):
-        """
-        Remove the request id from the database
-        """
-        for index in range(len(context.instance.requests)):
-            if context.instance.requests[index].id == self.request_id:
-                return context.instance.requests.pop(index)
-
-        # Failed to find the job to cancel
-        response.status = 500
-        return {'message': 'No such request id'}
-
-
-
-class Request(RestController):
-    @expose(template='json')
-    @paginate
-    @auth
-    def get(self, **kwargs):
-        """
-        List all the available requests
-        """
-        return context.instance.requests
-
-
-    @expose(template='json')
-    @auth
-    @lock
-    def delete(self, **kwargs):
-        """
-        Remove all the finished requests
-        """
-        num_requests = len(context.instance.requests)
-
-        context.instance.requests = [x for x in context.instance.requests
-                                     if not x.is_finished()]
-        remaining = len(context.instance.requests)
-        # Return the job statistics
-        return {
-            'cleaned': num_requests - remaining,
-            'remaining': remaining,
-        }
-
-
-    @expose(template='json')
-    @auth
-    def post(self, **kwargs):
-        """
-        Pass through method to create any request
-        """
-        if isinstance(request.json, list):
-            if all(isinstance(element, list) for element in request.json):
-                return context.instance.submit_request(request.json, **kwargs)
-
-            # The request.json has wrong format
-            response.status = 500
-            return {'message': 'The request format should be [[{c1},{c2}]]'}
-
-        return context.instance.submit_request([[request.json]], **kwargs)
-
-
-    @expose()
-    def _lookup(self, request_id, *remainder):
-        return RequestId(request_id), remainder
diff --git a/src/pybind/mgr/restful/api/server.py b/src/pybind/mgr/restful/api/server.py
deleted file mode 100644 (file)
index 8ce6349..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from pecan import expose
-from pecan.rest import RestController
-
-from restful import context
-from restful.decorators import auth
-
-
-class ServerFqdn(RestController):
-    def __init__(self, fqdn):
-        self.fqdn = fqdn
-
-
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for the server fqdn
-        """
-        return context.instance.get_server(self.fqdn)
-
-
-
-class Server(RestController):
-    @expose(template='json')
-    @auth
-    def get(self, **kwargs):
-        """
-        Show the information for all the servers
-        """
-        return context.instance.list_servers()
-
-
-    @expose()
-    def _lookup(self, fqdn, *remainder):
-        return ServerFqdn(fqdn), remainder
diff --git a/src/pybind/mgr/restful/common.py b/src/pybind/mgr/restful/common.py
deleted file mode 100644 (file)
index 1b957d6..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-# List of valid osd flags
-OSD_FLAGS = [
-    'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill',
-    'norecover', 'noscrub', 'nodeep-scrub',
-]
-
-# Implemented osd commands
-OSD_IMPLEMENTED_COMMANDS = [
-    'scrub', 'deep-scrub', 'repair'
-]
-
-# Valid values for the 'var' argument to 'ceph osd pool set'
-POOL_PROPERTIES_1 = [
-    'size', 'min_size', 'pg_num',
-    'crush_rule', 'hashpspool',
-]
-
-POOL_PROPERTIES_2 = [
-    'pgp_num'
-]
-
-POOL_PROPERTIES = POOL_PROPERTIES_1 + POOL_PROPERTIES_2
-
-# Valid values for the 'ceph osd pool set-quota' command
-POOL_QUOTA_PROPERTIES = [
-    ('quota_max_bytes', 'max_bytes'),
-    ('quota_max_objects', 'max_objects'),
-]
-
-POOL_ARGS = POOL_PROPERTIES + [x for x,_ in POOL_QUOTA_PROPERTIES]
-
-
-# Transform command to a human readable form
-def humanify_command(command):
-    out = [command['prefix']]
-
-    for arg, val in command.items():
-        if arg != 'prefix':
-            out.append("%s=%s" % (str(arg), str(val)))
-
-    return " ".join(out)
-
-
-def invalid_pool_args(args):
-    invalid = []
-    for arg in args:
-        if arg not in POOL_ARGS:
-            invalid.append(arg)
-
-    return invalid
-
-
-def pool_update_commands(pool_name, args):
-    commands = [[], []]
-
-    # We should increase pgp_num when we are re-setting pg_num
-    if 'pg_num' in args and 'pgp_num' not in args:
-        args['pgp_num'] = args['pg_num']
-
-    # Run the first pool set and quota properties in parallel
-    for var in POOL_PROPERTIES_1:
-        if var in args:
-            commands[0].append({
-                'prefix': 'osd pool set',
-                'pool': pool_name,
-                'var': var,
-                'val': args[var],
-            })
-
-    for (var, field) in POOL_QUOTA_PROPERTIES:
-        if var in args:
-            commands[0].append({
-                'prefix': 'osd pool set-quota',
-                'pool': pool_name,
-                'field': field,
-                'val': str(args[var]),
-            })
-
-    # The second pool set properties need to be run after the first wave
-    for var in POOL_PROPERTIES_2:
-        if var in args:
-            commands[1].append({
-                'prefix': 'osd pool set',
-                'pool': pool_name,
-                'var': var,
-                'val': args[var],
-            })
-
-    return commands
-
-def crush_rule_osds(node_buckets, rule):
-    nodes_by_id = dict((b['id'], b) for b in node_buckets)
-
-    def _gather_leaf_ids(node_id):
-        if node_id >= 0:
-            return set([node_id])
-
-        result = set()
-        for item in nodes_by_id[node_id]['items']:
-            result |= _gather_leaf_ids(item['id'])
-
-        return result
-
-    def _gather_descendent_ids(node, typ):
-        result = set()
-        for item in node['items']:
-            if item['id'] >= 0:
-                if typ == "osd":
-                    result.add(item['id'])
-            else:
-                child_node = nodes_by_id[item['id']]
-                if child_node['type_name'] == typ:
-                    result.add(child_node['id'])
-                elif 'items' in child_node:
-                    result |= _gather_descendent_ids(child_node, typ)
-
-        return result
-
-    def _gather_osds(root, steps):
-        if root['id'] >= 0:
-            return set([root['id']])
-
-        osds = set()
-        step = steps[0]
-        if step['op'] == 'choose_firstn':
-            # Choose all descendents of the current node of type 'type'
-            descendent_ids = _gather_descendent_ids(root, step['type'])
-            for node_id in descendent_ids:
-                if node_id >= 0:
-                    osds.add(node_id)
-                else:
-                    osds |= _gather_osds(nodes_by_id[node_id], steps[1:])
-        elif step['op'] == 'chooseleaf_firstn':
-            # Choose all descendents of the current node of type 'type',
-            # and select all leaves beneath those
-            descendent_ids = _gather_descendent_ids(root, step['type'])
-            for node_id in descendent_ids:
-                if node_id >= 0:
-                    osds.add(node_id)
-                else:
-                    for desc_node in nodes_by_id[node_id]['items']:
-                        # Short circuit another iteration to find the emit
-                        # and assume anything we've done a chooseleaf on
-                        # is going to be part of the selected set of osds
-                        osds |= _gather_leaf_ids(desc_node['id'])
-        elif step['op'] == 'emit':
-            if root['id'] >= 0:
-                osds |= root['id']
-
-        return osds
-
-    osds = set()
-    for i, step in enumerate(rule['steps']):
-        if step['op'] == 'take':
-            osds |= _gather_osds(nodes_by_id[step['item']], rule['steps'][i + 1:])
-    return osds
diff --git a/src/pybind/mgr/restful/context.py b/src/pybind/mgr/restful/context.py
deleted file mode 100644 (file)
index a05ea85..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Global instance to share
-instance = None
diff --git a/src/pybind/mgr/restful/decorators.py b/src/pybind/mgr/restful/decorators.py
deleted file mode 100644 (file)
index 11840a9..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-
-from pecan import request, response
-from base64 import b64decode
-from functools import wraps
-
-import traceback
-
-from . import context
-
-
-# Handle authorization
-def auth(f):
-    @wraps(f)
-    def decorated(*args, **kwargs):
-        if not context.instance.enable_auth:
-            return f(*args, **kwargs)
-            
-        if not request.authorization:
-            response.status = 401
-            response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"'
-            return {'message': 'auth: No HTTP username/password'}
-
-        username, password = b64decode(request.authorization[1]).decode('utf-8').split(':')
-
-        # Check that the username exists
-        if username not in context.instance.keys:
-            response.status = 401
-            response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"'
-            return {'message': 'auth: No such user'}
-
-        # Check the password
-        if context.instance.keys[username] != password:
-            response.status = 401
-            response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"'
-            return {'message': 'auth: Incorrect password'}
-
-        return f(*args, **kwargs)
-    return decorated
-
-
-# Helper function to lock the function
-def lock(f):
-    @wraps(f)
-    def decorated(*args, **kwargs):
-        with context.instance.requests_lock:
-            return f(*args, **kwargs)
-    return decorated
-
-
-# Support ?page=N argument
-def paginate(f):
-    @wraps(f)
-    def decorated(*args, **kwargs):
-        _out = f(*args, **kwargs)
-
-        # Do not modify anything without a specific request
-        if not 'page' in kwargs:
-            return _out
-
-        # A pass-through for errors, etc
-        if not isinstance(_out, list):
-            return _out
-
-        # Parse the page argument
-        _page = kwargs['page']
-        try:
-            _page = int(_page)
-        except ValueError:
-            response.status = 500
-            return {'message': 'The requested page is not an integer'}
-
-        # Raise _page so that 0 is the first page and -1 is the last
-        _page += 1
-
-        if _page > 0:
-            _page *= 100
-        else:
-            _page = len(_out) - (_page*100)
-
-        return _out[_page - 100: _page]
-    return decorated
diff --git a/src/pybind/mgr/restful/hooks.py b/src/pybind/mgr/restful/hooks.py
deleted file mode 100644 (file)
index c57cbcd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-from pecan.hooks import PecanHook
-
-import traceback
-
-from . import context
-
-class ErrorHook(PecanHook):
-    def on_error(self, stat, exc):
-        context.instance.log.error(str(traceback.format_exc()))
diff --git a/src/pybind/mgr/restful/module.py b/src/pybind/mgr/restful/module.py
deleted file mode 100644 (file)
index ad76473..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-"""
-A RESTful API for Ceph
-"""
-
-import os
-import json
-import time
-import errno
-import inspect
-import tempfile
-import threading
-import traceback
-import socket
-import fcntl
-from typing import cast
-
-from . import common
-from . import context
-
-from uuid import uuid4
-from pecan import jsonify, make_app
-from OpenSSL import crypto
-from pecan.rest import RestController
-from werkzeug.serving import make_server, make_ssl_devcert
-
-from .hooks import ErrorHook
-from mgr_module import MgrModule, CommandResult, NotifyType, Option
-from mgr_util import build_url
-
-
-class CannotServe(Exception):
-    pass
-
-
-class CommandsRequest(object):
-    """
-    This class handles parallel as well as sequential execution of
-    commands. The class accept a list of iterables that should be
-    executed sequentially. Each iterable can contain several commands
-    that can be executed in parallel.
-
-    Example:
-    [[c1,c2],[c3,c4]]
-     - run c1 and c2 in parallel
-     - wait for them to finish
-     - run c3 and c4 in parallel
-     - wait for them to finish
-    """
-
-
-    def __init__(self, commands_arrays):
-        self.id = str(id(self))
-
-        # Filter out empty sub-requests
-        commands_arrays = [x for x in commands_arrays
-                           if len(x) != 0]
-
-        self.running = []
-        self.waiting = commands_arrays[1:]
-        self.finished = []
-        self.failed = []
-
-        self.lock = threading.RLock()
-        if not len(commands_arrays):
-            # Nothing to run
-            return
-
-        # Process first iteration of commands_arrays in parallel
-        results = self.run(commands_arrays[0])
-
-        self.running.extend(results)
-
-
-    def run(self, commands):
-        """
-        A static method that will execute the given list of commands in
-        parallel and will return the list of command results.
-        """
-
-        # Gather the results (in parallel)
-        results = []
-        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(command)
-            results.append(result)
-
-            # Run the command
-            context.instance.send_command(result, 'mon', '', json.dumps(command), tag)
-
-        return results
-
-
-    def next(self):
-        with self.lock:
-            if not self.waiting:
-                # Nothing to run
-                return
-
-            # Run a next iteration of commands
-            commands = self.waiting[0]
-            self.waiting = self.waiting[1:]
-
-            self.running.extend(self.run(commands))
-
-
-    def finish(self, tag):
-        with self.lock:
-            for index in range(len(self.running)):
-                if self.running[index].tag == tag:
-                    if self.running[index].r == 0:
-                        self.finished.append(self.running.pop(index))
-                    else:
-                        self.failed.append(self.running.pop(index))
-                    return True
-
-            # No such tag found
-            return False
-
-
-    def is_running(self, tag):
-        for result in self.running:
-            if result.tag == tag:
-                return True
-        return False
-
-
-    def is_ready(self):
-        with self.lock:
-            return not self.running and self.waiting
-
-
-    def is_waiting(self):
-        return bool(self.waiting)
-
-
-    def is_finished(self):
-        with self.lock:
-            return not self.running and not self.waiting
-
-
-    def has_failed(self):
-        return bool(self.failed)
-
-
-    def get_state(self):
-        with self.lock:
-            if not self.is_finished():
-                return "pending"
-
-            if self.has_failed():
-                return "failed"
-
-            return "success"
-
-
-    def __json__(self):
-        return {
-            'id': self.id,
-            'running': [
-                {
-                    'command': x.command,
-                    'outs': x.outs,
-                    'outb': x.outb,
-                } for x in self.running
-            ],
-            'finished': [
-                {
-                    'command': x.command,
-                    'outs': x.outs,
-                    'outb': x.outb,
-                } 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,
-                } for x in self.failed
-            ],
-            'is_waiting': self.is_waiting(),
-            'is_finished': self.is_finished(),
-            'has_failed': self.has_failed(),
-            'state': self.get_state(),
-        }
-
-
-
-class Module(MgrModule):
-    MODULE_OPTIONS = [
-        Option(name='server_addr'),
-        Option(name='server_port'),
-        Option(name='key_file'),
-        Option(name='enable_auth',
-               type='bool',
-               default=True),
-        Option(name='max_requests',
-               type='int',
-               default=500,
-               desc='Maximum number of requests to keep in memory. '
-                    ' When new request comes in, the oldest request will be removed if the number of requests exceeds the max request number.'
-                    'if un-finished request is removed, error message will be logged in the ceph-mgr log.'),
-    ]
-
-    COMMANDS = [
-        {
-            "cmd": "restful create-key name=key_name,type=CephString",
-            "desc": "Create an API key with this name",
-            "perm": "rw"
-        },
-        {
-            "cmd": "restful delete-key name=key_name,type=CephString",
-            "desc": "Delete an API key with this name",
-            "perm": "rw"
-        },
-        {
-            "cmd": "restful list-keys",
-            "desc": "List all API keys",
-            "perm": "r"
-        },
-        {
-            "cmd": "restful create-self-signed-cert",
-            "desc": "Create localized self signed certificate",
-            "perm": "rw"
-        },
-        {
-            "cmd": "restful restart",
-            "desc": "Restart API server",
-            "perm": "rw"
-        },
-    ]
-
-    NOTIFY_TYPES = [NotifyType.command]
-
-    def __init__(self, *args, **kwargs):
-        super(Module, self).__init__(*args, **kwargs)
-        context.instance = self
-
-        self.requests = []
-        self.requests_lock = threading.RLock()
-
-        self.keys = {}
-        self.enable_auth = True
-
-        self.server = None
-
-        self.stop_server = False
-        self.serve_event = threading.Event()
-        self.max_requests = cast(int, self.get_localized_module_option('max_requests', 500))
-
-
-    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.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 rawkeys.items():
-            self.keys[k[5:]] = v  # strip of keys/ prefix
-
-    def _serve(self):
-        # Load stored authentication keys
-        self.refresh_keys()
-
-        jsonify._instance = jsonify.GenericJSON(
-            sort_keys=True,
-            indent=4,
-            separators=(',', ': '),
-        )
-
-        server_addr = self.get_localized_module_option('server_addr', '::')
-        if server_addr is None:
-            raise CannotServe('no server_addr configured; try "ceph config-key set mgr/restful/server_addr <ip>"')
-
-        server_port = int(self.get_localized_module_option('server_port', '8003'))
-        self.log.info('server_addr: %s server_port: %d',
-                      server_addr, server_port)
-
-        cert = self.get_localized_store("crt")
-        if cert is not None:
-            cert_tmp = tempfile.NamedTemporaryFile()
-            cert_tmp.write(cert.encode('utf-8'))
-            cert_tmp.flush()
-            cert_fname = cert_tmp.name
-        else:
-            cert_fname = self.get_localized_store('crt_file')
-
-        pkey = self.get_localized_store("key")
-        if pkey is not None:
-            pkey_tmp = tempfile.NamedTemporaryFile()
-            pkey_tmp.write(pkey.encode('utf-8'))
-            pkey_tmp.flush()
-            pkey_fname = pkey_tmp.name
-        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):
-            raise CannotServe('certificate %s does not exist' % cert_fname)
-        if not os.path.isfile(pkey_fname):
-            raise CannotServe('private key %s does not exist' % pkey_fname)
-
-        # Publish the URI that others may use to access the service we're
-        # about to start serving
-        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(
-            host=server_addr,
-            port=server_port,
-            app=make_app(
-                root='restful.api.Root',
-                hooks = [ErrorHook()],  # use a callable if pecan >= 0.3.2
-            ),
-            ssl_context=(cert_fname, pkey_fname),
-        )
-        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):
-        try:
-            if self.server:
-                self.server.shutdown()
-            self.serve_event.set()
-        except:
-            self.log.error(str(traceback.format_exc()))
-
-
-    def notify(self, notify_type: NotifyType, tag: str):
-        try:
-            self._notify(notify_type, tag)
-        except:
-            self.log.error(str(traceback.format_exc()))
-
-
-    def _notify(self, notify_type: NotifyType, tag):
-        if notify_type != NotifyType.command:
-            self.log.debug("Unhandled notification type '%s'", notify_type)
-            return
-        # we can safely skip all the sequential commands
-        if tag == 'seq':
-            return
-        try:
-            with self.requests_lock:
-                request = next(x for x in self.requests if x.is_running(tag))
-            request.finish(tag)
-            if request.is_ready():
-                request.next()
-        except StopIteration:
-            # 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
-        pkey = crypto.PKey()
-        pkey.generate_key(crypto.TYPE_RSA, 2048)
-
-        # create a self-signed cert
-        cert = crypto.X509()
-        cert.get_subject().O = "IT"
-        cert.get_subject().CN = "ceph-restful"
-        cert.set_serial_number(int(uuid4()))
-        cert.gmtime_adj_notBefore(0)
-        cert.gmtime_adj_notAfter(10*365*24*60*60)
-        cert.set_issuer(cert.get_subject())
-        cert.set_pubkey(pkey)
-        cert.sign(pkey, 'sha512')
-
-        return (
-            crypto.dump_certificate(crypto.FILETYPE_PEM, cert),
-            crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
-        )
-
-
-    def handle_command(self, inbuf, 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']], ""
-
-            else:
-                key = str(uuid4())
-                self.keys[command['key_name']] = key
-                self.set_store('keys/' + command['key_name'], key)
-
-            return (
-                0,
-                self.keys[command['key_name']],
-                "",
-            )
-
-        elif command['prefix'] == "restful delete-key":
-            if command['key_name'] in self.keys:
-                del self.keys[command['key_name']]
-                self.set_store('keys/' + command['key_name'], None)
-
-            return (
-                0,
-                "",
-                "",
-            )
-
-        elif command['prefix'] == "restful list-keys":
-            self.refresh_keys()
-            return (
-                0,
-                json.dumps(self.keys, indent=4, sort_keys=True),
-                "",
-            )
-
-        elif command['prefix'] == "restful create-self-signed-cert":
-            cert, pkey = self.create_self_signed_cert()
-            self.set_store(self.get_mgr_id() + '/crt', cert.decode('utf-8'))
-            self.set_store(self.get_mgr_id() + '/key', pkey.decode('utf-8'))
-
-            self.restart()
-            return (
-                0,
-                "Restarting RESTful API server...",
-                ""
-            )
-
-        elif command['prefix'] == 'restful restart':
-            self.restart();
-            return (
-                0,
-                "Restarting RESTful API server...",
-                ""
-            )
-
-        else:
-            return (
-                -errno.EINVAL,
-                "",
-                "Command not found '{0}'".format(command['prefix'])
-            )
-
-
-    def get_doc_api(self, root, prefix=''):
-        doc = {}
-        for _obj in dir(root):
-            obj = getattr(root, _obj)
-
-            if isinstance(obj, RestController):
-                doc.update(self.get_doc_api(obj, prefix + '/' + _obj))
-
-        if getattr(root, '_lookup', None) and isinstance(root._lookup('0')[0], RestController):
-            doc.update(self.get_doc_api(root._lookup('0')[0], prefix + '/<arg>'))
-
-        prefix = prefix or '/'
-
-        doc[prefix] = {}
-        for method in 'get', 'post', 'patch', 'delete':
-            if getattr(root, method, None):
-                doc[prefix][method.upper()] = inspect.getdoc(getattr(root, method)).split('\n')
-
-        if len(doc[prefix]) == 0:
-            del doc[prefix]
-
-        return doc
-
-
-    def get_mons(self):
-        mon_map_mons = self.get('mon_map')['mons']
-        mon_status = json.loads(self.get('mon_status')['json'])
-
-        # Add more information
-        for mon in mon_map_mons:
-            mon['in_quorum'] = mon['rank'] in mon_status['quorum']
-            mon['server'] = self.get_metadata("mon", mon['name'])['hostname']
-            mon['leader'] = mon['rank'] == mon_status['quorum'][0]
-
-        return mon_map_mons
-
-
-    def get_osd_pools(self):
-        osds = dict(map(lambda x: (x['osd'], []), self.get('osd_map')['osds']))
-        pools = dict(map(lambda x: (x['pool'], x), self.get('osd_map')['pools']))
-        crush = self.get('osd_map_crush')
-        crush_rules = crush['rules']
-
-        osds_by_pool = {}
-        for pool_id, pool in pools.items():
-            pool_osds = None
-            for rule in [r for r in crush_rules if r['rule_id'] == pool['crush_rule']]:
-                pool_osds = common.crush_rule_osds(crush['buckets'], rule)
-
-            osds_by_pool[pool_id] = pool_osds
-
-        for pool_id in pools.keys():
-            for in_pool_id in osds_by_pool[pool_id]:
-                osds[in_pool_id].append(pool_id)
-
-        return osds
-
-
-    def get_osds(self, pool_id=None, ids=None):
-        # Get data
-        osd_map = self.get('osd_map')
-        osd_metadata = self.get('osd_metadata')
-
-        # Update the data with the additional info from the osd map
-        osds = osd_map['osds']
-
-        # Filter by osd ids
-        if ids is not None:
-            osds = [x for x in osds if str(x['osd']) in ids]
-
-        # Get list of pools per osd node
-        pools_map = self.get_osd_pools()
-
-        # map osd IDs to reweight
-        reweight_map = dict([
-            (x.get('id'), x.get('reweight', None))
-            for x in self.get('osd_map_tree')['nodes']
-        ])
-
-        # Build OSD data objects
-        for osd in osds:
-            osd['pools'] = pools_map[osd['osd']]
-            osd['server'] = osd_metadata.get(str(osd['osd']), {}).get('hostname', None)
-
-            osd['reweight'] = reweight_map.get(osd['osd'], 0.0)
-
-            if osd['up']:
-                osd['valid_commands'] = common.OSD_IMPLEMENTED_COMMANDS
-            else:
-                osd['valid_commands'] = []
-
-        # Filter by pool
-        if pool_id:
-            pool_id = int(pool_id)
-            osds = [x for x in osds if pool_id in x['pools']]
-
-        return osds
-
-
-    def get_osd_by_id(self, osd_id):
-        osd = [x for x in self.get('osd_map')['osds']
-               if x['osd'] == osd_id]
-
-        if len(osd) != 1:
-            return None
-
-        return osd[0]
-
-
-    def get_pool_by_id(self, pool_id):
-        pool = [x for x in self.get('osd_map')['pools']
-                if x['pool'] == pool_id]
-
-        if len(pool) != 1:
-            return None
-
-        return pool[0]
-
-
-    def submit_request(self, _request, **kwargs):
-        with self.requests_lock:
-            request = CommandsRequest(_request)
-            self.requests.append(request)
-            if len(self.requests) > self.max_requests:
-                req_to_trim = 0
-                for i, req in enumerate(self.requests):
-                    if req.is_finished():
-                        self.log.error("Trimmed one finished request due to exceeded maximum requests limit")
-                        req_to_trim = i
-                        break
-                    else:
-                        self.log.error("Trimmed the oldest unfinished request due to exceeded maximum requests limit")
-                self.requests.pop(req_to_trim)
-        if kwargs.get('wait', 0):
-            while not request.is_finished():
-                time.sleep(0.001)
-        return request
-
-
-    def run_command(self, command):
-        # tag with 'seq' so that we can ignore these in notify function
-        result = CommandResult('seq')
-
-        self.send_command(result, 'mon', '', json.dumps(command), 'seq')
-        return result.wait()
index 4b62db677d106a3e4e79ea295c427812b5b4ed8e..45d3ba9b070c9b8cb63ec82ce5aa8a0b709016a4 100755 (executable)
@@ -192,7 +192,6 @@ if [[ "$(get_cmake_variable WITH_MGR_DASHBOARD_FRONTEND)" != "ON" ]] ||
     debug echo "ceph-mgr dashboard not built - disabling."
     with_mgr_dashboard=false
 fi
-with_mgr_restful=false
 
 kstore_path=
 declare -a block_devs
@@ -205,7 +204,6 @@ VSTART_SEC="client.vstart.sh"
 
 MON_ADDR=""
 DASH_URLS=""
-RESTFUL_URLS=""
 
 conf_fn="$CEPH_CONF_PATH/ceph.conf"
 keyring_fn="$CEPH_CONF_PATH/keyring"
@@ -558,9 +556,6 @@ case $1 in
     --without-dashboard)
         with_mgr_dashboard=false
         ;;
-    --with-restful)
-        with_mgr_restful=true
-        ;;
     --seastore-device-size)
         seastore_size="$2"
         shift
@@ -782,9 +777,6 @@ prepare_conf() {
     if $with_mgr_dashboard; then
         mgr_modules+=" dashboard"
     fi
-    if $with_mgr_restful; then
-        mgr_modules+=" restful"
-    fi
 
     local msgr_conf=''
     if [ $msgr -eq 21 ]; then
@@ -1010,7 +1002,7 @@ EOF
         ; see src/vstart.sh for more info
         public bind addr =
 EOF
-    fi   
+    fi
 }
 
 write_logrotate_conf() {
@@ -1254,22 +1246,6 @@ EOF
     fi
 }
 
-create_mgr_restful_secret() {
-    while ! ceph_adm -h | grep -c -q ^restful ; do
-        debug echo 'waiting for mgr restful module to start'
-        sleep 1
-    done
-    local secret_file
-    if ceph_adm restful create-self-signed-cert > /dev/null; then
-        secret_file=`mktemp`
-        ceph_adm restful create-key admin -o $secret_file
-        RESTFUL_SECRET=`cat $secret_file`
-        rm $secret_file
-    else
-        debug echo MGR Restful is not working, perhaps the package is not installed?
-    fi
-}
-
 start_mgr() {
     local mgr=0
     local ssl=${DASHBOARD_SSL:-1}
@@ -1309,15 +1285,7 @@ EOF
            MGR_PORT=$(($MGR_PORT + 1000))
            ceph_adm config set mgr mgr/prometheus/$name/server_port $PROMETHEUS_PORT --force
            PROMETHEUS_PORT=$(($PROMETHEUS_PORT + 1000))
-
-           ceph_adm config set mgr mgr/restful/$name/server_port $MGR_PORT --force
-            if [ $mgr -eq 1 ]; then
-                RESTFUL_URLS="https://$IP:$MGR_PORT"
-            else
-                RESTFUL_URLS+=", https://$IP:$MGR_PORT"
-            fi
-           MGR_PORT=$(($MGR_PORT + 1000))
-        fi
+       fi
 
         debug echo "Starting mgr.${name}"
         run 'mgr' $name $CEPH_BIN/ceph-mgr -i $name $ARGS
@@ -1327,7 +1295,7 @@ EOF
         debug echo 'waiting for mgr to become available'
         sleep 1
     done
-    
+
     if [ "$new" -eq 1 ]; then
         # setting login credentials for dashboard
         if $with_mgr_dashboard; then
@@ -1353,9 +1321,6 @@ EOF
                 ceph_adm dashboard nvmeof-gateway-add -i <(echo "${NVMEOF_GW}") "${NVMEOF_GW/:/_}"
             fi
         fi
-        if $with_mgr_restful; then
-            create_mgr_restful_secret
-        fi
     fi
 
     if [ "$cephadm" -eq 1 ]; then
@@ -2044,12 +2009,6 @@ if [ "$new" -eq 1 ]; then
         cat <<EOF
 dashboard urls: $DASH_URLS
   w/ user/pass: admin / admin
-EOF
-    fi
-    if $with_mgr_restful; then
-        cat <<EOF
-restful urls: $RESTFUL_URLS
-  w/ user/pass: admin / $RESTFUL_SECRET
 EOF
     fi
 fi