Rework novaclient floating ips actions
Methods for association floating ips and dissociation were deprecated in novaclient a year ago and latest major release (python-novaclient 10) doesn't include them[*]. These actions should be performed via neutronclient now. It requires more work, but there is no other options. As well, we can turn neutron job voting. [*] https://github.com/openstack/python-novaclient/blob/master/releasenotes/notes/remove-virt-interfaces-add-rm-fixed-floating-398c905d9c91cca8.yaml Change-Id: I6c019fe84fb3d6dfcef5dfadbbccff01bde4a102
This commit is contained in:
parent
64f3a57c4c
commit
f62456a221
@ -57,9 +57,7 @@
|
|||||||
- rally-task-murano:
|
- rally-task-murano:
|
||||||
# some workloads began fail. need more time to investigate
|
# some workloads began fail. need more time to investigate
|
||||||
voting: false
|
voting: false
|
||||||
- rally-task-neutron:
|
- rally-task-neutron
|
||||||
# should fail due to novaclient release
|
|
||||||
voting: false
|
|
||||||
- rally-task-neutron-with-extensions:
|
- rally-task-neutron-with-extensions:
|
||||||
# more services should be enabled
|
# more services should be enabled
|
||||||
voting: false
|
voting: false
|
||||||
@ -83,5 +81,6 @@
|
|||||||
- rally-task-ironic
|
- rally-task-ironic
|
||||||
- rally-task-keystone-glance-swift
|
- rally-task-keystone-glance-swift
|
||||||
- rally-task-mistral
|
- rally-task-mistral
|
||||||
|
- rally-task-neutron
|
||||||
- rally-task-telemetry
|
- rally-task-telemetry
|
||||||
- rally-task-zaqar
|
- rally-task-zaqar
|
||||||
|
@ -608,13 +608,42 @@ class NovaScenario(scenario.OpenStackScenario):
|
|||||||
"""Add floating IP to an instance
|
"""Add floating IP to an instance
|
||||||
|
|
||||||
:param server: The :class:`Server` to add an IP to.
|
:param server: The :class:`Server` to add an IP to.
|
||||||
:param address: The ip address or FloatingIP to add to the instance
|
:param address: The dict-like representation of FloatingIP to add
|
||||||
|
to the instance
|
||||||
:param fixed_address: The fixedIP address the FloatingIP is to be
|
:param fixed_address: The fixedIP address the FloatingIP is to be
|
||||||
associated with (optional)
|
associated with (optional)
|
||||||
"""
|
"""
|
||||||
server.add_floating_ip(address, fixed_address=fixed_address)
|
with atomic.ActionTimer(self, "neutron.list_ports"):
|
||||||
|
ports = self.clients("neutron").list_ports(device_id=server.id)
|
||||||
|
port = ports["ports"][0]
|
||||||
|
|
||||||
|
fip = address
|
||||||
|
if not isinstance(address, dict):
|
||||||
|
LOG.warning(
|
||||||
|
"The argument 'address' of "
|
||||||
|
"NovaScenario._associate_floating_ip method accepts a "
|
||||||
|
"dict-like representation of floating ip. Transmitting a "
|
||||||
|
"string with just an IP is deprecated.")
|
||||||
|
with atomic.ActionTimer(self, "neutron.list_floating_ips"):
|
||||||
|
all_fips = self.clients("neutron").list_floatingips(
|
||||||
|
tenant_id=self.context["tenant"]["id"])
|
||||||
|
filtered_fip = [f for f in all_fips["floatingips"]
|
||||||
|
if f["floating_ip_address"] == address]
|
||||||
|
if not filtered_fip:
|
||||||
|
raise exceptions.NotFoundException(
|
||||||
|
"There is no floating ip with '%s' address." % address)
|
||||||
|
fip = filtered_fip[0]
|
||||||
|
# the first case: fip object is returned from network wrapper
|
||||||
|
# the second case: from neutronclient directly
|
||||||
|
fip_ip = fip.get("ip", fip.get("floating_ip_address", None))
|
||||||
|
fip_update_dict = {"port_id": port["id"]}
|
||||||
|
if fixed_address:
|
||||||
|
fip_update_dict["fixed_ip_address"] = fixed_address
|
||||||
|
self.clients("neutron").update_floatingip(
|
||||||
|
fip["id"], {"floatingip": fip_update_dict}
|
||||||
|
)
|
||||||
utils.wait_for(server,
|
utils.wait_for(server,
|
||||||
is_ready=self.check_ip_address(address),
|
is_ready=self.check_ip_address(fip_ip),
|
||||||
update_resource=utils.get_from_manager())
|
update_resource=utils.get_from_manager())
|
||||||
# Update server data
|
# Update server data
|
||||||
server.addresses = server.manager.get(server.id).addresses
|
server.addresses = server.manager.get(server.id).addresses
|
||||||
@ -624,12 +653,34 @@ class NovaScenario(scenario.OpenStackScenario):
|
|||||||
"""Remove floating IP from an instance
|
"""Remove floating IP from an instance
|
||||||
|
|
||||||
:param server: The :class:`Server` to add an IP to.
|
:param server: The :class:`Server` to add an IP to.
|
||||||
:param address: The ip address or FloatingIP to remove
|
:param address: The dict-like representation of FloatingIP to remove
|
||||||
"""
|
"""
|
||||||
server.remove_floating_ip(address)
|
fip = address
|
||||||
|
if not isinstance(fip, dict):
|
||||||
|
LOG.warning(
|
||||||
|
"The argument 'address' of "
|
||||||
|
"NovaScenario._dissociate_floating_ip method accepts a "
|
||||||
|
"dict-like representation of floating ip. Transmitting a "
|
||||||
|
"string with just an IP is deprecated.")
|
||||||
|
with atomic.ActionTimer(self, "neutron.list_floating_ips"):
|
||||||
|
all_fips = self.clients("neutron").list_floatingips(
|
||||||
|
tenant_id=self.context["tenant"]["id"]
|
||||||
|
)
|
||||||
|
filtered_fip = [f for f in all_fips["floatingips"]
|
||||||
|
if f["floating_ip_address"] == address]
|
||||||
|
if not filtered_fip:
|
||||||
|
raise exceptions.NotFoundException(
|
||||||
|
"There is no floating ip with '%s' address." % address)
|
||||||
|
fip = filtered_fip[0]
|
||||||
|
self.clients("neutron").update_floatingip(
|
||||||
|
fip["id"], {"floatingip": {"port_id": None}}
|
||||||
|
)
|
||||||
|
# the first case: fip object is returned from network wrapper
|
||||||
|
# the second case: from neutronclient directly
|
||||||
|
fip_ip = fip.get("ip", fip.get("floating_ip_address", None))
|
||||||
utils.wait_for(
|
utils.wait_for(
|
||||||
server,
|
server,
|
||||||
is_ready=self.check_ip_address(address, must_exist=False),
|
is_ready=self.check_ip_address(fip_ip, must_exist=False),
|
||||||
update_resource=utils.get_from_manager()
|
update_resource=utils.get_from_manager()
|
||||||
)
|
)
|
||||||
# Update server data
|
# Update server data
|
||||||
|
@ -170,7 +170,7 @@ class VMScenario(nova_utils.NovaScenario):
|
|||||||
ext_network=floating_network,
|
ext_network=floating_network,
|
||||||
tenant_id=server.tenant_id, fixed_ip=fixed_ip)
|
tenant_id=server.tenant_id, fixed_ip=fixed_ip)
|
||||||
|
|
||||||
self._associate_floating_ip(server, fip["ip"], fixed_address=fixed_ip)
|
self._associate_floating_ip(server, fip, fixed_address=fixed_ip)
|
||||||
|
|
||||||
return fip
|
return fip
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ class VMScenario(nova_utils.NovaScenario):
|
|||||||
with logging.ExceptionLogger(
|
with logging.ExceptionLogger(
|
||||||
LOG, "Unable to delete IP: %s" % fip["ip"]):
|
LOG, "Unable to delete IP: %s" % fip["ip"]):
|
||||||
if self.check_ip_address(fip["ip"])(server):
|
if self.check_ip_address(fip["ip"])(server):
|
||||||
self._dissociate_floating_ip(server, fip["ip"])
|
self._dissociate_floating_ip(server, fip)
|
||||||
with atomic.ActionTimer(self, "neutron.delete_floating_ip"):
|
with atomic.ActionTimer(self, "neutron.delete_floating_ip"):
|
||||||
network_wrapper.wrap(self.clients,
|
network_wrapper.wrap(self.clients,
|
||||||
self).delete_floating_ip(
|
self).delete_floating_ip(
|
||||||
|
@ -38,12 +38,8 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
|||||||
self.floating_ip = mock.Mock()
|
self.floating_ip = mock.Mock()
|
||||||
self.image = mock.Mock()
|
self.image = mock.Mock()
|
||||||
self.context.update(
|
self.context.update(
|
||||||
{"user": {"id": "fake_user_id", "credential": mock.MagicMock()}})
|
{"user": {"id": "fake_user_id", "credential": mock.MagicMock()},
|
||||||
|
"tenant": {"id": "fake_tenant"}})
|
||||||
def _context_with_networks(self, networks):
|
|
||||||
retval = {"tenant": {"networks": networks}}
|
|
||||||
retval.update(self.context)
|
|
||||||
return retval
|
|
||||||
|
|
||||||
def _context_with_secgroup(self, secgroup):
|
def _context_with_secgroup(self, secgroup):
|
||||||
retval = {"user": {"secgroup": secgroup,
|
retval = {"user": {"secgroup": secgroup,
|
||||||
@ -140,9 +136,12 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
|||||||
"nova.boot_server")
|
"nova.boot_server")
|
||||||
|
|
||||||
def test__boot_server_with_network_exception(self):
|
def test__boot_server_with_network_exception(self):
|
||||||
|
self.context.update({"tenant": {"networks": None}})
|
||||||
|
|
||||||
self.clients("nova").servers.create.return_value = self.server
|
self.clients("nova").servers.create.return_value = self.server
|
||||||
|
|
||||||
nova_scenario = utils.NovaScenario(
|
nova_scenario = utils.NovaScenario(
|
||||||
context=self._context_with_networks(None))
|
context=self.context)
|
||||||
self.assertRaises(TypeError, nova_scenario._boot_server,
|
self.assertRaises(TypeError, nova_scenario._boot_server,
|
||||||
"image_id", "flavor_id",
|
"image_id", "flavor_id",
|
||||||
auto_assign_nic=True)
|
auto_assign_nic=True)
|
||||||
@ -506,32 +505,121 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
|||||||
|
|
||||||
def test__associate_floating_ip(self):
|
def test__associate_floating_ip(self):
|
||||||
nova_scenario = utils.NovaScenario(context=self.context)
|
nova_scenario = utils.NovaScenario(context=self.context)
|
||||||
nova_scenario._associate_floating_ip(self.server, self.floating_ip)
|
neutronclient = nova_scenario.clients("neutron")
|
||||||
self.server.add_floating_ip.assert_called_once_with(self.floating_ip,
|
neutronclient.list_ports.return_value = {"ports": [{"id": "p1"},
|
||||||
fixed_address=None)
|
{"id": "p2"}]}
|
||||||
|
|
||||||
|
fip_ip = "172.168.0.1"
|
||||||
|
fip_id = "some"
|
||||||
|
# case #1- an object from neutronclient
|
||||||
|
floating_ip = {"floating_ip_address": fip_ip, "id": fip_id}
|
||||||
|
|
||||||
|
nova_scenario._associate_floating_ip(self.server, floating_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": "p1"}}
|
||||||
|
)
|
||||||
|
# case #2 - an object from network wrapper
|
||||||
|
neutronclient.update_floatingip.reset_mock()
|
||||||
|
floating_ip = {"ip": fip_ip, "id": fip_id}
|
||||||
|
|
||||||
|
nova_scenario._associate_floating_ip(self.server, floating_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": "p1"}}
|
||||||
|
)
|
||||||
|
|
||||||
|
# these should not be called in both cases
|
||||||
|
self.assertFalse(neutronclient.list_floatingips.called)
|
||||||
|
# it is an old behavior. let's check that it was not called
|
||||||
|
self.assertFalse(self.server.add_floating_ip.called)
|
||||||
|
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.associate_floating_ip", count=2)
|
||||||
|
|
||||||
|
def test__associate_floating_ip_deprecated_behavior(self):
|
||||||
|
nova_scenario = utils.NovaScenario(context=self.context)
|
||||||
|
neutronclient = nova_scenario.clients("neutron")
|
||||||
|
neutronclient.list_ports.return_value = {"ports": [{"id": "p1"},
|
||||||
|
{"id": "p2"}]}
|
||||||
|
|
||||||
|
fip_id = "fip1"
|
||||||
|
fip_ip = "172.168.0.1"
|
||||||
|
neutronclient.list_floatingips.return_value = {
|
||||||
|
"floatingips": [
|
||||||
|
{"id": fip_id, "floating_ip_address": fip_ip},
|
||||||
|
{"id": "fip2", "floating_ip_address": "127.0.0.1"}]}
|
||||||
|
|
||||||
|
nova_scenario._associate_floating_ip(self.server, fip_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": "p1"}}
|
||||||
|
)
|
||||||
|
|
||||||
|
neutronclient.list_floatingips.assert_called_once_with(
|
||||||
|
tenant_id="fake_tenant")
|
||||||
|
|
||||||
|
# it is an old behavior. let's check that it was not called
|
||||||
|
self.assertFalse(self.server.add_floating_ip.called)
|
||||||
|
|
||||||
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
"nova.associate_floating_ip")
|
"nova.associate_floating_ip")
|
||||||
|
|
||||||
def test__associate_floating_ip_with_no_atomic_action(self):
|
|
||||||
nova_scenario = utils.NovaScenario(context=self.context)
|
|
||||||
nova_scenario._associate_floating_ip(self.server, self.floating_ip)
|
|
||||||
self.server.add_floating_ip.assert_called_once_with(self.floating_ip,
|
|
||||||
fixed_address=None)
|
|
||||||
|
|
||||||
def test__dissociate_floating_ip(self):
|
def test__dissociate_floating_ip(self):
|
||||||
nova_scenario = utils.NovaScenario(context=self.context)
|
nova_scenario = utils.NovaScenario(context=self.context)
|
||||||
nova_scenario._dissociate_floating_ip(self.server, self.floating_ip)
|
neutronclient = nova_scenario.clients("neutron")
|
||||||
self.server.remove_floating_ip.assert_called_once_with(
|
|
||||||
self.floating_ip)
|
fip_ip = "172.168.0.1"
|
||||||
|
fip_id = "some"
|
||||||
|
# case #1- an object from neutronclient
|
||||||
|
floating_ip = {"floating_ip_address": fip_ip, "id": fip_id}
|
||||||
|
|
||||||
|
nova_scenario._dissociate_floating_ip(self.server, floating_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": None}}
|
||||||
|
)
|
||||||
|
# case #2 - an object from network wrapper
|
||||||
|
neutronclient.update_floatingip.reset_mock()
|
||||||
|
floating_ip = {"ip": fip_ip, "id": fip_id}
|
||||||
|
|
||||||
|
nova_scenario._dissociate_floating_ip(self.server, floating_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": None}}
|
||||||
|
)
|
||||||
|
|
||||||
|
# these should not be called in both cases
|
||||||
|
self.assertFalse(neutronclient.list_floatingips.called)
|
||||||
|
# it is an old behavior. let's check that it was not called
|
||||||
|
self.assertFalse(self.server.add_floating_ip.called)
|
||||||
|
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.dissociate_floating_ip", count=2)
|
||||||
|
|
||||||
|
def test__disassociate_floating_ip_deprecated_behavior(self):
|
||||||
|
nova_scenario = utils.NovaScenario(context=self.context)
|
||||||
|
neutronclient = nova_scenario.clients("neutron")
|
||||||
|
|
||||||
|
fip_id = "fip1"
|
||||||
|
fip_ip = "172.168.0.1"
|
||||||
|
neutronclient.list_floatingips.return_value = {
|
||||||
|
"floatingips": [
|
||||||
|
{"id": fip_id, "floating_ip_address": fip_ip},
|
||||||
|
{"id": "fip2", "floating_ip_address": "127.0.0.1"}]}
|
||||||
|
|
||||||
|
nova_scenario._dissociate_floating_ip(self.server, fip_ip)
|
||||||
|
|
||||||
|
neutronclient.update_floatingip.assert_called_once_with(
|
||||||
|
fip_id, {"floatingip": {"port_id": None}}
|
||||||
|
)
|
||||||
|
|
||||||
|
neutronclient.list_floatingips.assert_called_once_with(
|
||||||
|
tenant_id="fake_tenant")
|
||||||
|
|
||||||
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
"nova.dissociate_floating_ip")
|
"nova.dissociate_floating_ip")
|
||||||
|
|
||||||
def test__dissociate_floating_ip_with_no_atomic_action(self):
|
|
||||||
nova_scenario = utils.NovaScenario(context=self.context)
|
|
||||||
nova_scenario._dissociate_floating_ip(self.server, self.floating_ip)
|
|
||||||
self.server.remove_floating_ip.assert_called_once_with(
|
|
||||||
self.floating_ip)
|
|
||||||
|
|
||||||
def test__check_ip_address(self):
|
def test__check_ip_address(self):
|
||||||
nova_scenario = utils.NovaScenario(context=self.context)
|
nova_scenario = utils.NovaScenario(context=self.context)
|
||||||
fake_server = fakes.FakeServerManager().create("test_server",
|
fake_server = fakes.FakeServerManager().create("test_server",
|
||||||
|
@ -209,8 +209,8 @@ class VMScenarioTestCase(test.ScenarioTestCase):
|
|||||||
scenario, server = self.get_scenario()
|
scenario, server = self.get_scenario()
|
||||||
|
|
||||||
netwrap = mock_wrap.return_value
|
netwrap = mock_wrap.return_value
|
||||||
netwrap.create_floating_ip.return_value = {
|
fip = {"id": "foo_id", "ip": "foo_ip"}
|
||||||
"id": "foo_id", "ip": "foo_ip"}
|
netwrap.create_floating_ip.return_value = fip
|
||||||
|
|
||||||
scenario._attach_floating_ip(
|
scenario._attach_floating_ip(
|
||||||
server, floating_network="bar_network")
|
server, floating_network="bar_network")
|
||||||
@ -221,7 +221,7 @@ class VMScenarioTestCase(test.ScenarioTestCase):
|
|||||||
tenant_id="foo_tenant", fixed_ip="foo_ip")
|
tenant_id="foo_tenant", fixed_ip="foo_ip")
|
||||||
|
|
||||||
scenario._associate_floating_ip.assert_called_once_with(
|
scenario._associate_floating_ip.assert_called_once_with(
|
||||||
server, "foo_ip", fixed_address="foo_ip")
|
server, fip, fixed_address="foo_ip")
|
||||||
|
|
||||||
@mock.patch(VMTASKS_UTILS + ".network_wrapper.wrap")
|
@mock.patch(VMTASKS_UTILS + ".network_wrapper.wrap")
|
||||||
def test__delete_floating_ip(self, mock_wrap):
|
def test__delete_floating_ip(self, mock_wrap):
|
||||||
@ -231,14 +231,14 @@ class VMScenarioTestCase(test.ScenarioTestCase):
|
|||||||
scenario.check_ip_address = mock.Mock(return_value=_check_addr)
|
scenario.check_ip_address = mock.Mock(return_value=_check_addr)
|
||||||
scenario._dissociate_floating_ip = mock.Mock()
|
scenario._dissociate_floating_ip = mock.Mock()
|
||||||
|
|
||||||
scenario._delete_floating_ip(
|
fip = {"id": "foo_id", "ip": "foo_ip"}
|
||||||
server, fip={"id": "foo_id", "ip": "foo_ip"})
|
scenario._delete_floating_ip(server, fip=fip)
|
||||||
|
|
||||||
scenario.check_ip_address.assert_called_once_with(
|
scenario.check_ip_address.assert_called_once_with(
|
||||||
"foo_ip")
|
"foo_ip")
|
||||||
_check_addr.assert_called_once_with(server)
|
_check_addr.assert_called_once_with(server)
|
||||||
scenario._dissociate_floating_ip.assert_called_once_with(
|
scenario._dissociate_floating_ip.assert_called_once_with(
|
||||||
server, "foo_ip")
|
server, fip)
|
||||||
mock_wrap.assert_called_once_with(scenario.clients, scenario)
|
mock_wrap.assert_called_once_with(scenario.clients, scenario)
|
||||||
mock_wrap.return_value.delete_floating_ip.assert_called_once_with(
|
mock_wrap.return_value.delete_floating_ip.assert_called_once_with(
|
||||||
"foo_id", wait=True)
|
"foo_id", wait=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user