Hello Yedidyah Bar David,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/21451
to review the following change.
Change subject: packaging: setup: config broker notifications
......................................................................
packaging: setup: config broker notifications
Bug-Url: https://bugzilla.redhat.com/1030437
Bug-Url: https://bugzilla.redhat.com/1032467
Change-Id: Ib49f0534b5f8a9918558a82d40cc9828ccf87868
Signed-off-by: Yedidyah Bar David <[email protected]>
Signed-off-by: Sandro Bonazzola <[email protected]>
---
M src/ovirt_hosted_engine_setup/constants.py
M src/plugins/ovirt-hosted-engine-setup/ha/Makefile.am
M src/plugins/ovirt-hosted-engine-setup/ha/__init__.py
A src/plugins/ovirt-hosted-engine-setup/ha/ha_notifications.py
4 files changed, 285 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-hosted-engine-setup
refs/changes/51/21451/1
diff --git a/src/ovirt_hosted_engine_setup/constants.py
b/src/ovirt_hosted_engine_setup/constants.py
index 391356e..b8f9549 100644
--- a/src/ovirt_hosted_engine_setup/constants.py
+++ b/src/ovirt_hosted_engine_setup/constants.py
@@ -169,6 +169,14 @@
)
VDSMD_SYSTEMD_SERVICE = '/lib/systemd/systemd-vdsmd'
VDSMD_SYSV_SERVICE = '/etc/init.d/vdsmd'
+ ENGINE_HA_CONFDIR = os.path.join(
+ SYSCONFDIR,
+ 'ovirt-hosted-engine-ha'
+ )
+ NOTIFY_CONF_FILE = os.path.join(
+ ENGINE_HA_CONFDIR,
+ 'broker.conf'
+ )
@util.export
@@ -181,6 +189,10 @@
HOSTED_ENGINE_VM_NAME = 'HostedEngine'
METADATA_CHUNK_SIZE = 4096
MAX_HOST_ID = 250
+ HA_NOTIF_SMTP_SERVER = 'smtp-server'
+ HA_NOTIF_SMTP_PORT = 'smtp-port'
+ HA_NOTIF_SMTP_SOURCE_EMAIL = 'source-email'
+ HA_NOTIF_SMTP_DEST_EMAILS = 'destination-emails'
@util.export
@@ -489,6 +501,40 @@
@util.export
@util.codegen
+@ohostedattrsclass
+class NotificationsEnv(object):
+ @ohostedattrs(
+ answerfile=True,
+ )
+ def SMTP_SERVER(self):
+ return 'OVEHOSTED_NOTIF/smtpServer'
+
+ @ohostedattrs(
+ answerfile=True,
+ )
+ def SMTP_PORT(self):
+ return 'OVEHOSTED_NOTIF/smtpPort'
+
+ @ohostedattrs(
+ answerfile=True,
+ )
+ def SOURCE_EMAIL(self):
+ return 'OVEHOSTED_NOTIF/sourceEmail'
+
+ @ohostedattrs(
+ answerfile=True,
+ )
+ def DEST_EMAIL(self):
+ return 'OVEHOSTED_NOTIF/destEmail'
+
+ DEFAULT_SMTP_SERVER = 'localhost'
+ DEFAULT_SMTP_PORT = 25
+ DEFAULT_SOURCE_EMAIL = 'root@localhost'
+ DEFAULT_DEST_EMAIL = 'root@localhost'
+
+
[email protected]
[email protected]
class Stages(object):
CONFIG_BOOT_DEVICE = 'ohosted.boot.configuration.available'
CONFIG_STORAGE = 'ohosted.storage.configuration.available'
diff --git a/src/plugins/ovirt-hosted-engine-setup/ha/Makefile.am
b/src/plugins/ovirt-hosted-engine-setup/ha/Makefile.am
index c176193..c2fc379 100644
--- a/src/plugins/ovirt-hosted-engine-setup/ha/Makefile.am
+++ b/src/plugins/ovirt-hosted-engine-setup/ha/Makefile.am
@@ -27,6 +27,7 @@
dist_my_PYTHON = \
__init__.py \
ha_services.py \
+ ha_notifications.py \
$(NULL)
clean-local: \
diff --git a/src/plugins/ovirt-hosted-engine-setup/ha/__init__.py
b/src/plugins/ovirt-hosted-engine-setup/ha/__init__.py
index 0072ff6..ab965cd 100644
--- a/src/plugins/ovirt-hosted-engine-setup/ha/__init__.py
+++ b/src/plugins/ovirt-hosted-engine-setup/ha/__init__.py
@@ -24,11 +24,13 @@
from otopi import util
+from . import ha_notifications
from . import ha_services
@util.export
def createPlugins(context):
+ ha_notifications.Plugin(context=context)
ha_services.Plugin(context=context)
diff --git a/src/plugins/ovirt-hosted-engine-setup/ha/ha_notifications.py
b/src/plugins/ovirt-hosted-engine-setup/ha/ha_notifications.py
new file mode 100644
index 0000000..64e41e7
--- /dev/null
+++ b/src/plugins/ovirt-hosted-engine-setup/ha/ha_notifications.py
@@ -0,0 +1,236 @@
+#
+# ovirt-hosted-engine-setup -- ovirt hosted engine setup
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+
+"""
+HA notifications configuration
+"""
+
+
+import ConfigParser
+import gettext
+import re
+import StringIO
+import os
+
+
+from otopi import constants as otopicons
+from otopi import util
+from otopi import plugin
+from otopi import filetransaction
+
+
+from ovirt_hosted_engine_setup import constants as ohostedcons
+
+
+_ = lambda m: gettext.dgettext(message=m, domain='ovirt-hosted-engine-setup')
+
+
[email protected]
+class Plugin(plugin.PluginBase):
+ """
+ HA notifications plugin.
+ """
+
+ _RE_HOSTNAME = re.compile(
+ flags=re.VERBOSE,
+ pattern=r"""
+ ^
+ [a-z0-9.-]+
+ $
+ """
+ )
+
+ _RE_PORT = re.compile(
+ flags=re.VERBOSE,
+ pattern=r"""
+ ^
+ [0-9]+
+ $
+ """
+ )
+
+ _RE_EMAIL_ADDRESS = re.compile(
+ flags=re.VERBOSE,
+ pattern=r"""
+ [a-zA-Z0-9_.+]+
+ @
+ [a-z0-9.-]+
+ """
+ )
+
+ def __init__(self, context):
+ super(Plugin, self).__init__(context=context)
+
+ @plugin.event(
+ stage=plugin.Stages.STAGE_INIT,
+ )
+ def _init(self):
+ self._conffile = ohostedcons.FileLocations.NOTIFY_CONF_FILE
+ self._enabled = os.path.exists(self._conffile)
+ self.environment.setdefault(
+ ohostedcons.NotificationsEnv.SMTP_SERVER,
+ None
+ )
+ self.environment.setdefault(
+ ohostedcons.NotificationsEnv.SMTP_PORT,
+ None
+ )
+ self.environment.setdefault(
+ ohostedcons.NotificationsEnv.SOURCE_EMAIL,
+ None
+ )
+ self.environment.setdefault(
+ ohostedcons.NotificationsEnv.DEST_EMAIL,
+ None
+ )
+
+ @plugin.event(
+ stage=plugin.Stages.STAGE_CUSTOMIZATION,
+ condition=lambda self: self._enabled,
+ )
+ def _customization(self):
+ default_smtp_config = {
+ # TODO - remove the ugly parens below when pep8 stops failing
+ # https://github.com/jcrocholl/pep8/issues/144
+ ohostedcons.Const.HA_NOTIF_SMTP_SERVER: (
+ ohostedcons.NotificationsEnv.DEFAULT_SMTP_SERVER),
+ ohostedcons.Const.HA_NOTIF_SMTP_PORT: (
+ ohostedcons.NotificationsEnv.DEFAULT_SMTP_PORT),
+ ohostedcons.Const.HA_NOTIF_SMTP_SOURCE_EMAIL: (
+ ohostedcons.NotificationsEnv.DEFAULT_SOURCE_EMAIL),
+ ohostedcons.Const.HA_NOTIF_SMTP_DEST_EMAILS: (
+ ohostedcons.NotificationsEnv.DEFAULT_DEST_EMAIL),
+ }
+ self._cfg = ConfigParser.SafeConfigParser()
+ self._cfg.read(self._conffile)
+ if self._cfg.has_section('email'):
+ for name, value in dict(self._cfg.items('email')).items():
+ if name in default_smtp_config:
+ default_smtp_config[name] = value
+ else:
+ self._cfg.add_section('email')
+
+ interactions = (
+ {
+ 'name': ohostedcons.Const.HA_NOTIF_SMTP_SERVER,
+ 'envkey': ohostedcons.NotificationsEnv.SMTP_SERVER,
+ 'note': _(
+ 'Please provide the name of the SMTP server through which '
+ 'we will send notifications [@DEFAULT@]: '
+ ),
+ 'validation': lambda value: self._RE_HOSTNAME.match(value),
+ },
+ {
+ 'name': ohostedcons.Const.HA_NOTIF_SMTP_PORT,
+ 'envkey': ohostedcons.NotificationsEnv.SMTP_PORT,
+ 'note': _(
+ 'Please provide the TCP port number of the SMTP server '
+ '[@DEFAULT@]: '
+ ),
+ 'validation': lambda value: self._RE_PORT.match(value),
+ },
+ {
+ 'name': ohostedcons.Const.HA_NOTIF_SMTP_SOURCE_EMAIL,
+ 'envkey': ohostedcons.NotificationsEnv.SOURCE_EMAIL,
+ 'note': _(
+ 'Please provide the email address from which '
+ 'notifications will be sent [@DEFAULT@]: '
+ ),
+ 'validation': lambda value: self._RE_EMAIL_ADDRESS.match(
+ value
+ ),
+ },
+ {
+ 'name': ohostedcons.Const.HA_NOTIF_SMTP_DEST_EMAILS,
+ 'envkey': ohostedcons.NotificationsEnv.DEST_EMAIL,
+ 'note': _(
+ 'Please provide a comma-separated list of email addresses '
+ 'which will get notifications [@DEFAULT@]: '
+ ),
+ 'validation': lambda value: (
+ None not in [
+ self._RE_EMAIL_ADDRESS.match(addr)
+ for addr in value.split(',')
+ ]
+ ),
+ },
+ )
+
+ for item in interactions:
+ interactive = self.environment[item['envkey']] is None
+ valid = False
+ while not valid:
+ if interactive:
+ self.environment[item['envkey']] = self.dialog.queryString(
+ name='DIALOG' + item['envkey'],
+ note=item['note'],
+ prompt=True,
+ caseSensitive=True,
+ default=default_smtp_config[item['name']]
+ )
+ if item['validation'](self.environment[item['envkey']]):
+ valid = True
+ else:
+ self.logger.debug(
+ 'input %s for %s failed validation' % (
+ self.environment[item['envkey']],
+ item['envkey'],
+ )
+ )
+ if interactive:
+ self.logger.error(
+ _('Invalid input, please try again')
+ )
+ else:
+ raise RuntimeError(
+ _(
+ 'Invalid input for environment value {key}'
+ ).format(
+ key=item['envkey'],
+ ),
+ )
+ self._cfg.set(
+ 'email',
+ item['name'],
+ self.environment[item['envkey']]
+ )
+
+ @plugin.event(
+ stage=plugin.Stages.STAGE_MISC,
+ condition=lambda self: self._enabled,
+ )
+ def _misc(self):
+ f = StringIO.StringIO()
+ try:
+ self._cfg.write(f)
+ self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append(
+ filetransaction.FileTransaction(
+ name=self._conffile,
+ content=f.getvalue(),
+ modifiedList=self.environment[
+ otopicons.CoreEnv.MODIFIED_FILES
+ ],
+ )
+ )
+ finally:
+ f.close()
+
+
+# vim: expandtab tabstop=4 shiftwidth=4
--
To view, visit http://gerrit.ovirt.org/21451
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib49f0534b5f8a9918558a82d40cc9828ccf87868
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-hosted-engine-setup
Gerrit-Branch: ovirt-hosted-engine-setup-1.0
Gerrit-Owner: Sandro Bonazzola <[email protected]>
Gerrit-Reviewer: Yedidyah Bar David <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches