Merge "Extend octavia cleanup"

This commit is contained in:
Zuul 2019-07-10 17:50:18 +00:00 committed by Gerrit Code Review
commit a2645b7f79
2 changed files with 181 additions and 56 deletions

View File

@ -21,7 +21,6 @@ from rally_openstack.cleanup import base
from rally_openstack.services.identity import identity
from rally_openstack.services.image import glance_v2
from rally_openstack.services.image import image
from rally_openstack.services.loadbalancer import octavia
CONF = cfg.CONF
@ -264,13 +263,16 @@ class NeutronMixin(SynchronizedDeletion, base.ResourceManager):
delete_method = getattr(self._manager(), "delete_%s" % self._resource)
delete_method(self.id())
def list(self):
@property
def _plural_key(self):
if self._resource.endswith("y"):
resources = self._resource[:-1] + "ies"
return self._resource[:-1] + "ies"
else:
resources = self._resource + "s"
list_method = getattr(self._manager(), "list_%s" % resources)
result = list_method(tenant_id=self.tenant_uuid)[resources]
return self._resource + "s"
def list(self):
list_method = getattr(self._manager(), "list_%s" % self._plural_key)
result = list_method(tenant_id=self.tenant_uuid)[self._plural_key]
if self.tenant_uuid:
result = [r for r in result if r["tenant_id"] == self.tenant_uuid]
@ -326,41 +328,87 @@ class NeutronV2Loadbalancer(NeutronLbaasV2Mixin):
# OCTAVIA
@base.resource("octavia", "loadbalancer", order=next(_neutron_order),
tenant_resource=True)
class OctaviaMixIn(base.ResourceManager):
class OctaviaMixIn(NeutronMixin):
@property
def _client(self):
return octavia.Octavia(self.admin or self.user)
def id(self):
return self.raw_resource["id"]
def name(self):
return self.raw_resource["name"]
# TODO(andreykurilin): use proper helper class from
# rally_openstack.services as soon as it will have unified style
# of arguments across all methods
client = self.admin or self.user
return getattr(client, self._service)()
def delete(self):
return self._client().load_balancer_delete(
self.id(), cascade=True)
from octaviaclient.api.v2 import octavia as octavia_exc
delete_method = getattr(self._client, "%s_delete" % self._resource)
try:
return delete_method(self.id())
except octavia_exc.OctaviaClientException as e:
if e.code == 409 and "Invalid state PENDING_DELETE" in e.message:
# NOTE(andreykurilin): it is not ok. Probably this resource
# is not properly cleanup-ed (without wait-for loop)
# during the workload. No need to fail, continue silently.
return
raise
def is_deleted(self):
try:
self._client().load_balancer_show(self.id())
except Exception:
return True
from osc_lib import exceptions as osc_exc
show_method = getattr(self._client, "%s_show" % self._resource)
try:
show_method(self.id())
except osc_exc.NotFound:
return True
return False
def list(self):
return self._client().load_balancer_list()["loadbalancers"]
list_method = getattr(self._client, "%s_list" % self._resource)
return list_method()[self._plural_key.replace("_", "")]
@base.resource("octavia", "pools", order=next(_neutron_order),
@base.resource("octavia", "load_balancer", order=next(_neutron_order),
tenant_resource=True)
class OctaviaLoadBalancers(OctaviaMixIn):
def delete(self):
from octaviaclient.api.v2 import octavia as octavia_exc
delete_method = getattr(self._client, "load_balancer_delete")
try:
return delete_method(self.id(), cascade=True)
except octavia_exc.OctaviaClientException as e:
if e.code == 409 and "Invalid state PENDING_DELETE" in e.message:
# NOTE(andreykurilin): it is not ok. Probably this resource
# is not properly cleanup-ed (without wait-for loop)
# during the workload. No need to fail, continue silently.
return
raise
@base.resource("octavia", "pool", order=next(_neutron_order),
tenant_resource=True)
class OctaviaPools(OctaviaMixIn):
pass
@base.resource("octavia", "listener", order=next(_neutron_order),
tenant_resource=True)
class OctaviaListeners(OctaviaMixIn):
pass
@base.resource("octavia", "l7policy", order=next(_neutron_order),
tenant_resource=True)
class OctaviaL7Policies(OctaviaMixIn):
pass
@base.resource("octavia", "health_monitor", order=next(_neutron_order),
tenant_resource=True)
class OctaviaHealthMonitors(OctaviaMixIn):
pass
@base.resource("neutron", "bgpvpn", order=next(_neutron_order),
admin_required=True, perform_for_admin_only=True)
class NeutronBgpvpn(NeutronMixin):

View File

@ -1244,51 +1244,128 @@ class BarbicanSecretsTestCase(test.TestCase):
self.assertFalse(barbican.is_deleted())
@resources.base.resource("octavia", "some", order=3)
class OctaviaSimpleResource(resources.OctaviaMixIn):
pass
class OctaviaResourceTestCase(test.TestCase):
def get_octavia(self):
octavia = resources.OctaviaMixIn()
octavia._service = "octavia"
octavia._manager = mock.Mock()
return octavia
def test_name(self):
octavia = self.get_octavia()
octavia.raw_resource = {"name": "test_name"}
self.assertEqual("test_name", octavia.name())
resource = OctaviaSimpleResource({"name": "test_name"})
self.assertEqual("test_name", resource.name())
def test_id(self):
octavia = self.get_octavia()
octavia.raw_resource = {"id": "test_id"}
self.assertEqual("test_id", octavia.id())
resource = OctaviaSimpleResource({"id": "test_id"})
self.assertEqual("test_id", resource.id())
def test_delete(self):
octavia = self.get_octavia()
octavia.raw_resource = {"id": "test_id"}
octavia._client = mock.MagicMock()
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
resource = OctaviaSimpleResource(
user=clients, resource={"id": "test_id"})
octavia.delete()
octavia._client().load_balancer_delete.assert_called_once_with(
resource.delete()
octavia_client.some_delete.assert_called_once_with("test_id")
def test_delete_load_balancers(self):
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
resource = resources.OctaviaLoadBalancers(
user=clients, resource={"id": "test_id"})
resource.delete()
octavia_client.load_balancer_delete.assert_called_once_with(
"test_id", cascade=True)
def test_delete_with_exception(self):
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
resource = OctaviaSimpleResource(
user=clients, resource={"id": "test_id"})
# case #1: random exception is raised
octavia_client.some_delete.side_effect = ValueError("asd")
self.assertRaises(ValueError, resource.delete)
# case #2: octaviaclient inner exception with random message
from octaviaclient.api.v2 import octavia as octavia_exc
e = octavia_exc.OctaviaClientException(409, "bla bla bla")
octavia_client.some_delete.side_effect = e
self.assertRaises(octavia_exc.OctaviaClientException, resource.delete)
# case #3: octaviaclient inner exception with specific message
e = octavia_exc.OctaviaClientException(
409, "Invalid state PENDING_DELETE bla bla")
octavia_client.some_delete.side_effect = e
resource.delete()
def test_delete_load_balancer_with_exception(self):
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
resource = resources.OctaviaLoadBalancers(
user=clients, resource={"id": "test_id"})
# case #1: random exception is raised
octavia_client.load_balancer_delete.side_effect = ValueError("asd")
self.assertRaises(ValueError, resource.delete)
# case #2: octaviaclient inner exception with random message
from octaviaclient.api.v2 import octavia as octavia_exc
e = octavia_exc.OctaviaClientException(409, "bla bla bla")
octavia_client.load_balancer_delete.side_effect = e
self.assertRaises(octavia_exc.OctaviaClientException, resource.delete)
# case #3: octaviaclient inner exception with specific message
e = octavia_exc.OctaviaClientException(
409, "Invalid state PENDING_DELETE bla bla")
octavia_client.load_balancer_delete.side_effect = e
resource.delete()
def test_is_deleted_false(self):
octavia = self.get_octavia()
octavia.raw_resource = {"id": "test_id"}
octavia._client = mock.MagicMock()
self.assertFalse(octavia.is_deleted())
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
resource = OctaviaSimpleResource(
user=clients, resource={"id": "test_id"})
self.assertFalse(resource.is_deleted())
octavia_client.some_show.assert_called_once_with("test_id")
def test_is_deleted_true(self):
octavia = self.get_octavia()
octavia.raw_resource = {"id": "test_id"}
octavia._client = mock.MagicMock()
ex = Exception()
octavia._client().load_balancer_show.side_effect = ex
self.assertTrue(octavia.is_deleted())
from osc_lib import exceptions as osc_exc
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
octavia_client.some_show.side_effect = osc_exc.NotFound(404, "foo")
resource = OctaviaSimpleResource(
user=clients, resource={"id": "test_id"})
self.assertTrue(resource.is_deleted())
octavia_client.some_show.assert_called_once_with("test_id")
def test_list(self):
octavia = self.get_octavia()
octavia.raw_resource = {"id": "test_id"}
octavia._client = mock.MagicMock()
clients = mock.MagicMock()
octavia_client = clients.octavia.return_value
octavia_client.some_list.return_value = {"somes": [1, 2]}
manager = OctaviaSimpleResource(user=clients)
octavia.list()
octavia._client().load_balancer_list.assert_called_once_with()
self.assertEqual([1, 2], manager.list())
octavia_client.some_list.assert_called_once_with()
octavia_client.l7policy_list.return_value = {"l7policies": [3, 4]}
manager = resources.OctaviaL7Policies(user=clients)
self.assertEqual([3, 4], manager.list())
octavia_client.l7policy_list.assert_called_once_with()