summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/controllers/service.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/pybind/mgr/dashboard/controllers/service.py
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/pybind/mgr/dashboard/controllers/service.py')
-rw-r--r--src/pybind/mgr/dashboard/controllers/service.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/controllers/service.py b/src/pybind/mgr/dashboard/controllers/service.py
new file mode 100644
index 000000000..b75f41736
--- /dev/null
+++ b/src/pybind/mgr/dashboard/controllers/service.py
@@ -0,0 +1,95 @@
+from typing import Dict, List, Optional
+
+import cherrypy
+from ceph.deployment.service_spec import ServiceSpec
+
+from ..security import Scope
+from ..services.exception import handle_custom_error, handle_orchestrator_error
+from ..services.orchestrator import OrchClient, OrchFeature
+from . import APIDoc, APIRouter, CreatePermission, DeletePermission, Endpoint, \
+ ReadPermission, RESTController, Task, UpdatePermission
+from ._version import APIVersion
+from .orchestrator import raise_if_no_orchestrator
+
+
+def service_task(name, metadata, wait_for=2.0):
+ return Task("service/{}".format(name), metadata, wait_for)
+
+
+@APIRouter('/service', Scope.HOSTS)
+@APIDoc("Service Management API", "Service")
+class Service(RESTController):
+
+ @Endpoint()
+ @ReadPermission
+ def known_types(self) -> List[str]:
+ """
+ Get a list of known service types, e.g. 'alertmanager',
+ 'node-exporter', 'osd' or 'rgw'.
+ """
+ return ServiceSpec.KNOWN_SERVICE_TYPES
+
+ @raise_if_no_orchestrator([OrchFeature.SERVICE_LIST])
+ @RESTController.MethodMap(version=APIVersion(2, 0)) # type: ignore
+ def list(self, service_name: Optional[str] = None, offset: int = 0, limit: int = 5,
+ search: str = '', sort: str = '+service_name') -> List[dict]:
+ orch = OrchClient.instance()
+ services, count = orch.services.list(service_name=service_name, offset=int(offset),
+ limit=int(limit), search=search, sort=sort)
+ cherrypy.response.headers['X-Total-Count'] = count
+ return services
+
+ @raise_if_no_orchestrator([OrchFeature.SERVICE_LIST])
+ def get(self, service_name: str) -> List[dict]:
+ orch = OrchClient.instance()
+ services = orch.services.get(service_name)
+ if not services:
+ raise cherrypy.HTTPError(404, 'Service {} not found'.format(service_name))
+ return services[0].to_json()
+
+ @RESTController.Resource('GET')
+ @raise_if_no_orchestrator([OrchFeature.DAEMON_LIST])
+ def daemons(self, service_name: str) -> List[dict]:
+ orch = OrchClient.instance()
+ daemons = orch.services.list_daemons(service_name=service_name)
+ return [d.to_dict() for d in daemons]
+
+ @CreatePermission
+ @handle_custom_error('service', exceptions=(ValueError, TypeError))
+ @raise_if_no_orchestrator([OrchFeature.SERVICE_CREATE])
+ @handle_orchestrator_error('service')
+ @service_task('create', {'service_name': '{service_name}'})
+ def create(self, service_spec: Dict, service_name: str): # pylint: disable=W0613
+ """
+ :param service_spec: The service specification as JSON.
+ :param service_name: The service name, e.g. 'alertmanager'.
+ :return: None
+ """
+
+ OrchClient.instance().services.apply(service_spec, no_overwrite=True)
+
+ @UpdatePermission
+ @handle_custom_error('service', exceptions=(ValueError, TypeError))
+ @raise_if_no_orchestrator([OrchFeature.SERVICE_CREATE])
+ @handle_orchestrator_error('service')
+ @service_task('edit', {'service_name': '{service_name}'})
+ def set(self, service_spec: Dict, service_name: str): # pylint: disable=W0613
+ """
+ :param service_spec: The service specification as JSON.
+ :param service_name: The service name, e.g. 'alertmanager'.
+ :return: None
+ """
+
+ OrchClient.instance().services.apply(service_spec, no_overwrite=False)
+
+ @DeletePermission
+ @raise_if_no_orchestrator([OrchFeature.SERVICE_DELETE])
+ @handle_orchestrator_error('service')
+ @service_task('delete', {'service_name': '{service_name}'})
+ def delete(self, service_name: str):
+ """
+ :param service_name: The service name, e.g. 'mds' or 'crash.foo'.
+ :return: None
+ """
+ orch = OrchClient.instance()
+ orch.services.remove(service_name)