Sandro Bonazzola has uploaded a new change for review.

Change subject: packaging: setup: firewall configuration
......................................................................

packaging: setup: firewall configuration

Added firewall manager selection and configuration
for enabling access to port 5900 for remote-viewer
access to the hosted engine VM console.

Change-Id: I6c3ac2ae97416f4a9b82f9a7c404350345a0c765
Signed-off-by: Sandro Bonazzola <[email protected]>
---
M ovirt-hosted-engine-setup.spec.in
M src/ovirt_hosted_engine_setup/constants.py
M src/plugins/ovirt-hosted-engine-setup/network/Makefile.am
M src/plugins/ovirt-hosted-engine-setup/network/__init__.py
A src/plugins/ovirt-hosted-engine-setup/network/firewall.py
A src/plugins/ovirt-hosted-engine-setup/network/firewall_manager.py
M templates/Makefile.am
A templates/hosted-console.xml.in
A templates/iptables.default.in
9 files changed, 423 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-hosted-engine-setup 
refs/changes/77/16877/1

diff --git a/ovirt-hosted-engine-setup.spec.in 
b/ovirt-hosted-engine-setup.spec.in
index ef68b36..3719616 100644
--- a/ovirt-hosted-engine-setup.spec.in
+++ b/ovirt-hosted-engine-setup.spec.in
@@ -84,8 +84,8 @@
 %{python_sitelib}/ovirt_hosted_engine_setup/*.py*
 %dir %{_datadir}/%{name}
 %{_datadir}/%{name}/plugins/%{name}/*/*.py*
