Support service VIPs without neutron

Allow the 'use_neutron' boolean option on a service
FixedIPs definition. When 'use_neutron' is false the
tripleo_service_vip ansible module will not create a
neutron API resource. Instead it will "echo" the
'ip_address' in the FixedIPs request.

Partial-Implements: blueprint network-data-v2-ports
Change-Id: I79857ace329740f0d8e50ceb6cd27a21e67cf08a
This commit is contained in:
Harald Jensås 2021-03-11 01:11:06 +01:00
parent a313a11e53
commit bb5c6877ff
2 changed files with 85 additions and 15 deletions

View File

@ -79,6 +79,10 @@ options:
description:
- Neutron subnet name or id
type: str
use_neutron:
description:
- Boolean option to allow not to create a neutron port.
type: bool
author:
- Harald Jensås <hjensas@redhat.com>
@ -96,6 +100,15 @@ EXAMPLES = '''
fixed_ip:
- subnet: internal_api_subnet
register: redis_vip
- name: Create foo Virtual IP (Not creating a neutron port)
tripleo_service_vip_port:
stack_name: overcloud
service_name: foo
network: foo
fixed_ip:
- ip_address: 192.0.2.5
use_neutron: false
register: redis_vip
'''
VIRTUAL_IP_NAME_SUFFIX = '_virtual_ip'
@ -238,6 +251,37 @@ def use_fake(service, fixed_ips):
return port
# This method is here so that openstack_cloud_from_module
# can be mocked in tests.
def _openstack_cloud_from_module(module):
_, conn = openstack_cloud_from_module(module)
return _, conn
def create_service_vip(module, stack, service, network, fixed_ips,
playbook_dir):
_use_neutron = True
for fixed_ip in fixed_ips:
if ('use_neutron', False) in fixed_ip.items():
_use_neutron = False
break
if _use_neutron:
try:
_, conn = _openstack_cloud_from_module(module)
_use_neutron = conn.identity.find_service('neutron') is not None
except kauth1_exc.MissingRequiredOptions:
_use_neutron = False
if _use_neutron:
port = use_neutron(conn, stack, service, network, fixed_ips)
else:
port = use_fake(service, fixed_ips)
write_vars_file(port, service, playbook_dir)
def run_module():
result = dict(
success=False,
@ -258,22 +302,12 @@ def run_module():
stack = module.params.get('stack_name', 'overcloud')
service = module.params['service_name']
network = module.params['network']
fixed_ips = module.params['fixed_ips']
fixed_ips = module.params.get('fixed_ips', [])
playbook_dir = module.params['playbook_dir']
try:
try:
_, conn = openstack_cloud_from_module(module)
neutron_found = conn.identity.find_service('neutron') is not None
except kauth1_exc.MissingRequiredOptions:
neutron_found = False
if neutron_found:
port = use_neutron(conn, stack, service, network, fixed_ips)
else:
port = use_fake(service, fixed_ips)
write_vars_file(port, service, playbook_dir)
create_service_vip(module, stack, service, network, fixed_ips,
playbook_dir)
result['changed'] = True
result['success'] = True

View File

@ -31,7 +31,7 @@ class TestTripleoServiceVip(tests_base.TestCase):
self.a2g = lambda x: (n for n in x)
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
def test_create(self, mock_conn):
def test_create_port(self, mock_conn):
fixed_ips = [{'subnet': 'test'}]
fake_net = stubs.FakeNeutronNetwork(
name='test',
@ -60,7 +60,7 @@ class TestTripleoServiceVip(tests_base.TestCase):
fake_port, [mock.ANY, mock.ANY])
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
def test_update(self, mock_conn):
def test_update_port(self, mock_conn):
fixed_ips = [{'subnet': 'test'}]
fake_net = stubs.FakeNeutronNetwork(
name='test',
@ -137,3 +137,39 @@ class TestTripleoServiceVip(tests_base.TestCase):
tags = ['tripleo_stack_name={}'.format(stack),
'tripleo_vip_net=ctlplane']
mock_conn.network.ports.assert_called_once_with(tags=tags)
@mock.patch.object(plugin, 'write_vars_file', autospec=True)
@mock.patch.object(plugin, 'use_neutron', autospec=True)
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
@mock.patch.object(plugin, '_openstack_cloud_from_module', autospec=True)
def test_create_service_vip(self, mock_ocfm, mock_conn, mock_use_neutron,
mock_write_file):
module = mock.Mock()
fixed_ips = [{'ip_address': '10.0.0.10', 'subnet_id': 'subnet_id'}]
mock_ocfm.return_value = None, mock_conn
mock_conn.identity.find_service.return_value = True
mock_port = mock.Mock()
mock_use_neutron.return_value = mock_port
plugin.create_service_vip(module, 'overcloud', 'service', 'network',
fixed_ips, '/tmp/dir')
mock_use_neutron.assert_called_with(mock_conn, 'overcloud', 'service',
'network', fixed_ips)
mock_write_file.assert_called_with(mock_port, 'service', '/tmp/dir')
@mock.patch.object(plugin, 'write_vars_file', autospec=True)
@mock.patch.object(plugin, 'use_fake', autospec=True)
@mock.patch.object(openstack.connection, 'Connection', autospec=True)
@mock.patch.object(plugin, '_openstack_cloud_from_module', autospec=True)
def test_create_no_neutron_service_vip(self, mock_ocfm, mock_conn,
mock_use_fake, mock_write_file):
module = mock.Mock()
fixed_ips = [{'ip_address': '10.0.0.10', 'subnet_id': 'subnet_id',
'use_neutron': False}]
mock_ocfm.return_value = None, mock_conn
mock_conn.identity.find_service.return_value = True
mock_port = mock.Mock()
mock_use_fake.return_value = mock_port
plugin.create_service_vip(module, 'overcloud', 'service', 'network',
fixed_ips, '/tmp/dir')
mock_use_fake.assert_called_with('service', fixed_ips)
mock_write_file.assert_called_with(mock_port, 'service', '/tmp/dir')