]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add IPset cleanup script
authorBrian Haley <brian.haley@hp.com>
Thu, 16 Apr 2015 20:20:01 +0000 (16:20 -0400)
committerBrian Haley <brian.haley@hp.com>
Mon, 22 Jun 2015 23:36:42 +0000 (23:36 +0000)
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 [new file with mode: 0644]
setup.cfg

diff --git a/neutron/cmd/ipset_cleanup.py b/neutron/cmd/ipset_cleanup.py
new file mode 100644 (file)
index 0000000..91e3e52
--- /dev/null
@@ -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)
index 605e3e3f3aa63c74304e3b6ec2ab9e9f228abb8c..f2fc00fd342a25fcef99e6265bde4449f0c10056 100755 (executable)
--- 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