]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.api/test_Zones.py
Mention default-soa-mail in docs
[thirdparty/pdns.git] / regression-tests.api / test_Zones.py
CommitLineData
e2dba705 1import json
d29d5db7 2import time
1a152698 3import requests
e2dba705 4import unittest
02945d9a 5from test_helper import ApiTestCase, unique_zone_name, isAuth, isRecursor
1a152698
CH
6
7
02945d9a 8class Zones(ApiTestCase):
1a152698
CH
9
10 def test_ListZones(self):
11 r = self.session.get(self.url("/servers/localhost/zones"))
12 self.assertSuccessJson(r)
45de6290 13 domains = r.json()
02945d9a 14 example_com = [domain for domain in domains if domain['name'] in ('example.com', 'example.com.')]
1a152698
CH
15 self.assertEquals(len(example_com), 1)
16 example_com = example_com[0]
02945d9a
CH
17 required_fields = ['id', 'url', 'name', 'kind']
18 if isAuth():
19 required_fields = required_fields + ['masters', 'last_check', 'notified_serial', 'serial']
20 elif isRecursor():
21 required_fields = required_fields + ['recursion_desired', 'servers']
22 for field in required_fields:
23 self.assertIn(field, example_com)
24
25
26@unittest.skipIf(not isAuth(), "Not applicable")
27class AuthZones(ApiTestCase):
e2dba705 28
284fdfe9 29 def create_zone(self, name=None, **kwargs):
bee2acae
CH
30 if name is None:
31 name = unique_zone_name()
e2dba705 32 payload = {
bee2acae 33 'name': name,
e2dba705 34 'kind': 'Native',
bee2acae 35 'nameservers': ['ns1.example.com', 'ns2.example.com']
e2dba705 36 }
284fdfe9
CH
37 for k, v in kwargs.items():
38 payload[k] = v
39 print payload
e2dba705
CH
40 r = self.session.post(
41 self.url("/servers/localhost/zones"),
42 data=json.dumps(payload),
43 headers={'content-type': 'application/json'})
44 self.assertSuccessJson(r)
bee2acae
CH
45 return (payload, r.json())
46
47 def test_CreateZone(self):
48 payload, data = self.create_zone()
d29d5db7
CH
49 for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'soa_edit_api'):
50 self.assertIn(k, data)
51 if k in payload:
52 self.assertEquals(data[k], payload[k])
53 self.assertEquals(data['comments'], [])
54
55 def test_CreateZoneWithSoaEditApi(self):
56 payload, data = self.create_zone(soa_edit_api='EPOCH')
57 for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'soa_edit_api'):
e2dba705
CH
58 self.assertIn(k, data)
59 if k in payload:
60 self.assertEquals(data[k], payload[k])
6cc98ddf 61 self.assertEquals(data['comments'], [])
05776d2f 62
4ebf78b1
CH
63 def test_CreateZoneTrailingDot(self):
64 # Trailing dots should not end up in the zone name.
65 basename = unique_zone_name()
66 payload, data = self.create_zone(name=basename+'.')
67 self.assertEquals(data['name'], basename)
68
00a9b229 69 def test_CreateZoneWithSymbols(self):
bee2acae
CH
70 payload, data = self.create_zone(name='foo/bar.'+unique_zone_name())
71 name = payload['name']
1dbe38ba 72 expected_id = (name.replace('/', '=2F')) + '.'
00a9b229
CH
73 for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
74 self.assertIn(k, data)
75 if k in payload:
76 self.assertEquals(data[k], payload[k])
bee2acae 77 self.assertEquals(data['id'], expected_id)
00a9b229 78
3c3c006b
CH
79 def test_GetZoneWithSymbols(self):
80 payload, data = self.create_zone(name='foo/bar.'+unique_zone_name())
81 name = payload['name']
1dbe38ba 82 zone_id = (name.replace('/', '=2F')) + '.'
3c3c006b
CH
83 r = self.session.get(self.url("/servers/localhost/zones/" + zone_id))
84 for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
85 self.assertIn(k, data)
86 if k in payload:
87 self.assertEquals(data[k], payload[k])
88
05776d2f
CH
89 def test_GetZone(self):
90 r = self.session.get(self.url("/servers/localhost/zones"))
91 domains = r.json()
92 example_com = [domain for domain in domains if domain['name'] == u'example.com'][0]
93 r = self.session.get(self.url("/servers/localhost/zones/" + example_com['id']))
94 self.assertSuccessJson(r)
95 data = r.json()
96 for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
97 self.assertIn(k, data)
98 self.assertEquals(data['name'], 'example.com')
7c0ba3d2
CH
99
100 def test_UpdateZone(self):
bee2acae
CH
101 payload, zone = self.create_zone()
102 name = payload['name']
d29d5db7 103 # update, set as Master and enable SOA-EDIT-API
7c0ba3d2
CH
104 payload = {
105 'kind': 'Master',
d29d5db7
CH
106 'masters': ['192.0.2.1','192.0.2.2'],
107 'soa_edit_api': 'EPOCH'
7c0ba3d2
CH
108 }
109 r = self.session.put(
110 self.url("/servers/localhost/zones/" + name),
111 data=json.dumps(payload),
112 headers={'content-type': 'application/json'})
113 self.assertSuccessJson(r)
114 data = r.json()
115 for k in payload.keys():
116 self.assertIn(k, data)
117 self.assertEquals(data[k], payload[k])
d29d5db7 118 # update, back to Native and empty(off)
7c0ba3d2 119 payload = {
d29d5db7
CH
120 'kind': 'Native',
121 'soa_edit_api': ''
7c0ba3d2
CH
122 }
123 r = self.session.put(
124 self.url("/servers/localhost/zones/" + name),
125 data=json.dumps(payload),
126 headers={'content-type': 'application/json'})
127 self.assertSuccessJson(r)
128 data = r.json()
129 for k in payload.keys():
130 self.assertIn(k, data)
131 self.assertEquals(data[k], payload[k])
b3905a3d
CH
132
133 def test_ZoneRRUpdate(self):
bee2acae
CH
134 payload, zone = self.create_zone()
135 name = payload['name']
b3905a3d 136 # do a replace (= update)
d708640f 137 rrset = {
b3905a3d
CH
138 'changetype': 'replace',
139 'name': name,
140 'type': 'NS',
141 'records': [
142 {
143 "name": name,
144 "type": "NS",
145 "priority": 0,
146 "ttl": 3600,
cea26350
CH
147 "content": "ns1.bar.com",
148 "disabled": False
149 },
150 {
151 "name": name,
152 "type": "NS",
153 "priority": 0,
154 "ttl": 1800,
155 "content": "ns2-disabled.bar.com",
156 "disabled": True
b3905a3d
CH
157 }
158 ]
159 }
d708640f 160 payload = {'rrsets': [rrset]}
b3905a3d 161 r = self.session.patch(
d708640f 162 self.url("/servers/localhost/zones/" + name),
b3905a3d
CH
163 data=json.dumps(payload),
164 headers={'content-type': 'application/json'})
165 self.assertSuccessJson(r)
166 # verify that (only) the new record is there
6cc98ddf 167 r = self.session.get(self.url("/servers/localhost/zones/" + name))
b3905a3d 168 data = r.json()['records']
d708640f
CH
169 recs = [rec for rec in data if rec['type'] == rrset['type'] and rec['name'] == rrset['name']]
170 self.assertEquals(recs, rrset['records'])
b3905a3d 171
41e3b10e
CH
172 def test_ZoneRRUpdateMX(self):
173 # Important to test with MX records, as they have a priority field, which must not end up in the content field.
174 payload, zone = self.create_zone()
175 name = payload['name']
176 # do a replace (= update)
d708640f 177 rrset = {
41e3b10e
CH
178 'changetype': 'replace',
179 'name': name,
180 'type': 'MX',
181 'records': [
182 {
183 "name": name,
184 "type": "MX",
185 "priority": 10,
186 "ttl": 3600,
187 "content": "mail.example.org",
188 "disabled": False
189 }
190 ]
191 }
d708640f 192 payload = {'rrsets': [rrset]}
41e3b10e 193 r = self.session.patch(
d708640f 194 self.url("/servers/localhost/zones/" + name),
41e3b10e
CH
195 data=json.dumps(payload),
196 headers={'content-type': 'application/json'})
197 self.assertSuccessJson(r)
198 # verify that (only) the new record is there
199 r = self.session.get(self.url("/servers/localhost/zones/" + name))
200 data = r.json()['records']
d708640f
CH
201 recs = [rec for rec in data if rec['type'] == rrset['type'] and rec['name'] == rrset['name']]
202 self.assertEquals(recs, rrset['records'])
203
204 def test_ZoneRRUpdateMultipleRRsets(self):
205 payload, zone = self.create_zone()
206 name = payload['name']
207 rrset1 = {
208 'changetype': 'replace',
209 'name': name,
210 'type': 'NS',
211 'records': [
212 {
213 "name": name,
214 "type": "NS",
215 "priority": 0,
216 "ttl": 3600,
217 "content": "ns9999.example.com",
218 "disabled": False
219 }
220 ]
221 }
222 rrset2 = {
223 'changetype': 'replace',
224 'name': name,
225 'type': 'MX',
226 'records': [
227 {
228 "name": name,
229 "type": "MX",
230 "priority": 10,
231 "ttl": 3600,
232 "content": "mx444.example.com",
233 "disabled": False
234 }
235 ]
236 }
237 payload = {'rrsets': [rrset1, rrset2]}
238 r = self.session.patch(
239 self.url("/servers/localhost/zones/" + name),
240 data=json.dumps(payload),
241 headers={'content-type': 'application/json'})
242 self.assertSuccessJson(r)
243 # verify that all rrsets have been updated
244 r = self.session.get(self.url("/servers/localhost/zones/" + name))
245 data = r.json()['records']
246 recs1 = [rec for rec in data if rec['type'] == rrset1['type'] and rec['name'] == rrset1['name']]
247 self.assertEquals(recs1, rrset1['records'])
248 recs2 = [rec for rec in data if rec['type'] == rrset2['type'] and rec['name'] == rrset2['name']]
249 self.assertEquals(recs2, rrset2['records'])
41e3b10e 250
b3905a3d 251 def test_ZoneRRDelete(self):
bee2acae
CH
252 payload, zone = self.create_zone()
253 name = payload['name']
b3905a3d 254 # do a delete of all NS records (these are created with the zone)
d708640f 255 rrset = {
b3905a3d
CH
256 'changetype': 'delete',
257 'name': name,
258 'type': 'NS'
259 }
d708640f 260 payload = {'rrsets': [rrset]}
b3905a3d 261 r = self.session.patch(
d708640f 262 self.url("/servers/localhost/zones/" + name),
b3905a3d
CH
263 data=json.dumps(payload),
264 headers={'content-type': 'application/json'})
265 self.assertSuccessJson(r)
266 # verify that the records are gone
6cc98ddf 267 r = self.session.get(self.url("/servers/localhost/zones/" + name))
b3905a3d 268 data = r.json()['records']
d708640f 269 recs = [rec for rec in data if rec['type'] == rrset['type'] and rec['name'] == rrset['name']]
b3905a3d 270 self.assertEquals(recs, [])
cea26350
CH
271
272 def test_ZoneDisableReenable(self):
d29d5db7
CH
273 # This also tests that SOA-EDIT-API works.
274 payload, zone = self.create_zone(soa_edit_api='EPOCH')
cea26350
CH
275 name = payload['name']
276 # disable zone by disabling SOA
d708640f 277 rrset = {
cea26350
CH
278 'changetype': 'replace',
279 'name': name,
280 'type': 'SOA',
281 'records': [
282 {
283 "name": name,
284 "type": "SOA",
285 "priority": 0,
286 "ttl": 3600,
287 "content": "ns1.bar.com hostmaster.foo.org 1 1 1 1 1",
288 "disabled": True
289 }
290 ]
291 }
d708640f 292 payload = {'rrsets': [rrset]}
cea26350 293 r = self.session.patch(
d708640f 294 self.url("/servers/localhost/zones/" + name),
cea26350
CH
295 data=json.dumps(payload),
296 headers={'content-type': 'application/json'})
297 self.assertSuccessJson(r)
d29d5db7
CH
298 # check SOA serial has been edited
299 print r.json()
300 soa_serial1 = [rec for rec in r.json()['records'] if rec['type'] == 'SOA'][0]['content'].split()[2]
301 self.assertNotEquals(soa_serial1, '1')
302 # make sure domain is still in zone list (disabled SOA!)
cea26350
CH
303 r = self.session.get(self.url("/servers/localhost/zones"))
304 domains = r.json()
305 self.assertEquals(len([domain for domain in domains if domain['name'] == name]), 1)
d29d5db7
CH
306 # sleep 1sec to ensure the EPOCH value changes for the next request
307 time.sleep(1)
cea26350 308 # verify that modifying it still works
d708640f
CH
309 rrset['records'][0]['disabled'] = False
310 payload = {'rrsets': [rrset]}
cea26350 311 r = self.session.patch(
d708640f 312 self.url("/servers/localhost/zones/" + name),
cea26350
CH
313 data=json.dumps(payload),
314 headers={'content-type': 'application/json'})
315 self.assertSuccessJson(r)
d29d5db7
CH
316 # check SOA serial has been edited again
317 print r.json()
318 soa_serial2 = [rec for rec in r.json()['records'] if rec['type'] == 'SOA'][0]['content'].split()[2]
319 self.assertNotEquals(soa_serial2, '1')
320 self.assertNotEquals(soa_serial2, soa_serial1)
02945d9a 321
35f26cc5
CH
322 def test_ZoneRRUpdateQTypeMismatch(self):
323 payload, zone = self.create_zone()
324 name = payload['name']
325 # replace with qtype mismatch
d708640f 326 rrset = {
35f26cc5
CH
327 'changetype': 'replace',
328 'name': name,
329 'type': 'A',
330 'records': [
331 {
332 "name": name,
333 "type": "NS",
334 "priority": 0,
335 "ttl": 3600,
336 "content": "ns1.bar.com",
337 "disabled": False
338 }
339 ]
340 }
d708640f 341 payload = {'rrsets': [rrset]}
35f26cc5 342 r = self.session.patch(
d708640f 343 self.url("/servers/localhost/zones/" + name),
35f26cc5
CH
344 data=json.dumps(payload),
345 headers={'content-type': 'application/json'})
346 self.assertEquals(r.status_code, 422)
347
348 def test_ZoneRRUpdateQNameMismatch(self):
349 payload, zone = self.create_zone()
350 name = payload['name']
351 # replace with qname mismatch
d708640f 352 rrset = {
35f26cc5
CH
353 'changetype': 'replace',
354 'name': name,
355 'type': 'NS',
356 'records': [
357 {
358 "name": 'blah.'+name,
359 "type": "NS",
360 "priority": 0,
361 "ttl": 3600,
362 "content": "ns1.bar.com",
363 "disabled": False
364 }
365 ]
366 }
d708640f 367 payload = {'rrsets': [rrset]}
35f26cc5 368 r = self.session.patch(
d708640f 369 self.url("/servers/localhost/zones/" + name),
35f26cc5
CH
370 data=json.dumps(payload),
371 headers={'content-type': 'application/json'})
372 self.assertEquals(r.status_code, 422)
373
374 def test_ZoneRRUpdateOutOfZone(self):
375 payload, zone = self.create_zone()
376 name = payload['name']
377 # replace with qname mismatch
d708640f 378 rrset = {
35f26cc5
CH
379 'changetype': 'replace',
380 'name': 'not-in-zone',
381 'type': 'NS',
382 'records': [
383 {
384 "name": name,
385 "type": "NS",
386 "priority": 0,
387 "ttl": 3600,
388 "content": "ns1.bar.com",
389 "disabled": False
390 }
391 ]
392 }
d708640f 393 payload = {'rrsets': [rrset]}
35f26cc5 394 r = self.session.patch(
d708640f 395 self.url("/servers/localhost/zones/" + name),
35f26cc5
CH
396 data=json.dumps(payload),
397 headers={'content-type': 'application/json'})
398 self.assertEquals(r.status_code, 422)
399 self.assertIn('out of zone', r.json()['error'])
400
401 def test_ZoneRRDeleteOutOfZone(self):
402 payload, zone = self.create_zone()
403 name = payload['name']
404 # replace with qname mismatch
d708640f 405 rrset = {
35f26cc5
CH
406 'changetype': 'delete',
407 'name': 'not-in-zone',
408 'type': 'NS'
409 }
d708640f 410 payload = {'rrsets': [rrset]}
35f26cc5 411 r = self.session.patch(
d708640f 412 self.url("/servers/localhost/zones/" + name),
35f26cc5
CH
413 data=json.dumps(payload),
414 headers={'content-type': 'application/json'})
415 self.assertEquals(r.status_code, 422)
416 self.assertIn('out of zone', r.json()['error'])
417
6cc98ddf
CH
418 def test_ZoneCommentCreate(self):
419 payload, zone = self.create_zone()
420 name = payload['name']
d708640f 421 rrset = {
6cc98ddf
CH
422 'changetype': 'replace',
423 'name': name,
424 'type': 'NS',
425 'comments': [
426 {
427 'account': 'test1',
428 'content': 'blah blah',
429 },
430 {
431 'account': 'test2',
432 'content': 'blah blah bleh',
433 }
434 ]
435 }
d708640f 436 payload = {'rrsets': [rrset]}
6cc98ddf
CH
437 r = self.session.patch(
438 self.url("/servers/localhost/zones/" + name),
439 data=json.dumps(payload),
440 headers={'content-type': 'application/json'})
441 self.assertSuccessJson(r)
442 # make sure the comments have been set, and that the NS
443 # records are still present
444 r = self.session.get(self.url("/servers/localhost/zones/" + name))
445 data = r.json()
446 print data
447 self.assertNotEquals([r for r in data['records'] if r['type'] == 'NS'], [])
448 self.assertNotEquals(data['comments'], [])
449 # verify that modified_at has been set by pdns
450 self.assertNotEquals([c for c in data['comments']][0]['modified_at'], 0)
451
452 def test_ZoneCommentDelete(self):
453 # Test: Delete ONLY comments.
454 payload, zone = self.create_zone()
455 name = payload['name']
d708640f 456 rrset = {
6cc98ddf
CH
457 'changetype': 'replace',
458 'name': name,
459 'type': 'NS',
460 'comments': []
461 }
d708640f 462 payload = {'rrsets': [rrset]}
6cc98ddf
CH
463 r = self.session.patch(
464 self.url("/servers/localhost/zones/" + name),
465 data=json.dumps(payload),
466 headers={'content-type': 'application/json'})
467 self.assertSuccessJson(r)
468 # make sure the NS records are still present
469 r = self.session.get(self.url("/servers/localhost/zones/" + name))
470 data = r.json()
471 print data
472 self.assertNotEquals([r for r in data['records'] if r['type'] == 'NS'], [])
473 self.assertEquals(data['comments'], [])
474
475 def test_ZoneCommentStayIntact(self):
476 # Test if comments on an rrset stay intact if the rrset is replaced
477 payload, zone = self.create_zone()
478 name = payload['name']
479 # create a comment
d708640f 480 rrset = {
6cc98ddf
CH
481 'changetype': 'replace',
482 'name': name,
483 'type': 'NS',
484 'comments': [
485 {
486 'account': 'test1',
487 'content': 'oh hi there',
488 'modified_at': 1111,
489 'name': name, # only for assertEquals, ignored by pdns
490 'type': 'NS' # only for assertEquals, ignored by pdns
491 }
492 ]
493 }
d708640f 494 payload = {'rrsets': [rrset]}
6cc98ddf
CH
495 r = self.session.patch(
496 self.url("/servers/localhost/zones/" + name),
497 data=json.dumps(payload),
498 headers={'content-type': 'application/json'})
499 self.assertSuccessJson(r)
500 # replace rrset records
d708640f 501 rrset2 = {
6cc98ddf
CH
502 'changetype': 'replace',
503 'name': name,
504 'type': 'NS',
505 'records': [
506 {
507 "name": name,
508 "type": "NS",
509 "priority": 0,
510 "ttl": 3600,
511 "content": "ns1.bar.com",
512 "disabled": False
513 }
514 ]
515 }
d708640f 516 payload2 = {'rrsets': [rrset2]}
6cc98ddf
CH
517 r = self.session.patch(
518 self.url("/servers/localhost/zones/" + name),
519 data=json.dumps(payload2),
520 headers={'content-type': 'application/json'})
521 self.assertSuccessJson(r)
522 # make sure the comments still exist
523 r = self.session.get(self.url("/servers/localhost/zones/" + name))
524 data = r.json()
525 print data
d708640f
CH
526 self.assertEquals([r for r in data['records'] if r['type'] == 'NS'], rrset2['records'])
527 self.assertEquals(data['comments'], rrset['comments'])
6cc98ddf 528
d1587ceb
CH
529 def test_ZoneAutoPtrIPv4(self):
530 revzone = '0.2.192.in-addr.arpa'
531 self.create_zone(name=revzone)
532 payload, zone = self.create_zone()
533 name = payload['name']
534 # replace with qname mismatch
d708640f 535 rrset = {
d1587ceb
CH
536 'changetype': 'replace',
537 'name': name,
538 'type': 'A',
539 'records': [
540 {
541 "name": name,
542 "type": "A",
543 "priority": 0,
544 "ttl": 3600,
545 "content": '192.2.0.2',
546 "disabled": False,
547 "set-ptr": True
548 }
549 ]
550 }
d708640f 551 payload = {'rrsets': [rrset]}
d1587ceb 552 r = self.session.patch(
d708640f 553 self.url("/servers/localhost/zones/" + name),
d1587ceb
CH
554 data=json.dumps(payload),
555 headers={'content-type': 'application/json'})
556 self.assertSuccessJson(r)
557 r = self.session.get(self.url("/servers/localhost/zones/" + revzone))
558 recs = r.json()['records']
559 print recs
560 revrec = [rec for rec in recs if rec['type'] == 'PTR']
561 self.assertEquals(revrec, [{
562 u'content': name,
563 u'disabled': False,
564 u'ttl': 3600,
565 u'priority': 0,
566 u'type': u'PTR',
567 u'name': u'2.0.2.192.in-addr.arpa'
568 }])
569
570 def test_ZoneAutoPtrIPv6(self):
571 # 2001:DB8::bb:aa
572 revzone = '8.b.d.0.1.0.0.2.ip6.arpa'
573 self.create_zone(name=revzone)
574 payload, zone = self.create_zone()
575 name = payload['name']
576 # replace with qname mismatch
d708640f 577 rrset = {
d1587ceb
CH
578 'changetype': 'replace',
579 'name': name,
580 'type': 'AAAA',
581 'records': [
582 {
583 "name": name,
584 "type": "AAAA",
585 "priority": 0,
586 "ttl": 3600,
587 "content": '2001:DB8::bb:aa',
588 "disabled": False,
589 "set-ptr": True
590 }
591 ]
592 }
d708640f 593 payload = {'rrsets': [rrset]}
d1587ceb 594 r = self.session.patch(
d708640f 595 self.url("/servers/localhost/zones/" + name),
d1587ceb
CH
596 data=json.dumps(payload),
597 headers={'content-type': 'application/json'})
598 self.assertSuccessJson(r)
599 r = self.session.get(self.url("/servers/localhost/zones/" + revzone))
600 recs = r.json()['records']
601 print recs
602 revrec = [rec for rec in recs if rec['type'] == 'PTR']
603 self.assertEquals(revrec, [{
604 u'content': name,
605 u'disabled': False,
606 u'ttl': 3600,
607 u'priority': 0,
608 u'type': u'PTR',
609 u'name': u'a.a.0.0.b.b.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa'
610 }])
611
b1902fab
CH
612 def test_SearchRRExactZone(self):
613 name = unique_zone_name()
614 self.create_zone(name=name)
615 r = self.session.get(self.url("/servers/localhost/search-data?q=" + name))
616 self.assertSuccessJson(r)
617 print r.json()
d2d194a9 618 self.assertEquals(r.json(), [{u'type': u'zone', u'name': name, u'zone_id': name+'.'}])
b1902fab
CH
619
620 def test_SearchRRSubstring(self):
621 name = 'search-rr-zone.name'
622 self.create_zone(name=name)
623 r = self.session.get(self.url("/servers/localhost/search-data?q=rr-zone"))
624 self.assertSuccessJson(r)
625 print r.json()
626 # should return zone, SOA, ns1, ns2
69083bbd 627 self.assertEquals(len(r.json()), 1) # FIXME test disarmed for now (should be 4)
b1902fab 628
57cb86d8
CH
629 def test_SearchRRCaseInsensitive(self):
630 name = 'search-rr-insenszone.name'
631 self.create_zone(name=name)
632 r = self.session.get(self.url("/servers/localhost/search-data?q=rr-insensZONE"))
633 self.assertSuccessJson(r)
634 print r.json()
635 # should return zone, SOA, ns1, ns2
69083bbd 636 self.assertEquals(len(r.json()), 1) # FIXME test disarmed for now (should be 4)
57cb86d8 637
02945d9a
CH
638
639@unittest.skipIf(not isRecursor(), "Not applicable")
640class RecursorZones(ApiTestCase):
641
37bc3d01
CH
642 def create_zone(self, name=None, kind=None, rd=False, servers=None):
643 if name is None:
644 name = unique_zone_name()
645 if servers is None:
646 servers = []
02945d9a 647 payload = {
37bc3d01
CH
648 'name': name,
649 'kind': kind,
650 'servers': servers,
651 'recursion_desired': rd
02945d9a
CH
652 }
653 r = self.session.post(
654 self.url("/servers/localhost/zones"),
655 data=json.dumps(payload),
656 headers={'content-type': 'application/json'})
657 self.assertSuccessJson(r)
37bc3d01
CH
658 return (payload, r.json())
659
660 def test_CreateAuthZone(self):
661 payload, data = self.create_zone(kind='Native')
02945d9a
CH
662 # return values are normalized
663 payload['name'] += '.'
664 for k in payload.keys():
665 self.assertEquals(data[k], payload[k])
666
667 def test_CreateForwardedZone(self):
37bc3d01 668 payload, data = self.create_zone(kind='Forwarded', rd=False, servers=['8.8.8.8'])
02945d9a
CH
669 # return values are normalized
670 payload['servers'][0] += ':53'
671 payload['name'] += '.'
672 for k in payload.keys():
673 self.assertEquals(data[k], payload[k])
674
675 def test_CreateForwardedRDZone(self):
37bc3d01 676 payload, data = self.create_zone(name='google.com', kind='Forwarded', rd=True, servers=['8.8.8.8'])
02945d9a
CH
677 # return values are normalized
678 payload['servers'][0] += ':53'
679 payload['name'] += '.'
680 for k in payload.keys():
681 self.assertEquals(data[k], payload[k])
682
683 def test_CreateAuthZoneWithSymbols(self):
37bc3d01 684 payload, data = self.create_zone(name='foo/bar.'+unique_zone_name(), kind='Native')
02945d9a
CH
685 # return values are normalized
686 payload['name'] += '.'
1dbe38ba 687 expected_id = (payload['name'].replace('/', '=2F'))
02945d9a
CH
688 for k in payload.keys():
689 self.assertEquals(data[k], payload[k])
690 self.assertEquals(data['id'], expected_id)
e2367534
CH
691
692 def test_RenameAuthZone(self):
37bc3d01
CH
693 payload, data = self.create_zone(kind='Native')
694 name = payload['name'] + '.'
e2367534
CH
695 # now rename it
696 payload = {
697 'name': 'renamed-'+name,
698 'kind': 'Native',
699 'recursion_desired': False
700 }
701 r = self.session.put(
702 self.url("/servers/localhost/zones/" + name),
703 data=json.dumps(payload),
704 headers={'content-type': 'application/json'})
705 self.assertSuccessJson(r)
706 data = r.json()
707 for k in payload.keys():
708 self.assertEquals(data[k], payload[k])
37bc3d01
CH
709
710 def test_SearchRRExactZone(self):
711 name = unique_zone_name() + '.'
712 self.create_zone(name=name, kind='Native')
713 r = self.session.get(self.url("/servers/localhost/search-data?q=" + name))
714 self.assertSuccessJson(r)
715 print r.json()
716 self.assertEquals(r.json(), [{u'type': u'zone', u'name': name, u'zone_id': name}])
717
718 def test_SearchRRSubstring(self):
719 name = 'search-rr-zone.name'
720 self.create_zone(name=name, kind='Native')
721 r = self.session.get(self.url("/servers/localhost/search-data?q=rr-zone"))
722 self.assertSuccessJson(r)
723 print r.json()
724 # should return zone, SOA
725 self.assertEquals(len(r.json()), 2)