From c384b13ae6b83a8bad944972c60bdcbe6f4fa050 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Thu, 16 Apr 2015 16:20:01 -0400 Subject: [PATCH] Add IPset cleanup script This will aid in removing stale IPsets when we change the prefix used in creating IPset names. Change-Id: Ia9ff79c34bd4c9124ec8663a8f616ded4f389f62 Partial-Bug: #1444201 --- neutron/cmd/ipset_cleanup.py | 112 +++++++++++++++++++++++++++++++++++ setup.cfg | 1 + 2 files changed, 113 insertions(+) create mode 100644 neutron/cmd/ipset_cleanup.py diff --git a/neutron/cmd/ipset_cleanup.py b/neutron/cmd/ipset_cleanup.py new file mode 100644 index 00000000000..91e3e52d667 --- /dev/null +++ b/neutron/cmd/ipset_cleanup.py @@ -0,0 +1,112 @@ +# Copyright (c) 2015 OpenStack Foundation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_config import cfg +from oslo_log import log as logging + +from neutron.agent.linux import ipset_manager +from neutron.agent.linux import utils +from neutron.common import config +from neutron.i18n import _LE, _LI + + +LOG = logging.getLogger(__name__) + + +def setup_conf(): + """Setup the cfg for the clean up utility. + + Use separate setup_conf for the utility because there are many options + from the main config that do not apply during clean-up. + """ + + cli_opts = [ + cfg.BoolOpt('allsets', + default=False, + help=_('Destroy all IPsets.')), + cfg.BoolOpt('force', + default=False, + help=_('Destroy IPsets even if there is an iptables ' + 'reference.')), + cfg.StrOpt('prefix', + default=ipset_manager.NET_PREFIX, + help=_('String prefix used to match IPset names.')), + ] + + conf = cfg.CONF + conf.register_cli_opts(cli_opts) + return conf + + +def remove_iptables_reference(ipset): + # Remove any iptables reference to this IPset + cmd = ['iptables-save'] if 'IPv4' in ipset else ['ip6tables-save'] + iptables_save = utils.execute(cmd, run_as_root=True) + + if ipset in iptables_save: + cmd = ['iptables'] if 'IPv4' in ipset else ['ip6tables'] + LOG.info(_LI("Removing iptables rule for IPset: %s"), ipset) + for rule in iptables_save.splitlines(): + if '--match-set %s ' % ipset in rule and rule.startswith('-A'): + # change to delete + params = rule.split() + params[0] = '-D' + try: + utils.execute(cmd + params, run_as_root=True) + except Exception: + LOG.exception(_LE('Error, unable to remove iptables rule ' + 'for IPset: %s'), ipset) + + +def destroy_ipset(conf, ipset): + # If there is an iptables reference and we don't remove it, the + # IPset removal will fail below + if conf.force: + remove_iptables_reference(ipset) + + LOG.info(_LI("Destroying IPset: %s"), ipset) + cmd = ['ipset', 'destroy', ipset] + try: + utils.execute(cmd, run_as_root=True) + except Exception: + LOG.exception(_LE('Error, unable to destroy IPset: %s'), ipset) + + +def cleanup_ipsets(conf): + # Identify ipsets for destruction. + LOG.info(_LI("Destroying IPsets with prefix: %s"), conf.prefix) + + cmd = ['ipset', '-L', '-n'] + ipsets = utils.execute(cmd, run_as_root=True) + for ipset in ipsets.split('\n'): + if conf.allsets or ipset.startswith(conf.prefix): + destroy_ipset(conf, ipset) + + LOG.info(_LI("IPset cleanup completed successfully")) + + +def main(): + """Main method for cleaning up IPsets. + + The utility is designed to clean-up after the forced or unexpected + termination of Neutron agents. + + The --allsets flag should only be used as part of the cleanup of a devstack + installation as it will blindly destroy all IPsets. + """ + conf = setup_conf() + conf() + config.setup_logging() + cleanup_ipsets(conf) diff --git a/setup.cfg b/setup.cfg index 605e3e3f3aa..f2fc00fd342 100755 --- a/setup.cfg +++ b/setup.cfg @@ -92,6 +92,7 @@ console_scripts = neutron-hyperv-agent = neutron.cmd.eventlet.plugins.hyperv_neutron_agent:main neutron-keepalived-state-change = neutron.cmd.keepalived_state_change:main neutron-ibm-agent = neutron.plugins.ibm.agent.sdnve_neutron_agent:main + neutron-ipset-cleanup = neutron.cmd.ipset_cleanup:main neutron-l3-agent = neutron.cmd.eventlet.agents.l3:main neutron-linuxbridge-agent = neutron.plugins.linuxbridge.agent.linuxbridge_neutron_agent:main neutron-metadata-agent = neutron.cmd.eventlet.agents.metadata:main