Merge ~mpontillo/maas:fix-dnsresource-synthetic-records-for-zero-record-case--bug-1791383 into maas:master

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: 900145961bbb448a430186fd29c99b9705bf7985
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~mpontillo/maas:fix-dnsresource-synthetic-records-for-zero-record-case--bug-1791383
Merge into: maas:master
Diff against target: 133 lines (+60/-25)
2 files modified
src/maasserver/api/dnsresources.py (+35/-25)
src/maasserver/api/tests/test_dnsresources.py (+25/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Andres Rodriguez (community) Approve
Review via email: mp+354524@code.launchpad.net

Commit message

LP: #1791383 - Fix dnsresources read all=true when no concrete records exist.

To post a comment you must log in.
9001459... by Mike Pontillo

Format imports.

Revision history for this message
Andres Rodriguez (andreserl) wrote :

Lgtm!!!

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix-dnsresource-synthetic-records-for-zero-record-case--bug-1791383 lp:~mpontillo/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 900145961bbb448a430186fd29c99b9705bf7985

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/api/dnsresources.py b/src/maasserver/api/dnsresources.py
index bd8e994..7a8ae00 100644
--- a/src/maasserver/api/dnsresources.py
+++ b/src/maasserver/api/dnsresources.py
@@ -34,41 +34,50 @@ class DNSResourcesQuerySet(QuerySet):
3434
35 def __iter__(self):35 def __iter__(self):
36 """Custom iterator which also includes implicit DNS records."""36 """Custom iterator which also includes implicit DNS records."""
37 previous_domain = None37 domain = None
38 if self._domain_filter is not None:
39 unvisited_domains = set()
40 unvisited_domains.add(self._domain_filter)
41 else:
42 unvisited_domains = set(Domain.objects.all())
38 for record in super().__iter__():43 for record in super().__iter__():
39 # This works because the query always either contains a single44 # This works because the query always either contains a single
40 # domain, or is sorted by domain.45 # domain, or is sorted by domain.
41 if record.domain != previous_domain:46 if record.domain != domain:
42 previous_domain = record.domain47 domain = record.domain
43 rrdata = record.domain.render_json_for_related_rrdata(48 unvisited_domains.remove(domain)
44 include_dnsdata=False, as_dict=True,49 yield from self._generate_synthetic_rrdata(domain)
45 user=self._user_filter)
46 for name, value in rrdata.items():
47 name = name.split('.')[0]
48 # Remove redundant info (this is provided in the top
49 # level 'fqdn' field).
50 if (self._name_filter is not None and
51 name != self._name_filter):
52 continue
53 items = []
54 for rr in value:
55 if (self._rrtype_filter is not None and
56 rr['rrtype'] != self._rrtype_filter):
57 continue
58 del rr['name']
59 items.append(rr)
60 if len(items) > 0:
61 resource = DNSResource(
62 id=-1, name=name, domain=record.domain)
63 resource._rrdata = items
64 yield resource
65 yield record50 yield record
51 for domain in unvisited_domains:
52 yield from self._generate_synthetic_rrdata(domain)
53
54 def _generate_synthetic_rrdata(self, domain):
55 rrdata = domain.render_json_for_related_rrdata(
56 include_dnsdata=False, as_dict=True, user=self._user_filter)
57 for name, value in rrdata.items():
58 name = name.split('.')[0]
59 # Remove redundant info (this is provided in the top
60 # level 'fqdn' field).
61 if (self._name_filter is not None and name != self._name_filter):
62 continue
63 items = []
64 for rr in value:
65 if (self._rrtype_filter is not None and
66 rr['rrtype'] != self._rrtype_filter):
67 continue
68 del rr['name']
69 items.append(rr)
70 if len(items) > 0:
71 resource = DNSResource(id=-1, name=name, domain=domain)
72 resource._rrdata = items
73 yield resource
6674
6775
68def get_dnsresource_queryset(76def get_dnsresource_queryset(
69 all_records: bool, domainname: str=None, name: str=None,77 all_records: bool, domainname: str=None, name: str=None,
70 rrtype: str=None, user=None):78 rrtype: str=None, user=None):
71 # If the domain is a name, make it an id.79 # If the domain is a name, make it an id.
80 domain = None
72 if domainname is not None:81 if domainname is not None:
73 if domainname.isdigit():82 if domainname.isdigit():
74 domain = Domain.objects.get_domain_or_404(83 domain = Domain.objects.get_domain_or_404(
@@ -96,6 +105,7 @@ def get_dnsresource_queryset(
96 query.__class__ = DNSResourcesQuerySet105 query.__class__ = DNSResourcesQuerySet
97 query._name_filter = name_filter106 query._name_filter = name_filter
98 query._rrtype_filter = rrtype_filter107 query._rrtype_filter = rrtype_filter
108 query._domain_filter = domain
99 # Note: the _user_filter should be set to None we want to display109 # Note: the _user_filter should be set to None we want to display
100 # all records, even for non-superusers.110 # all records, even for non-superusers.
101 query._user_filter = user111 query._user_filter = user
diff --git a/src/maasserver/api/tests/test_dnsresources.py b/src/maasserver/api/tests/test_dnsresources.py
index ed3aa02..6c92513 100644
--- a/src/maasserver/api/tests/test_dnsresources.py
+++ b/src/maasserver/api/tests/test_dnsresources.py
@@ -11,8 +11,10 @@ import random
1111
12from django.conf import settings12from django.conf import settings
13from maasserver.api.dnsresources import get_dnsresource_queryset13from maasserver.api.dnsresources import get_dnsresource_queryset
14from maasserver.enum import NODE_STATUS
14from maasserver.models.dnsdata import DNSData15from maasserver.models.dnsdata import DNSData
15from maasserver.models.dnsresource import DNSResource16from maasserver.models.dnsresource import DNSResource
17from maasserver.models.domain import Domain
16from maasserver.testing.api import APITestCase18from maasserver.testing.api import APITestCase
17from maasserver.testing.factory import factory19from maasserver.testing.factory import factory
18from maasserver.utils.django_urls import reverse20from maasserver.utils.django_urls import reverse
@@ -121,6 +123,29 @@ class TestDNSResourcesAPI(APITestCase.ForUser):
121 ]123 ]
122 self.assertItemsEqual(expected_ids, result_ids)124 self.assertItemsEqual(expected_ids, result_ids)
123125
126 def test_read_all_with_only_implicit_records(self):
127 self.become_admin()
128 domain = Domain.objects.get_default_domain()
129 uri = get_dnsresources_uri()
130 machine = factory.make_Node_with_Interface_on_Subnet(
131 status=NODE_STATUS.DEPLOYED, domain=domain)
132 factory.make_StaticIPAddress(interface=machine.boot_interface)
133 response = self.client.get(
134 uri,
135 {
136 'all': 'true',
137 }
138 )
139 self.assertEqual(
140 http.client.OK, response.status_code, response.content)
141 expected_ids = [-1]
142 result_ids = [
143 dnsresource["id"]
144 for dnsresource in json.loads(
145 response.content.decode(settings.DEFAULT_CHARSET))
146 ]
147 self.assertItemsEqual(expected_ids, result_ids)
148
124 def test_read_with_name(self):149 def test_read_with_name(self):
125 for _ in range(3):150 for _ in range(3):
126 factory.make_DNSResource()151 factory.make_DNSResource()

Subscribers

People subscribed via source and target branches