diff --git a/contrail_api_cli/exceptions.py b/contrail_api_cli/exceptions.py index e23a2ca..7a9f95c 100644 --- a/contrail_api_cli/exceptions.py +++ b/contrail_api_cli/exceptions.py @@ -81,3 +81,9 @@ class BackRefsExists(Exists): def __str__(self): return "Back references from %s exists" % self._paths + + +class IsSystemResource(Exists): + + def __str__(self): + return "System resources %s cannot be changed" % self._paths diff --git a/contrail_api_cli/resource.py b/contrail_api_cli/resource.py index e107aec..b6713d2 100644 --- a/contrail_api_cli/resource.py +++ b/contrail_api_cli/resource.py @@ -20,7 +20,7 @@ from .utils import FQName, Path, Observable, to_json from .exceptions import ResourceNotFound, ResourceMissing, \ - CollectionNotFound, ChildrenExists, BackRefsExists + CollectionNotFound, ChildrenExists, BackRefsExists, IsSystemResource from .context import Context @@ -56,23 +56,27 @@ def wrapper(self, *args, **kwargs): raise CollectionNotFound(collection=self) elif e.http_status == 409: # contrail 3.2 - matches = re.match(r'^Delete when children still present: (\[[^]]*\])', e.message) + matches = re.match(r'^Delete when children still present: (\[[^]]*\])($| \(HTTP 409\)$)', e.message) if matches: raise ChildrenExists( resources=list(hrefs_list_to_resources(matches.group(1)))) - matches = re.match(r'^Delete when resource still referred: (\[[^]]*\])', e.message) + matches = re.match(r'^Delete when resource still referred: (\[[^]]*\])($| \(HTTP 409\)$)', e.message) if matches: raise BackRefsExists( resources=list(hrefs_list_to_resources(matches.group(1)))) # contrail 2.21 - matches = re.match(r'^Children (.*) still exist$', e.message) + matches = re.match(r'^Children (.*) still exist($| \(HTTP 409\)$)', e.message) if matches: raise ChildrenExists( resources=list(hrefs_to_resources(matches.group(1)))) - matches = re.match(r'^Back-References from (.*) still exist$', e.message) + matches = re.match(r'^Back-References from (.*) still exist($| \(HTTP 409\)$)', e.message) if matches: raise BackRefsExists( resources=list(hrefs_to_resources(matches.group(1)))) + # contrail 5.1 + matches = re.match(r'^Cannot modify system resource (.*) .*\(([a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12})\)($| \(HTTP 409\)$)', e.message) + if matches: + raise IsSystemResource(resources=[Resource(matches.group(1), uuid=matches.group(2))]) raise return wrapper diff --git a/contrail_api_cli/tests/test_resource.py b/contrail_api_cli/tests/test_resource.py index b6832b8..92acc14 100644 --- a/contrail_api_cli/tests/test_resource.py +++ b/contrail_api_cli/tests/test_resource.py @@ -11,7 +11,7 @@ from contrail_api_cli.utils import Path, FQName from contrail_api_cli.resource import RootCollection, Collection, Resource, ResourceEncoder from contrail_api_cli.client import ContrailAPISession -from contrail_api_cli.exceptions import ResourceNotFound, ResourceMissing, CollectionNotFound +from contrail_api_cli.exceptions import ResourceNotFound, ResourceMissing, CollectionNotFound, ChildrenExists, BackRefsExists, IsSystemResource from .utils import CLITest @@ -560,6 +560,22 @@ def test_resource_comparaison(self, mock_session): r1, r1.fq_name, r2, r2.fq_name, is_equal), ) + @mock.patch('contrail_api_cli.resource.Context.session') + def test_exist_exception(self, mock_session): + r = Resource('foo', uuid='ec1afeaa-8930-43b0-a60a-939f23a50724') + test_suite = [ + ("Delete when children still present: %s" % ['http://host%s' % r.path], ChildrenExists), + ("Children http://host%s still exist" % r.path, ChildrenExists), + ("Delete when resource still referred: %s" % ['http://host%s' % r.path], BackRefsExists), + ("Back-References from http://host%s still exist" % r.path, BackRefsExists), + ("Cannot modify system resource %s %s(%s)" % (r.type, r.fq_name, r.uuid), IsSystemResource), + ] + for msg, exception in test_suite: + mock_session.get_json.side_effect = HttpError(http_status=409, message=msg) + with self.assertRaises(exception) as e: + r.fetch() + self.assertListEqual([r], e.exception.resources) + if __name__ == "__main__": unittest.main()