Create Amphora floating IP using a stack
Change-Id: I7ea1e775476fcd097ed6b56c574abf01e53d4954
This commit is contained in:
parent
bbf99d35be
commit
87ec31f52a
@ -65,6 +65,7 @@ skip_if_missing_networking_extensions = (
|
||||
|
||||
create_floating_ip = _floating_ip.create_floating_ip
|
||||
delete_floating_ip = _floating_ip.delete_floating_ip
|
||||
ensure_floating_ip = _floating_ip.ensure_floating_ip
|
||||
get_floating_ip = _floating_ip.get_floating_ip
|
||||
get_floating_ip_id = _floating_ip.get_floating_ip_id
|
||||
find_floating_ip = _floating_ip.find_floating_ip
|
||||
@ -108,6 +109,7 @@ NetworkIdType = _network.NetworkIdType
|
||||
add_router_interface = _router.add_router_interface
|
||||
create_router = _router.create_router
|
||||
delete_router = _router.delete_router
|
||||
ensure_router_interface = _router.ensure_router_interface
|
||||
get_router = _router.get_router
|
||||
get_router_id = _router.get_router_id
|
||||
remove_router_interface = _router.remove_router_interface
|
||||
|
@ -18,6 +18,9 @@ import typing
|
||||
import tobiko
|
||||
from tobiko.openstack.neutron import _client
|
||||
from tobiko.openstack.neutron import _network
|
||||
from tobiko.openstack.neutron import _port
|
||||
from tobiko.openstack.neutron import _router
|
||||
|
||||
|
||||
FloatingIpType = typing.Dict[str, typing.Any]
|
||||
FloatingIpIdType = typing.Union[str, FloatingIpType]
|
||||
@ -58,25 +61,28 @@ def find_floating_ip(client: _client.NeutronClientType = None,
|
||||
|
||||
def list_floating_ips(client: _client.NeutronClientType = None,
|
||||
retrieve_all=True,
|
||||
port: _port.PortIdType = None,
|
||||
**params) -> tobiko.Selection[FloatingIpType]:
|
||||
if port is not None:
|
||||
params['port_id'] = _port.get_port_id(port)
|
||||
floating_ips = _client.neutron_client(client).list_floatingips(
|
||||
retrieve_all=retrieve_all, **params)['floatingips']
|
||||
return tobiko.select(floating_ips)
|
||||
|
||||
|
||||
def create_floating_ip(network: _network.NetworkIdType = None,
|
||||
port: _port.PortIdType = None,
|
||||
client: _client.NeutronClientType = None,
|
||||
add_cleanup=True,
|
||||
**params) -> FloatingIpType:
|
||||
if 'floating_network_id' not in params:
|
||||
if network is None:
|
||||
network = params.get('floating_network_id')
|
||||
if network is None:
|
||||
from tobiko.openstack import stacks
|
||||
network_id = stacks.get_floating_network_id()
|
||||
else:
|
||||
network_id = _network.get_network_id(network)
|
||||
|
||||
if network_id is not None:
|
||||
params['floating_network_id'] = network_id
|
||||
network = stacks.get_floating_network_id()
|
||||
params['floating_network_id'] = _network.get_network_id(network)
|
||||
if port is not None:
|
||||
params['port_id'] = _port.get_port_id(port)
|
||||
floating_ip: FloatingIpType = _client.neutron_client(
|
||||
client).create_floatingip(body={'floatingip': params})['floatingip']
|
||||
if add_cleanup:
|
||||
@ -115,5 +121,21 @@ def update_floating_ip(floating_ip: FloatingIpIdType,
|
||||
raise NoSuchFloatingIp(id=floating_ip_id) from ex
|
||||
|
||||
|
||||
def ensure_floating_ip(fixed_ip_address: str,
|
||||
device_id: str = None) \
|
||||
-> FloatingIpType:
|
||||
port = _port.find_port(device_id=device_id,
|
||||
fixed_ips=[f'ip_address={fixed_ip_address}'])
|
||||
try:
|
||||
return find_floating_ip(port=port)
|
||||
except tobiko.ObjectNotFound:
|
||||
from tobiko.openstack import stacks
|
||||
subnet = tobiko.select(port['fixed_ips']).with_attributes(
|
||||
ip_address=fixed_ip_address).unique['subnet_id']
|
||||
_router.ensure_router_interface(subnet=subnet)
|
||||
fixture = stacks.FloatingIpStackFixture(port=port)
|
||||
return tobiko.setup_fixture(fixture).floating_ip_details
|
||||
|
||||
|
||||
class NoSuchFloatingIp(tobiko.ObjectNotFound):
|
||||
message = "No such floating IP found for {id!r}"
|
||||
|
@ -182,5 +182,25 @@ def remove_router_interface(router: RouterIdType,
|
||||
raise tobiko.ObjectNotFound() from ex
|
||||
|
||||
|
||||
def ensure_router_interface(subnet: _subnet.SubnetIdType,
|
||||
router: RouterIdType = None,
|
||||
client: _client.NeutronClientType = None):
|
||||
if isinstance(subnet, str):
|
||||
subnet = _subnet.get_subnet(subnet=subnet, client=client)
|
||||
if 'gateway_ip' not in subnet:
|
||||
if router is None:
|
||||
from tobiko.openstack import stacks
|
||||
router = stacks.get_router_id()
|
||||
LOG.debug("Add router interface: subnet={subnet['id']}")
|
||||
interface = add_router_interface(router=router,
|
||||
subnet=subnet,
|
||||
add_cleanup=False,
|
||||
client=client)
|
||||
interface_dump = json.dumps(interface, sort_keys=True, indent=4)
|
||||
LOG.info(f"Added router interface:\n{interface_dump}")
|
||||
subnet = _subnet.get_subnet(subnet=subnet, client=client)
|
||||
assert subnet['gateway_ip']
|
||||
|
||||
|
||||
class NoSuchRouter(tobiko.ObjectNotFound):
|
||||
message = "No such router found for {id!r}"
|
||||
|
@ -69,7 +69,7 @@ RouterStackFixture = _neutron.RouterStackFixture
|
||||
NetworkWithNetMtuWriteStackFixture = (
|
||||
_neutron.NetworkWithNetMtuWriteStackFixture)
|
||||
SecurityGroupsFixture = _neutron.SecurityGroupsFixture
|
||||
|
||||
FloatingIpStackFixture = _neutron.FloatingIpStackFixture
|
||||
get_external_network = _neutron.get_external_network
|
||||
has_external_network = _neutron.has_external_network
|
||||
skip_unless_has_external_network = _neutron.skip_unless_has_external_network
|
||||
|
@ -504,3 +504,50 @@ def default_nameservers(
|
||||
if ip_version is not None:
|
||||
nameservers = nameservers.with_attributes(version=ip_version)
|
||||
return nameservers
|
||||
|
||||
|
||||
class FloatingIpStackFixture(heat.HeatStackFixture):
|
||||
|
||||
#: Heat template file
|
||||
template = _hot.heat_template_file('neutron/floating_ip.yaml')
|
||||
|
||||
router_stack = tobiko.required_fixture(RouterStackFixture)
|
||||
|
||||
def __init__(self,
|
||||
stack_name: str = None,
|
||||
network: neutron.NetworkIdType = None,
|
||||
port: neutron.PortIdType = None):
|
||||
self._network = network
|
||||
self._port = port
|
||||
if port is not None and stack_name is None:
|
||||
stack_name = (f"{tobiko.get_object_name(self)}-"
|
||||
f"{neutron.get_port_id(port)}")
|
||||
super(FloatingIpStackFixture, self).__init__(stack_name=stack_name)
|
||||
|
||||
@property
|
||||
def network(self) -> str:
|
||||
network = self._network
|
||||
if network is None:
|
||||
return self.router_stack.network_id
|
||||
else:
|
||||
return neutron.get_network_id(network)
|
||||
|
||||
@property
|
||||
def port(self) -> str:
|
||||
port = self._port
|
||||
if port is None:
|
||||
raise ValueError(f"Undefined floating IP port ID for stack"
|
||||
f" {self.stack_name}")
|
||||
return neutron.get_port_id(port)
|
||||
|
||||
@property
|
||||
def network_details(self) -> neutron.NetworkType:
|
||||
return neutron.get_network(self.network_id)
|
||||
|
||||
@property
|
||||
def router_details(self) -> neutron.RouterType:
|
||||
return neutron.get_network(self.router_id)
|
||||
|
||||
@property
|
||||
def floating_ip_details(self) -> neutron.FloatingIpType:
|
||||
return neutron.get_floating_ip(self.floating_ip_id)
|
||||
|
57
tobiko/openstack/stacks/neutron/floating_ip.yaml
Normal file
57
tobiko/openstack/stacks/neutron/floating_ip.yaml
Normal file
@ -0,0 +1,57 @@
|
||||
heat_template_version: newton
|
||||
|
||||
|
||||
description: |
|
||||
Creates a floating IP connected to an existing Neutron port
|
||||
|
||||
|
||||
parameters:
|
||||
|
||||
network:
|
||||
type: string
|
||||
description: |
|
||||
provisioner network where floating IP addresses will be allocated
|
||||
constraints:
|
||||
- custom_constraint: neutron.network
|
||||
|
||||
port:
|
||||
type: string
|
||||
description: |
|
||||
port where fixed IP is being allocated
|
||||
constraints:
|
||||
- custom_constraint: neutron.port
|
||||
|
||||
|
||||
resources:
|
||||
|
||||
_network:
|
||||
type: OS::Neutron::Network
|
||||
external_id: network
|
||||
|
||||
_port:
|
||||
type: OS::Neutron::Port
|
||||
external_id: port
|
||||
|
||||
_floating_ip:
|
||||
type: OS::Neutron::FloatingIP
|
||||
description: Floating IP address to be connected to server
|
||||
properties:
|
||||
floating_network: {get_resource: _network}
|
||||
port_id: {get_resource: _port}
|
||||
|
||||
|
||||
outputs:
|
||||
|
||||
fixed_ips:
|
||||
description: fixed IP addresses of server
|
||||
value: {get_attr: [_port, fixed_ips]}
|
||||
|
||||
floating_ip_address:
|
||||
description: floating IP address of server in public network
|
||||
value: { get_attr: [_floating_ip, floating_ip_address] }
|
||||
|
||||
netowkr_id:
|
||||
value: {get_resource: _network}
|
||||
|
||||
port_id:
|
||||
value: {get_resource: _port}
|
@ -258,14 +258,6 @@ class OctaviaBasicFaultTest(testtools.TestCase):
|
||||
ip_address=self.loadbalancer_stack.floating_ip_address,
|
||||
lb_port=self.listener_stack.lb_port,
|
||||
lb_protocol=self.listener_stack.lb_protocol)
|
||||
|
||||
# Finding the loadbalancer's management port
|
||||
lb_network_ip = amphora['lb_network_ip']
|
||||
port = neutron.find_port(device_id=amphora['compute_id'],
|
||||
fixed_ips=[f'ip_address={lb_network_ip}'])
|
||||
# Ensure there is a floating IP which is set to the LB management port
|
||||
try:
|
||||
floating_ip = neutron.find_floating_ip(port_id=port['id'])
|
||||
except tobiko.ObjectNotFound:
|
||||
floating_ip = neutron.create_floating_ip(port_id=port['id'])
|
||||
return floating_ip
|
||||
return neutron.ensure_floating_ip(
|
||||
fixed_ip_address=amphora['lb_network_ip'],
|
||||
device_id=amphora['compute_id'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user