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
