Statistics
| Branch: | Tag: | Revision:

root / qa / qa_iptables.py @ 31d3b918

History | View | Annotate | Download (3 kB)

1 ec7b6d63 Petr Pudlak
#!/usr/bin/python -u
2 ec7b6d63 Petr Pudlak
#
3 ec7b6d63 Petr Pudlak
4 ec7b6d63 Petr Pudlak
# Copyright (C) 2013 Google Inc.
5 ec7b6d63 Petr Pudlak
#
6 ec7b6d63 Petr Pudlak
# This program is free software; you can redistribute it and/or modify
7 ec7b6d63 Petr Pudlak
# it under the terms of the GNU General Public License as published by
8 ec7b6d63 Petr Pudlak
# the Free Software Foundation; either version 2 of the License, or
9 ec7b6d63 Petr Pudlak
# (at your option) any later version.
10 ec7b6d63 Petr Pudlak
#
11 ec7b6d63 Petr Pudlak
# This program is distributed in the hope that it will be useful, but
12 ec7b6d63 Petr Pudlak
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 ec7b6d63 Petr Pudlak
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ec7b6d63 Petr Pudlak
# General Public License for more details.
15 ec7b6d63 Petr Pudlak
#
16 ec7b6d63 Petr Pudlak
# You should have received a copy of the GNU General Public License
17 ec7b6d63 Petr Pudlak
# along with this program; if not, write to the Free Software
18 ec7b6d63 Petr Pudlak
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 ec7b6d63 Petr Pudlak
# 02110-1301, USA.
20 ec7b6d63 Petr Pudlak
21 ec7b6d63 Petr Pudlak
22 ec7b6d63 Petr Pudlak
"""Manipulates nodes using `iptables` to simulate non-standard network
23 ec7b6d63 Petr Pudlak
conditions.
24 ec7b6d63 Petr Pudlak

25 ec7b6d63 Petr Pudlak
"""
26 ec7b6d63 Petr Pudlak
27 ec7b6d63 Petr Pudlak
import uuid
28 ec7b6d63 Petr Pudlak
29 ec7b6d63 Petr Pudlak
import qa_config
30 ec7b6d63 Petr Pudlak
import qa_utils
31 ec7b6d63 Petr Pudlak
32 ec7b6d63 Petr Pudlak
from qa_utils import AssertCommand
33 ec7b6d63 Petr Pudlak
34 ec7b6d63 Petr Pudlak
# String used as a comment for produced `iptables` results
35 ec7b6d63 Petr Pudlak
IPTABLES_COMMENT_MARKER = "ganeti_qa_script"
36 ec7b6d63 Petr Pudlak
37 ec7b6d63 Petr Pudlak
38 ec7b6d63 Petr Pudlak
class RulesContext(object):
39 ec7b6d63 Petr Pudlak
  def __init__(self, nodes):
40 ec7b6d63 Petr Pudlak
    self._nodes = set()
41 ec7b6d63 Petr Pudlak
42 ec7b6d63 Petr Pudlak
  def __enter__(self):
43 ec7b6d63 Petr Pudlak
    self._marker = IPTABLES_COMMENT_MARKER + "_" + str(uuid.uuid4())
44 ec7b6d63 Petr Pudlak
    return Rules(self)
45 ec7b6d63 Petr Pudlak
46 ec7b6d63 Petr Pudlak
  def __exit__(self, ext_type, exc_val, exc_tb):
47 ec7b6d63 Petr Pudlak
    CleanRules(self._nodes, self._marker)
48 ec7b6d63 Petr Pudlak
49 ec7b6d63 Petr Pudlak
  def _AddNode(self, node):
50 ec7b6d63 Petr Pudlak
    self._nodes.add(node)
51 ec7b6d63 Petr Pudlak
52 ec7b6d63 Petr Pudlak
53 ec7b6d63 Petr Pudlak
class Rules(object):
54 ec7b6d63 Petr Pudlak
  """Allows to introduce iptable rules and dispose them at the end of a block.
55 ec7b6d63 Petr Pudlak

56 ec7b6d63 Petr Pudlak
  Don't instantiate this class directly. Use `with RulesContext() as r` instead.
57 ec7b6d63 Petr Pudlak
  """
