Merge "Add tripleo_findif_for_ip ansible module"

This commit is contained in:
Zuul 2021-05-19 21:31:02 +00:00 committed by Gerrit Code Review
commit dadbe18555
2 changed files with 163 additions and 0 deletions

View File

@ -0,0 +1,103 @@
#!/usr/bin/python
# Copyright 2021 Red Hat, Inc.
# 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.
import netaddr
import os
import yaml
from ansible.module_utils.basic import AnsibleModule
DOCUMENTATION = """
---
module: tripleo_findif_for_ip
author:
- OpenStack TripleO Contributors
version_added: '1.0'
short_description: Finds the interface that an IP address is assigned to.
notes: []
requirements:
description:
- Locates the interface that has the provided IP address assigned to it
options:
ip_address:
description:
- The IP address to look for
type: str
debug:
description:
- Print debug output.
type: bool
default: false
"""
EXAMPLES = """
- name: Find the interface for the provided IP address
tripleo_find_if_for_ip:
ip_address: 192.168.24.22
"""
RETURN = """
interface:
description:
- if not empty, the interface that has the given IP address
returned: always
type: str
"""
def find_interface(module, ip_address):
rc, out, err = module.run_command(['ip', '-br', 'addr'])
result = {
'changed': False,
'interface': ''
}
for ifline in out.splitlines():
columns = ifline.strip().split()
if len(columns) == 0:
continue
interface_name = columns[0]
ips = columns[2:]
for addr in ips:
ip = addr.split('/')[0]
if ip == ip_address:
result['interface'] = interface_name
return result
return result
def main():
module = AnsibleModule(
argument_spec=yaml.safe_load(DOCUMENTATION)['options'],
supports_check_mode=True,
)
results = dict(
changed=False
)
# parse args
ip_address = module.params['ip_address']
if netaddr.valid_ipv6(ip_address) or netaddr.valid_ipv4(ip_address):
results = find_interface(module, ip_address)
else:
module.fail_json(msg='%s is not a valid ip address' % ip_address)
module.exit_json(**results)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,60 @@
# Copyright 2021 Red Hat, Inc. 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 tripleo_ansible.ansible_plugins.modules import tripleo_findif_for_ip as fip
from tripleo_ansible.tests import base as tests_base
from unittest import mock
test_output = """
UNKNOWN 127.0.0.1/8 ::1/128
ens4 UP fe80::5054:ff:fe54:eb48/64
ovs-system DOWN
br-ex UNKNOWN 192.168.24.23/24 192.168.24.10/32 192.168.24.13/32 192.168.24.16/32 fe80::5054:ff:fe54:eb48/64
br-int DOWN
br-tun DOWN
vxlan_sys_4789 UNKNOWN fe80::90dc:e2ff:fedd:10a8/64
"""
class TestFindIfForIp(tests_base.TestCase):
def test_find_ipv6_interface(self):
module = mock.MagicMock()
module.run_command = mock.MagicMock()
module.run_command.return_value = (0, test_output, '')
self.assertEqual(fip.find_interface(module, 'fe80::5054:ff:fe54:eb48')['interface'],
'ens4')
def test_find_ipv4_interface(self):
module = mock.MagicMock()
module.run_command = mock.MagicMock()
module.run_command.return_value = (0, test_output, '')
self.assertEqual(fip.find_interface(module, '192.168.24.23')['interface'],
'br-ex')
def test_find_ipv4_interface_noresult(self):
module = mock.MagicMock()
module.run_command = mock.MagicMock()
module.run_command.return_value = (0, test_output, '')
self.assertEqual(fip.find_interface(module, '192.168.24.99')['interface'],
'')
@mock.patch('subprocess.check_output')
def test_find_ipv6_interface_noresult(self, mock_checkoutput):
module = mock.MagicMock()
module.run_command = mock.MagicMock()
module.run_command.return_value = (0, test_output, '')
self.assertEqual(fip.find_interface(module, 'fe80::5054:ff:fe54:eb47')['interface'],
'')