-%{ovirt_hosted_engine_setup_templates}/vm.conf.in
-%{ovirt_hosted_engine_setup_templates}/hosted-engine.conf.in
+%{ovirt_hosted_engine_setup_templates}/*.in
+%{ovirt_hosted_engine_setup_templates}/firewalld/base/*.xml.in
 %{ovirt_hosted_engine_setup_scripts}/%{name}
 %{ovirt_hosted_engine_setup_scripts}/%{name}.env
 
diff --git a/src/ovirt_hosted_engine_setup/constants.py 
b/src/ovirt_hosted_engine_setup/constants.py
index 65c8899..4018d21 100644
--- a/src/ovirt_hosted_engine_setup/constants.py
+++ b/src/ovirt_hosted_engine_setup/constants.py
@@ -88,6 +88,29 @@
         OVIRT_HOSTED_ENGINE,
         'hosted-engine.conf'
     )
+    HOSTED_ENGINE_IPTABLES_TEMPLATE = os.path.join(
+        DATADIR,
+        OVIRT_HOSTED_ENGINE_SETUP,
+        'templates',
+        'iptables.default.in'
+    )
+    HOSTED_ENGINE_IPTABLES_EXAMPLE = os.path.join(
+        SYSCONFDIR,
+        OVIRT_HOSTED_ENGINE,
+        'iptables.example'
+    )
+    HOSTED_ENGINE_FIREWALLD_EXAMPLE_DIR = os.path.join(
+        SYSCONFDIR,
+        OVIRT_HOSTED_ENGINE,
+        'firewalld'
+    )
+    HOSTED_ENGINE_FIREWALLD_TEMPLATES_DIR = os.path.join(
+        DATADIR,
+        OVIRT_HOSTED_ENGINE_SETUP,
+        'templates',
+        'firewalld',
+    )
+
     VDSM_GEN_CERTS = os.path.join(
         LIBEXECDIR,
         'vdsm',
@@ -160,6 +183,15 @@
     )
     def BRIDGE_NAME(self):
         return 'OVEHOSTED_NETWORK/bridgeName'
+
+    @ohostedattrs(
+        answerfile=True,
+    )
+    def FIREWALL_MANAGER(self):
+        return 'OVEHOSTED_NETWORK/firewallManager'
+
+    FIREWALLD_SERVICES = 'OVEHOSTED_NETWORK/firewalldServices'
+    FIREWALLD_SUBST = 'OVEHOSTED_NETWORK/firewalldSubst'
 
 
 @util.export
@@ -334,6 +366,10 @@
     OS_INSTALLED = 'ohosted.vm.state.os.installed'
     INSTALLED_VM_RUNNING = 'ohosted.vm.state.os.installed.running'
     ENGINE_ALIVE = 'ohosted.engine.alive'
+    NET_FIREWALL_MANAGER_AVAILABLE = \
+        'ohosted.network.firewallmanager.available'
+    NET_FIREWALL_MANAGER_PROCESS_TEMPLATES = \
+        'ohosted.network.firewallmanager.templates.available'
 
 
 @util.export
diff --git a/src/plugins/ovirt-hosted-engine-setup/network/Makefile.am 
b/src/plugins/ovirt-hosted-engine-setup/network/Makefile.am
index 9c67f74..bab0737 100644
--- a/src/plugins/ovirt-hosted-engine-setup/network/Makefile.am
+++ b/src/plugins/ovirt-hosted-engine-setup/network/Makefile.am
@@ -27,6 +27,8 @@
 dist_my_PYTHON = \
        __init__.py \
        bridge.py \
+       firewall_manager.py \
+       firewall.py \
        $(NULL)
 
 clean-local: \
diff --git a/src/plugins/ovirt-hosted-engine-setup/network/__init__.py 
b/src/plugins/ovirt-hosted-engine-setup/network/__init__.py
index 00a1b55..d622da3 100644
--- a/src/plugins/ovirt-hosted-engine-setup/network/__init__.py
+++ b/src/plugins/ovirt-hosted-engine-setup/network/__init__.py
@@ -25,11 +25,15 @@
 
 
 from . import bridge
+from . import firewall
+from . import firewall_manager
 
 
 @util.export
 def createPlugins(context):
     bridge.Plugin(context=context)
+    firewall.Plugin(context=context)
+    firewall_manager.Plugin(context=context)
 
 
 # vim: expandtab tabstop=4 shiftwidth=4
diff --git a/src/plugins/ovirt-hosted-engine-setup/network/firewall.py 
b/src/plugins/ovirt-hosted-engine-setup/network/firewall.py
new file mode 100644
index 0000000..24d7305
--- /dev/null
+++ b/src/plugins/ovirt-hosted-engine-setup/network/firewall.py
@@ -0,0 +1,65 @@
+#
+# 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
+#
+
+
+"""
+Firewall configuration plugin for Hosted Engine.
+"""
+
+import gettext
+
+
+from otopi import util
+from otopi import plugin
+
+
+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):
+    """
+    Firewall configuration plugin for Hosted Engine
+    """
+
+    def __init__(self, context):
+        super(Plugin, self).__init__(context=context)
+
+    @plugin.event(
+        stage=plugin.Stages.STAGE_CUSTOMIZATION,
+        before=[
+            ohostedcons.Stages.NET_FIREWALL_MANAGER_PROCESS_TEMPLATES,
+        ],
+        after=[
+            ohostedcons.Stages.NET_FIREWALL_MANAGER_AVAILABLE,
+        ],
+    )
+    def _configuration(self):
+        self.environment[ohostedcons.NetworkEnv.FIREWALLD_SERVICES].extend([
+            {
+                'name': 'hosted-console',
+                'directory': 'base'
+            },
+        ])
+
+
+# vim: expandtab tabstop=4 shiftwidth=4
diff --git a/src/plugins/ovirt-hosted-engine-setup/network/firewall_manager.py 
b/src/plugins/ovirt-hosted-engine-setup/network/firewall_manager.py
new file mode 100644
index 0000000..eaef6bf
--- /dev/null
+++ b/src/plugins/ovirt-hosted-engine-setup/network/firewall_manager.py
@@ -0,0 +1,286 @@
+#
+# 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
+#
+
+
+"""
+Firewall manager selection plugin.
+"""
+
+
+import os
+import gettext
+
+
+import libxml2
+
+
+from otopi import util
+from otopi import plugin
+from otopi import constants as otopicons
+from otopi import filetransaction
+
+
+from ovirt_hosted_engine_setup import constants as ohostedcons
+from ovirt_hosted_engine_setup import util as ohostedutil
+
+
+_ = lambda m: gettext.dgettext(message=m, domain='ovirt-hosted-engine-setup')
+
+
[email protected]
+class Plugin(plugin.PluginBase):
+    """
+    Firewall manager selection plugin.
+    """
+
+    def _parseFirewalld(self, format):
+        ret = ''
+        for content in [
+            content
+            for key, content in self.environment.items()
+            if key.startswith(
+                otopicons.NetEnv.FIREWALLD_SERVICE_PREFIX
+            )
+        ]:
+            doc = None
+            ctx = None
+            try:
+                doc = libxml2.parseDoc(content)
+                ctx = doc.xpathNewContext()
+                nodes = ctx.xpathEval("/service/port")
+                for node in nodes:
+                    ret += format.format(
+                        protocol=node.prop('protocol'),
+                        port=node.prop('port'),
+                    )
+            finally:
+                if doc is not None:
+                    doc.freeDoc()
+                if ctx is not None:
+                    ctx.xpathFreeContext()
+
+        return ret
+
+    def _createIptablesConfig(self):
+        return ohostedutil.processTemplate(
+            ohostedcons.FileLocations.HOSTED_ENGINE_IPTABLES_TEMPLATE,
+            subst={
+                '@CUSTOM_RULES@': self._parseFirewalld(
+                    format=(
+                        '-A INPUT -p {protocol} -m state --state NEW '
+                        '-m {protocol} --dport {port} -j ACCEPT\n'
+                    )
+                )
+            }
+        )
+
+    def _createHumanConfig(self):
+        return '\n'.join(
+            sorted(
+                self._parseFirewalld(
+                    format='{protocol}:{port}\n',
+                ).splitlines()
+            )
+        ) + '\n'
+
+    def __init__(self, context):
+        super(Plugin, self).__init__(context=context)
+
+    @plugin.event(
+        stage=plugin.Stages.STAGE_INIT,
+    )
+    def _init(self):
+        self.environment.setdefault(
+            ohostedcons.NetworkEnv.FIREWALL_MANAGER,
+            None
+        )
+        self.environment.setdefault(
+            ohostedcons.NetworkEnv.FIREWALLD_SERVICES,
+            []
+        )
+        self.environment.setdefault(
+            ohostedcons.NetworkEnv.FIREWALLD_SUBST,
+            {}
+        )
+
+    @plugin.event(
+        stage=plugin.Stages.STAGE_CUSTOMIZATION,
+        name=ohostedcons.Stages.NET_FIREWALL_MANAGER_AVAILABLE,
+    )
+    def _customization(self):
+        if self.environment[ohostedcons.NetworkEnv.FIREWALL_MANAGER] is None:
+            managers = []
+            if self.environment[otopicons.NetEnv.FIREWALLD_AVAILABLE]:
+                managers.append('firewalld')
+            if self.services.exists('iptables'):
+                managers.append('iptables')
+
+            for manager in managers:
+                response = self.dialog.queryString(
+                    name='OHOSTED_NETWORK_FIREWALL_MANAGER',
+                    note=_(
+                        '{manager} was detected on your computer, '
+                        'do you wish setup to configure it? '
+                        '(@VALUES@) [@DEFAULT@]: '
+                    ).format(
+                        manager=manager,
+                    ),
+                    prompt=True,
+                    validValues=(_('yes'), _('no')),
+                    caseSensitive=False,
+                    default=_('yes'),
+                )
+                if response == _('yes'):
+                    self.environment[
+                        ohostedcons.NetworkEnv.FIREWALL_MANAGER
+                    ] = manager
+                    break
+
+        self.environment[otopicons.NetEnv.IPTABLES_ENABLE] = (
+            self.environment[
+                ohostedcons.NetworkEnv.FIREWALL_MANAGER
+            ] == 'iptables'
+        )
+        self.environment[otopicons.NetEnv.FIREWALLD_ENABLE] = (
+            self.environment[
+                ohostedcons.NetworkEnv.FIREWALL_MANAGER
+            ] == 'firewalld'
+        )
+
+    @plugin.event(
+        # must be at customization as otopi modules
+        # need a chance to validate content
+        stage=plugin.Stages.STAGE_CUSTOMIZATION,
+        name=ohostedcons.Stages.NET_FIREWALL_MANAGER_PROCESS_TEMPLATES,
+        priority=plugin.Stages.PRIORITY_LOW,
+        after=[
+            ohostedcons.Stages.NET_FIREWALL_MANAGER_AVAILABLE,
+        ],
+        # must be always enabled to create examples
+    )
+    def _process_templates(self):
+        for service in self.environment[
+            ohostedcons.NetworkEnv.FIREWALLD_SERVICES
+        ]:
+            content = ohostedutil.processTemplate(
+                template=os.path.join(
+                    ohostedcons.FileLocations.
+                    HOSTED_ENGINE_FIREWALLD_TEMPLATES_DIR,
+                    service['directory'],
+                    '%s.xml.in' % service['name'],
+                ),
+                subst=self.environment[ohostedcons.NetworkEnv.FIREWALLD_SUBST],
+            )
+
+            self.environment[
+                otopicons.NetEnv.FIREWALLD_SERVICE_PREFIX +
+                service['name']
+            ] = content
+
+            target = os.path.join(
+                ohostedcons.FileLocations.HOSTED_ENGINE_FIREWALLD_EXAMPLE_DIR,
+                '%s.xml' % service['name']
+            )
+
+            self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append(
+                filetransaction.FileTransaction(
+                    name=target,
+                    content=content,
+                    modifiedList=self.environment[
+                        otopicons.CoreEnv.MODIFIED_FILES
+                    ],
+                )
+            )
+
+        self.environment[
+            otopicons.NetEnv.IPTABLES_RULES
+        ] = self._createIptablesConfig()
+
+        self.environment[otopicons.CoreEnv.MAIN_TRANSACTION].append(
+            filetransaction.FileTransaction(
+                name=ohostedcons.FileLocations.HOSTED_ENGINE_IPTABLES_EXAMPLE,
+                content=self.environment[otopicons.NetEnv.IPTABLES_RULES],
+                modifiedList=self.environment[
+                    otopicons.CoreEnv.MODIFIED_FILES
+                ],
+            )
+        )
+
+    @plugin.event(
+        stage=plugin.Stages.STAGE_CLOSEUP,
+        condition=lambda self: self.environment[
+            ohostedcons.NetworkEnv.FIREWALL_MANAGER
+        ] is None
+    )
+    def _closeup(self):
+        self.dialog.note(
+            text=_(
+                'The following network ports should be opened:\n'
+                '{ports}'
+            ).format(
+                ports='\n'.join([
+                    '    ' + l
+                    for l in self._createHumanConfig().splitlines()
+                ]),
+            ),
+        )
+
+        self.dialog.note(
+            text=_(
+                'An example of the required configuration for iptables '
+                'can be found at:\n'
+                '    {example}'
+            ).format(
+                example=(
+                    ohostedcons.FileLocations.HOSTED_ENGINE_IPTABLES_EXAMPLE
+                )
+            )
+        )
+
+        commands = []
+        for service in [
+            key[len(otopicons.NetEnv.FIREWALLD_SERVICE_PREFIX):]
+            for key in self.environment
+            if key.startswith(
+                otopicons.NetEnv.FIREWALLD_SERVICE_PREFIX
+            )
+        ]:
+            commands.append('firewall-cmd -service %s' % service)
+        self.dialog.note(
+            text=_(
+                'In order to configure firewalld, copy the '
+                'files from\n'
+                '{examples} to {configdir}\n'
+                'and execute the following commands:\n'
+                '{commands}'
+            ).format(
+                examples=(
+                    ohostedcons.FileLocations.
+                    HOSTED_ENGINE_FIREWALLD_EXAMPLE_DIR
+                ),
+                configdir='/etc/firewalld/services',
+                commands='\n'.join([
+                    '    ' + l
+                    for l in commands
+                ]),
+            )
+        )
+
+
+# vim: expandtab tabstop=4 shiftwidth=4
diff --git a/templates/Makefile.am b/templates/Makefile.am
index a016285..6fd2483 100644
--- a/templates/Makefile.am
+++ b/templates/Makefile.am
@@ -24,5 +24,11 @@
 templatesdir=$(ovirthostedenginetemplatedir)
 dist_templates_DATA = \
        vm.conf.in \
-       hosted-engine.conf.in
+       hosted-engine.conf.in \
+       iptables.default.in \
+       $(NULL)
+
+basefirewalldtemplatesdir=$(ovirthostedenginetemplatedir)/firewalld/base
+dist_basefirewalldtemplates_DATA = \
+       hosted-console.xml.in \
        $(NULL)
diff --git a/templates/hosted-console.xml.in b/templates/hosted-console.xml.in
new file mode 100644
index 0000000..db00dd3
--- /dev/null
+++ b/templates/hosted-console.xml.in
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+    <short>hosted-console</short>
+    <description>oVirt Hosted Engine console service</description>
+    <port protocol="tcp" port="5900"/>
+    <port protocol="udp" port="5900"/>
+</service>
diff --git a/templates/iptables.default.in b/templates/iptables.default.in
new file mode 100644
index 0000000..5cb4682
--- /dev/null
+++ b/templates/iptables.default.in
@@ -0,0 +1,14 @@
+# Generated by ovirt-hosted-engine-setup installer
+#filtering rules
+*filter
+:INPUT ACCEPT [0:0]
+:FORWARD ACCEPT [0:0]
+:OUTPUT ACCEPT [0:0]
+-A INPUT -i lo -j ACCEPT
+-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
+-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
+@CUSTOM_RULES@
+#drop all rule
+-A INPUT -j REJECT --reject-with icmp-host-prohibited
+COMMIT


-- 
To view, visit http://gerrit.ovirt.org/16877
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6c3ac2ae97416f4a9b82f9a7c404350345a0c765
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-hosted-engine-setup
Gerrit-Branch: master
Gerrit-Owner: Sandro Bonazzola <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to