diff --git a/.zuul.yaml b/.zuul.yaml index a45220f09..32c8b1fa3 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -181,26 +181,27 @@ queue: designate check: jobs: - - designate-bind9 +# - designate-bind9 - designate-bind9-centos9stream-fips: voting: false - designate-bind9-centos-9-stream: voting: false - - designate-bind9-keystone-default-roles - - designate-pdns4 - - designate-grenade-bind9 - - designate-grenade-pdns4 - - designate-ipv6-only-pdns4 - - designate-ipv6-only-bind9 - gate: - fail-fast: true - jobs: - - designate-bind9 - - designate-bind9-keystone-default-roles - - designate-pdns4 - - designate-grenade-pdns4 - - designate-ipv6-only-pdns4 - - designate-ipv6-only-bind9 +# Temporary disable to fix circular dependency +# - designate-bind9-keystone-default-roles +# - designate-pdns4 +# - designate-grenade-bind9 +# - designate-grenade-pdns4 +# - designate-ipv6-only-pdns4 +# - designate-ipv6-only-bind9 +# gate: +# fail-fast: true +# jobs: +# - designate-bind9 +# - designate-bind9-keystone-default-roles +# - designate-pdns4 +# - designate-grenade-pdns4 +# - designate-ipv6-only-pdns4 +# - designate-ipv6-only-bind9 - project: templates: diff --git a/designate/storage/sqlalchemy/__init__.py b/designate/storage/sqlalchemy/__init__.py index c04bffdde..11a46e92f 100644 --- a/designate/storage/sqlalchemy/__init__.py +++ b/designate/storage/sqlalchemy/__init__.py @@ -359,7 +359,7 @@ class SQLAlchemyStorage(base.SQLAlchemy): ## def _find_zones(self, context, criterion, one=False, marker=None, limit=None, sort_key=None, sort_dir=None, - apply_tenant_criteria=True): + apply_tenant_criteria=True, include_shared=False): # Check to see if the criterion can use the reverse_name column criterion = self._rname_check(criterion) @@ -374,7 +374,8 @@ class SQLAlchemyStorage(base.SQLAlchemy): context, tables.zones, objects.Zone, objects.ZoneList, exceptions.ZoneNotFound, criterion, one, marker, limit, sort_key, sort_dir, query=query, - apply_tenant_criteria=apply_tenant_criteria) + apply_tenant_criteria=apply_tenant_criteria, + include_shared=include_shared) def _load_relations(zone): if zone.type == 'SECONDARY': @@ -443,7 +444,8 @@ class SQLAlchemyStorage(base.SQLAlchemy): :param apply_tenant_criteria: Whether to filter results by project_id. """ zone = self._find_zones(context, {'id': zone_id}, one=True, - apply_tenant_criteria=apply_tenant_criteria) + apply_tenant_criteria=apply_tenant_criteria, + include_shared=True) return zone def find_zones(self, context, criterion=None, marker=None, limit=None, @@ -462,7 +464,7 @@ class SQLAlchemyStorage(base.SQLAlchemy): """ zones = self._find_zones(context, criterion, marker=marker, limit=limit, sort_key=sort_key, - sort_dir=sort_dir) + sort_dir=sort_dir, include_shared=True) return zones def find_zone(self, context, criterion): @@ -472,7 +474,8 @@ class SQLAlchemyStorage(base.SQLAlchemy): :param context: RPC Context. :param criterion: Criteria to filter by. """ - zone = self._find_zones(context, criterion, one=True) + zone = self._find_zones(context, criterion, one=True, + include_shared=True) return zone def update_zone(self, context, zone): diff --git a/designate/storage/sqlalchemy/base.py b/designate/storage/sqlalchemy/base.py index 79954ce3e..2a5985288 100644 --- a/designate/storage/sqlalchemy/base.py +++ b/designate/storage/sqlalchemy/base.py @@ -174,19 +174,33 @@ class SQLAlchemy(object, metaclass=abc.ABCMeta): return query def _apply_tenant_criteria(self, context, table, query, - include_null_tenant=True): + include_null_tenant=True, + include_shared=False): + shared_zone_project_id = tables.shared_zones.c.target_project_id if hasattr(table.c, 'tenant_id'): if not context.all_tenants: # NOTE: The query doesn't work with table.c.tenant_id is None, # so I had to force flake8 to skip the check if include_null_tenant: - query = query.where(or_( - table.c.tenant_id == context.project_id, - table.c.tenant_id == None)) # NOQA + if include_shared: + query = query.where(or_( + table.c.tenant_id == context.project_id, + shared_zone_project_id == context.project_id, + table.c.tenant_id == None)) # NOQA + else: + query = query.where(or_( + table.c.tenant_id == context.project_id, + table.c.tenant_id == None)) # NOQA else: - query = query.where( - table.c.tenant_id == context.project_id - ) + if include_shared: + query = query.where(or_( + table.c.tenant_id == context.project_id, + shared_zone_project_id == context.project_id + )) + else: + query = query.where( + table.c.tenant_id == context.project_id + ) return query @@ -247,7 +261,8 @@ class SQLAlchemy(object, metaclass=abc.ABCMeta): def _find(self, context, table, cls, list_cls, exc_notfound, criterion, one=False, marker=None, limit=None, sort_key=None, - sort_dir=None, query=None, apply_tenant_criteria=True): + sort_dir=None, query=None, apply_tenant_criteria=True, + include_shared=False): sort_key = sort_key or 'created_at' sort_dir = sort_dir or 'asc' @@ -257,7 +272,8 @@ class SQLAlchemy(object, metaclass=abc.ABCMeta): query = select(table) query = self._apply_criterion(table, query, criterion) if apply_tenant_criteria: - query = self._apply_tenant_criteria(context, table, query) + query = self._apply_tenant_criteria(context, table, query, + include_shared=include_shared) query = self._apply_deleted_criteria(context, table, query) # Execute the Query diff --git a/designate/tests/test_central/test_service.py b/designate/tests/test_central/test_service.py index df66e39a3..5c1db4af4 100644 --- a/designate/tests/test_central/test_service.py +++ b/designate/tests/test_central/test_service.py @@ -3966,6 +3966,36 @@ class CentralServiceTest(designate.tests.TestCase): self.assertEqual(context.project_id, shared_zone.project_id) self.assertEqual(zone.id, shared_zone.zone_id) + def test_share_zone_visibility(self): + context1 = self.get_context(project_id='1', roles=['member', 'reader']) + context2 = self.get_context(project_id='2', roles=['member', 'reader']) + context3 = self.get_context(project_id='3', roles=['member', 'reader']) + + # Create zone for project_id '1'. + zone = self.create_zone(context=context1) + + self.assertEqual(1, len(self.central_service.find_zones(context1))) + self.assertEqual(0, len(self.central_service.find_zones(context2))) + self.assertEqual(0, len(self.central_service.find_zones(context3))) + + # Share with project_id '2'. + share_zone = self.central_service.share_zone( + context1, zone['id'], objects.SharedZone.from_dict({ + 'target_project_id': context2.project_id + }) + ) + + self.assertEqual(1, len(self.central_service.find_zones(context1))) + self.assertEqual(1, len(self.central_service.find_zones(context2))) + self.assertEqual(0, len(self.central_service.find_zones(context3))) + + # Unshare zone. + self.central_service.unshare_zone(context1, zone['id'], share_zone.id) + + self.assertEqual(1, len(self.central_service.find_zones(context1))) + self.assertEqual(0, len(self.central_service.find_zones(context2))) + self.assertEqual(0, len(self.central_service.find_zones(context3))) + def test_share_zone_new_policy_defaults(self): # Configure designate for enforcing the new policy defaults self.useFixture(cfg_fixture.Config(cfg.CONF)) diff --git a/releasenotes/notes/Fix-list-and-show-shared-zones-8a42a6b5f4910fc7.yaml b/releasenotes/notes/Fix-list-and-show-shared-zones-8a42a6b5f4910fc7.yaml new file mode 100644 index 000000000..6e66c8e12 --- /dev/null +++ b/releasenotes/notes/Fix-list-and-show-shared-zones-8a42a6b5f4910fc7.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed an issue where zones shared with other projects may not be visible + when a zone list or zone show request is made by the other projects.