def test_bind_reverse(self): # Correct data set for data in BIND_REVERSE["correct"]: form = BindReverse(data) self.assertTrue(form.is_valid()) # Incorrect data set for data in BIND_REVERSE["incorrect"]: form = BindReverse(data[0]) self.assertFalse(form.is_valid()) self.assertTrue(set(form._errors.keys()) == set(data[1]))
def record(request, mode, zone_name, action): data = json.loads(request.REQUEST.get('data', "{}")) form = BindForm.get_form(zone_name) if form is None: # add operation for a slave zone requested return HttpResponseBadRequest() if request.method == 'GET': # requesting the form if action == "add": return render_to_response("bind/add_form_rr_%s.django.html" % form.TYPE, {"form": form(), "zone_name": zone_name}) elif action == "edit": # requesting the form record_name = request.GET.get('rrkey', None) rrtype = request.GET.get('rrtype', None) bind_daemon = Bind() zone_config = bind_daemon.zone_config(zone_name) records = zone_config.config.names[record_name].records(rrtype).get_items() return render_to_response("bind/edit_form_rr.django.html", { "records": records, "type": rrtype, "record": record_name, "zone_name": zone_name}) else: if action != "delete": # delete actions are GET requests return HttpResponseBadRequest() if form.TYPE == BindForm.ZONE_STRAIGHT or form.TYPE == BindForm.ZONE_REVERSE: if action == "add": data["zone_name"] = zone_name # submitting the form form = form(data) if not form.is_valid(): return HttpResponse(json.dumps({"ok": 0, "errors": get_errors(form, data)}), mimetype="application/json") bind_daemon = Bind() # making shortcuts for key data rrkey = form.cleaned_data['rrkey'] # name rrtype = form.cleaned_data['rrtype'] # type rrvalue = form.cleaned_data['rrvalue'] # resolve zone_config = bind_daemon.zone_config(zone_name) zone_config.config.add_name(rrkey) zone_config.config.names[rrkey].records(rrtype, create=True).add(str(rrvalue)) zone_config.config.save(autoserial=True) # Checking whether we need to create a reversed record for straight A-records if data["rrtype"] == "A" and request.POST.get('create_reversed', False): reverse_form = BindReverse({"rrvalue": rrkey, "rrkey": rrvalue, "zone_name": "in-addr.arpa"}) if reverse_form.is_valid(): rrkey = reverse_form.cleaned_data['rrkey'] rrvalue = reverse_form.cleaned_data['rrvalue'] rrtype = form.cleaned_data['rrtype'] zone_name_reverse = bind_daemon.get_zone_name_by_ip(rrvalue) zone_config = bind_daemon.zone_config(zone_name_reverse) zone_config.config.add_name(rrkey) zone_config.config.names[rrkey].records(rrtypem,create=True).add(str(rrvalue)) zone_zonfig.config.save(autoserial=True) else: # Automatic PTR writing has failed log(2, "bind_app - record add", \ "Failed to write a reverse record. Data are: name='%s',resolve='%s'" % (rrkey, rrvalue)) return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json") data["rrkey"] = request.REQUEST.get('rrkey', None) data["rrtype"] = request.REQUEST.get('rrtype', None) if action == "edit": _data = {'rrtype': data['rrtype'], 'rrkey': data['rrkey'], 'zone_name': zone_name} errors = {} clean_data = [] for rrvalue_key in data: re_index = re.search("rrvalue_(\d+)", rrvalue_key) if not re_index: continue index = re_index.group(1) _data["rrvalue"] = data[rrvalue_key] _data['priority'] = data.get("priority_%s" % index, None) _form = form(_data) if _form.is_valid(): clean_data.append(_form.cleaned_data["rrvalue"]) else: _errors = get_errors(_form, _data) for e in _errors: errors["%s_%s" % (e, index)] = _errors[e] if errors: return HttpResponse(json.dumps({"ok": 0, "errors": errors}), mimetype="application/json") if len(clean_data) != 0: bind_daemon = Bind() zone_config = bind_daemon.zone_config(zone_name) records = zone_config.config.names[data['rrkey']].records(data['rrtype']) for item in records.get_items(): records.delete(item) for rrvalue in clean_data: records.add(str(rrvalue)) zone_config.config.save(autoserial=True) error = _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name} return HttpResponse(json.dumps({"ok": 1, "error": error}), mimetype="application/json") else: # data is empty. meaning delete the record errors = {"general": _("At least on value is required for the record '%(rrkey)s'") % {"rrkey": data['rrkey']}} return HttpResponse(json.dumps({"ok": 0, "errors": errors}), mimetype="application/json") if action == "delete": if request.GET.get("flag", None) == "info": msg = _('Are you sure you want to delete the %(type)s-record "%(name)s"?' % {"name": data["rrkey"],"type": data["rrtype"]}) return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json") bind_daemon = Bind() zone_config = bind_daemon.zone_config(zone_name) names = zone_config.config.get_names() if data["rrkey"] in names: zone_config.config.delete_name(data["rrkey"]) zone_config.config.save(autoserial=True) return HttpResponse(json.dumps({"ok": 1, "error": _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name}}), mimetype="application/json") elif form.TYPE == BindForm.FORWARD or form.TYPE == BindForm.HINT: # submitting the form if action == "add": form = form(data) if not form.is_valid(): return HttpResponse(json.dumps({"ok": 0, "errors": get_errors(form, data)}), mimetype="application/json") # making shortcuts for key data ipaddress = form.cleaned_data['ipaddress'] priority = int(form.cleaned_data['priority']) bind_daemon = Bind() named_zone = bind_daemon.get_zone(zone_name) forwarders = named_zone.get("forwarders", SortedDict()) # sorting the forwarders according to the priority i = 0 for forwarder in forwarders: i += 1 forwarders[forwarder] = i forwarders[ipaddress] = priority - 0.5 new_forwarders = SortedDict(sorted(forwarders.items(), key=lambda x:x[1])) # transforming to an appropriate format for forwarder in new_forwarders: new_forwarders[forwarder] = True named_zone["forwarders"] = new_forwarders bind_daemon.set_zone(zone_name, named_zone) bind_daemon.config.save() return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json") elif action == "type": # Changing zone type bind_daemon = Bind() named_zone = bind_daemon.get_zone(zone_name) if data["zone_type"] == "hint": named_zone["type"] = "hint" named_zone["file"] = BindConfig.ROOT_ZONE_PATH if "forwarders" in named_zone: del named_zone["forwarders"] if "forward" in named_zone: del named_zone["forward"] elif data["zone_type"] == "forward": # type == "forward" if "file" in named_zone: del named_zone["file"] named_zone["type"] = "forward" named_zone["forward"] = "only" if not "forwarders" in named_zone: named_zone["forwarders"] = {} else: return HttpResponse(json.dumps({"ok": 1, "errors": _("Not implemented")}), mimetype="application/json") bind_daemon.set_zone(zone_name, named_zone) bind_daemon.config.save() return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json") elif action == "delete": if request.GET.get("flag", None) == "info": msg = _('Are you sure you want to delete the forward server "%(name)s"?' % {"name": request.REQUEST.get("rrkey", "")}) return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json") bind_daemon = Bind() named_zone = bind_daemon.get_zone(zone_name) forwarders = named_zone.get("forwarders", SortedDict()) forwarder = request.REQUEST.get('rrkey', None) if forwarder in forwarders: del forwarders[forwarder] named_zone["forwarders"] = forwarders bind_daemon.set_zone(zone_name, named_zone) bind_daemon.config.save() return HttpResponse(json.dumps({"ok": 1, "error": _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name}}), mimetype="application/json") else: # unrecognized request return HttpResponseBadRequest() #bind_daemon = Bind() #zone_config = bind_daemon.zone_config(zone_name) #include_file = bind_daemon.check_includefile(ZONE_INCLUDE_FILE % zone_name) """