summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/plugins/motd.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pybind/mgr/dashboard/plugins/motd.py')
-rw-r--r--src/pybind/mgr/dashboard/plugins/motd.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/plugins/motd.py b/src/pybind/mgr/dashboard/plugins/motd.py
new file mode 100644
index 000000000..22d6a294a
--- /dev/null
+++ b/src/pybind/mgr/dashboard/plugins/motd.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+
+import hashlib
+import json
+from enum import Enum
+from typing import Dict, NamedTuple, Optional
+
+from ceph.utils import datetime_now, datetime_to_str, parse_timedelta, str_to_datetime
+from mgr_module import CLICommand
+
+from . import PLUGIN_MANAGER as PM
+from .plugin import SimplePlugin as SP
+
+
+class MotdSeverity(Enum):
+ INFO = 'info'
+ WARNING = 'warning'
+ DANGER = 'danger'
+
+
+class MotdData(NamedTuple):
+ message: str
+ md5: str # The MD5 of the message.
+ severity: MotdSeverity
+ expires: str # The expiration date in ISO 8601. Does not expire if empty.
+
+
+@PM.add_plugin # pylint: disable=too-many-ancestors
+class Motd(SP):
+ NAME = 'motd'
+
+ OPTIONS = [
+ SP.Option(
+ name=NAME,
+ default='',
+ type='str',
+ desc='The message of the day'
+ )
+ ]
+
+ @PM.add_hook
+ def register_commands(self):
+ @CLICommand("dashboard {name} get".format(name=self.NAME))
+ def _get(_):
+ stdout: str
+ value: str = self.get_option(self.NAME)
+ if not value:
+ stdout = 'No message of the day has been set.'
+ else:
+ data = json.loads(value)
+ if not data['expires']:
+ data['expires'] = "Never"
+ stdout = 'Message="{message}", severity="{severity}", ' \
+ 'expires="{expires}"'.format(**data)
+ return 0, stdout, ''
+
+ @CLICommand("dashboard {name} set".format(name=self.NAME))
+ def _set(_, severity: MotdSeverity, expires: str, message: str):
+ if expires != '0':
+ delta = parse_timedelta(expires)
+ if not delta:
+ return 1, '', 'Invalid expires format, use "2h", "10d" or "30s"'
+ expires = datetime_to_str(datetime_now() + delta)
+ else:
+ expires = ''
+ value: str = json.dumps({
+ 'message': message,
+ 'md5': hashlib.md5(message.encode()).hexdigest(),
+ 'severity': severity.value,
+ 'expires': expires
+ })
+ self.set_option(self.NAME, value)
+ return 0, 'Message of the day has been set.', ''
+
+ @CLICommand("dashboard {name} clear".format(name=self.NAME))
+ def _clear(_):
+ self.set_option(self.NAME, '')
+ return 0, 'Message of the day has been cleared.', ''
+
+ @PM.add_hook
+ def get_controllers(self):
+ from ..controllers import RESTController, UIRouter
+
+ @UIRouter('/motd')
+ class MessageOfTheDay(RESTController):
+ def list(_) -> Optional[Dict]: # pylint: disable=no-self-argument
+ value: str = self.get_option(self.NAME)
+ if not value:
+ return None
+ data: MotdData = MotdData(**json.loads(value))
+ # Check if the MOTD has been expired.
+ if data.expires:
+ expires = str_to_datetime(data.expires)
+ if expires < datetime_now():
+ return None
+ return data._asdict()
+
+ return [MessageOfTheDay]