58 ec7b6d63 Petr Pudlak
59 ec7b6d63 Petr Pudlak
  def __init__(self, ctx=None):
60 ec7b6d63 Petr Pudlak
    self._ctx = ctx
61 ec7b6d63 Petr Pudlak
    if self._ctx is not None:
62 ec7b6d63 Petr Pudlak
      self._marker = self._ctx._marker
63 ec7b6d63 Petr Pudlak
    else:
64 ec7b6d63 Petr Pudlak
      self._marker = IPTABLES_COMMENT_MARKER
65 ec7b6d63 Petr Pudlak
66 ec7b6d63 Petr Pudlak
  def _AddNode(self, node):
67 ec7b6d63 Petr Pudlak
    if self._ctx is not None:
68 ec7b6d63 Petr Pudlak
      self._ctx._AddNode(node)
69 ec7b6d63 Petr Pudlak
70 ec7b6d63 Petr Pudlak
  def AppendRule(self, node, chain, rule, table="filter"):
71 ec7b6d63 Petr Pudlak
    """Appends an `iptables` rule to a given node
72 ec7b6d63 Petr Pudlak
    """
73 ec7b6d63 Petr Pudlak
    AssertCommand(["iptables", "-t", table, "-A", chain] +
74 ec7b6d63 Petr Pudlak
                  rule +
75 ec7b6d63 Petr Pudlak
                  ["-m", "comment",
76 ec7b6d63 Petr Pudlak
                   "--comment", self._marker],
77 ec7b6d63 Petr Pudlak
                  node=node)
78 ec7b6d63 Petr Pudlak
    self._AddNode(node)
79 ec7b6d63 Petr Pudlak
80 ec7b6d63 Petr Pudlak
  def RedirectPort(self, node, host, port, new_port):
81 ec7b6d63 Petr Pudlak
    """Adds a rule to a master node that makes a destination host+port visible
82 ec7b6d63 Petr Pudlak
    under a different port number.
83 ec7b6d63 Petr Pudlak

84 ec7b6d63 Petr Pudlak
    """
85 ec7b6d63 Petr Pudlak
    self.AppendRule(node, "OUTPUT",
86 ec7b6d63 Petr Pudlak
                    ["--protocol", "tcp",
87 ec7b6d63 Petr Pudlak
                     "--destination", host, "--dport", str(port),
88 ec7b6d63 Petr Pudlak
                     "--jump", "DNAT",
89 ec7b6d63 Petr Pudlak
                     "--to-destination", ":" + str(new_port)],
90 ec7b6d63 Petr Pudlak
                    table="nat")
91 ec7b6d63 Petr Pudlak
92 ec7b6d63 Petr Pudlak
93 ec7b6d63 Petr Pudlak
GLOBAL_RULES = Rules()
94 ec7b6d63 Petr Pudlak
95 ec7b6d63 Petr Pudlak
96 ec7b6d63 Petr Pudlak
def CleanRules(nodes, marker=IPTABLES_COMMENT_MARKER):
97 ec7b6d63 Petr Pudlak
  """Removes all QA `iptables` rules matching a given marker from a given node.
98 ec7b6d63 Petr Pudlak

99 ec7b6d63 Petr Pudlak
  If no marker is given, the global default is used, which clean all custom
100 ec7b6d63 Petr Pudlak
  markers.
101 ec7b6d63 Petr Pudlak
  """
102 ec7b6d63 Petr Pudlak
  if not hasattr(nodes, '__iter__'):
103 ec7b6d63 Petr Pudlak
    nodes = [nodes]
104 ec7b6d63 Petr Pudlak
  for node in nodes:
105 ec7b6d63 Petr Pudlak
    AssertCommand(("iptables-save | grep -v '%s' | iptables-restore" %
106 ec7b6d63 Petr Pudlak
                    (marker, )),
107 ec7b6d63 Petr Pudlak
                  node=node)