Move plug/unplug bash command to ansible module
added new ansile module - iptables, that responsible for adding/removing of iptables rules. Change-Id: I97fc69103149794502653d052784b2d3586bb79e
This commit is contained in:
48
os_faults/ansible/modules/iptables.py
Normal file
48
os_faults/ansible/modules/iptables.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# 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 ansible.module_utils.basic import * # noqa
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
service=dict(required=True, type='str'),
|
||||
action=dict(required=True, choices=['block', 'unblock']),
|
||||
port=dict(required=True, type='int'),
|
||||
protocol=dict(required=True, choices=['tcp', 'udp']),
|
||||
))
|
||||
|
||||
service = module.params['service']
|
||||
action = module.params['action']
|
||||
port = module.params['port']
|
||||
protocol = module.params['protocol']
|
||||
comment = '{}_temporary_DROP'.format(service)
|
||||
|
||||
if action == 'block':
|
||||
cmd = ('bash -c "iptables -I INPUT 1 -p {protocol} --dport {port} '
|
||||
'-j DROP -m comment --comment "{comment}""'.format(
|
||||
comment=comment, port=port, protocol=protocol))
|
||||
else:
|
||||
cmd = ('bash -c "rule=`iptables -L INPUT -n --line-numbers | '
|
||||
'grep "{comment}" | cut -d \' \' -f1`; for arg in $rule;'
|
||||
' do iptables -D INPUT -p {protocol} --dport {port} '
|
||||
'-j DROP -m comment --comment "{comment}"; done"'.format(
|
||||
comment=comment, port=port, protocol=protocol))
|
||||
rc, stdout, stderr = module.run_command(cmd, check_rc=True)
|
||||
module.exit_json(cmd=cmd, rc=rc, stderr=stderr, stdout=stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -170,15 +170,21 @@ class FuelService(service.Service):
|
||||
|
||||
def plug(self, nodes=None):
|
||||
nodes = nodes if nodes is not None else self.get_nodes()
|
||||
logging.info("Open port %d for '%s' service on nodes: %s", self.PORT,
|
||||
self.SERVICE_NAME, nodes.get_ips())
|
||||
self._run_task({'command': self.PLUG_CMD.format(self.PORT)}, nodes)
|
||||
logging.info("Open port %d for '%s' service on nodes: %s",
|
||||
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
|
||||
self._run_task({'iptables': {'protocol': self.PORT[0],
|
||||
'port': self.PORT[1],
|
||||
'action': 'unblock',
|
||||
'service': self.SERVICE_NAME}}, nodes)
|
||||
|
||||
def unplug(self, nodes=None):
|
||||
nodes = nodes if nodes is not None else self.get_nodes()
|
||||
logging.info("Close port %d for '%s' service on nodes: %s",
|
||||
self.PORT, self.SERVICE_NAME, nodes.get_ips())
|
||||
self._run_task({'command': self.UNPLUG_CMD.format(self.PORT)}, nodes)
|
||||
self.PORT[1], self.SERVICE_NAME, nodes.get_ips())
|
||||
self._run_task({'iptables': {'protocol': self.PORT[0],
|
||||
'port': self.PORT[1],
|
||||
'action': 'block',
|
||||
'service': self.SERVICE_NAME}}, nodes)
|
||||
|
||||
|
||||
class KeystoneService(FuelService):
|
||||
@@ -196,13 +202,7 @@ class MemcachedService(FuelService):
|
||||
class MySQLService(FuelService):
|
||||
SERVICE_NAME = 'mysql'
|
||||
GREP = '[m]ysqld'
|
||||
PORT = 3307
|
||||
PLUG_CMD = ('bash -c "rule=`iptables -L INPUT -n --line-numbers | '
|
||||
'grep \"MySQL_temporary_DROP\" | cut -d \' \' -f1`; '
|
||||
'for arg in $rule; do iptables -D INPUT -p tcp --dport {0} '
|
||||
'-j DROP -m comment --comment "MySQL_temporary_DROP"; done"')
|
||||
UNPLUG_CMD = ('bash -c "iptables -I INPUT 1 -p tcp --dport {0} -j DROP '
|
||||
'-m comment --comment \"MySQL_temporary_DROP\""')
|
||||
PORT = ('tcp', 3307)
|
||||
|
||||
|
||||
class RabbitMQService(FuelService):
|
||||
|
||||
68
os_faults/tests/unit/ansible/modules/test_iptables.py
Normal file
68
os_faults/tests/unit/ansible/modules/test_iptables.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from os_faults.ansible.modules import iptables
|
||||
from os_faults.tests.unit import test
|
||||
|
||||
|
||||
class IptablesTestCase(test.TestCase):
|
||||
|
||||
@mock.patch("os_faults.ansible.modules.iptables.AnsibleModule")
|
||||
def test_main_unblock(self, mock_ansible_module):
|
||||
ansible_module_inst = mock_ansible_module.return_value
|
||||
ansible_module_inst.run_command.return_value = [
|
||||
'myrc', 'mystdout', 'mystderr']
|
||||
ansible_module_inst.params = {
|
||||
'service': 'foo',
|
||||
'action': 'unblock',
|
||||
'port': 5555,
|
||||
'protocol': 'tcp',
|
||||
}
|
||||
iptables.main()
|
||||
|
||||
cmd = (
|
||||
'bash -c "rule=`iptables -L INPUT -n --line-numbers | '
|
||||
'grep "foo_temporary_DROP" | cut -d \' \' -f1`; for arg in $rule;'
|
||||
' do iptables -D INPUT -p tcp --dport 5555 '
|
||||
'-j DROP -m comment --comment "foo_temporary_DROP"; done"')
|
||||
ansible_module_inst.exit_json.assert_called_once_with(
|
||||
cmd=cmd,
|
||||
rc='myrc',
|
||||
stdout='mystdout',
|
||||
stderr='mystderr',
|
||||
)
|
||||
|
||||
@mock.patch("os_faults.ansible.modules.iptables.AnsibleModule")
|
||||
def test_main_block(self, mock_ansible_module):
|
||||
ansible_module_inst = mock_ansible_module.return_value
|
||||
ansible_module_inst.run_command.return_value = [
|
||||
'myrc', 'mystdout', 'mystderr']
|
||||
ansible_module_inst.params = {
|
||||
'service': 'foo',
|
||||
'action': 'block',
|
||||
'port': 5555,
|
||||
'protocol': 'tcp',
|
||||
}
|
||||
iptables.main()
|
||||
|
||||
cmd = (
|
||||
'bash -c "iptables -I INPUT 1 -p tcp --dport 5555 '
|
||||
'-j DROP -m comment --comment "foo_temporary_DROP""')
|
||||
ansible_module_inst.exit_json.assert_called_once_with(
|
||||
cmd=cmd,
|
||||
rc='myrc',
|
||||
stdout='mystdout',
|
||||
stderr='mystderr',
|
||||
)
|
||||
@@ -202,8 +202,10 @@ class FuelServiceTestCase(test.TestCase):
|
||||
mock.call(['10.0.0.2', '10.0.0.3'],
|
||||
{'command': get_nodes_cmd}, []),
|
||||
mock.call(['10.0.0.2', '10.0.0.3'],
|
||||
{'command':
|
||||
service_cls.UNPLUG_CMD.format(service_cls.PORT)}),
|
||||
{'iptables': {'protocol': service_cls.PORT[0],
|
||||
'port': service_cls.PORT[1],
|
||||
'action': 'block',
|
||||
'service': service_cls.SERVICE_NAME}}),
|
||||
])
|
||||
|
||||
@mock.patch('os_faults.ansible.executor.AnsibleRunner', autospec=True)
|
||||
@@ -237,8 +239,10 @@ class FuelServiceTestCase(test.TestCase):
|
||||
mock.call(['10.0.0.2', '10.0.0.3'],
|
||||
{'command': get_nodes_cmd}, []),
|
||||
mock.call(['10.0.0.2', '10.0.0.3'],
|
||||
{'command':
|
||||
service_cls.PLUG_CMD.format(service_cls.PORT)}),
|
||||
{'iptables': {'protocol': service_cls.PORT[0],
|
||||
'port': service_cls.PORT[1],
|
||||
'action': 'unblock',
|
||||
'service': service_cls.SERVICE_NAME}}),
|
||||
])
|
||||
|
||||
@mock.patch('os_faults.ansible.executor.AnsibleRunner', autospec=True)
|
||||
|
||||
Reference in New Issue
Block a user