def zone(request, mode, zone_name): user = request.user bind_daemon = Bind() zone = bind_daemon.get_zone(zone_name) if zone["type"] == "forward": if "forwarders" in zone: forwarders = zone["forwarders"].keys() else: forwarders = () return render_to_response("bind/forward_zone.django.html", {"zone_name": zone_name, "zone_type": zone["type"], "forwarders": forwarders}, context_instance=RequestContext(request)) else: zone_config = bind_daemon.zone_config(zone_name) records = zone_config.to_array() # sorting the records by name records_sorted = sorted(records, key=lambda d: d["name"]) return render_to_response("bind/rrs.django.html", {"zone_name": zone_name, "zone_type": zone["type"], "records": records_sorted}, context_instance=RequestContext(request))
def dashboard(request, mode): user = request.user bind_daemon = Bind() zones = bind_daemon.get_zones() zones = filter(lambda key: not key in BANNED_ZONES, zones) zones = [{"zone": zone, "type": bind_daemon.get_zone(zone)["type"]} for zone in zones] return render_to_response("bind/dashboard.django.html", {"zones": zones}, context_instance=RequestContext(request))
# -*- coding: utf-8 -*- from django.utils.translation import ugettext as _ from utils.permission import title, checkbox, radio from settings import BANNED_ZONES from bind.daemon import Bind MAP = title(_("DNS-service"), {"bind": checkbox(_("can control daemon"), "daemon", _("dashboard access"), "dashboard")} ) daemon = Bind() zones = daemon.get_zones() for zone in zones: if not zone in BANNED_ZONES: if daemon.config['zone "%s"' % zone]['type'] == "master": MAP["bind"].update(checkbox(_("Zone %(zone)s") % {"zone": zone}, {"_%s_" % zone: checkbox(_("can add new records"), "add", _("can delete records"), "delete", _("can change records"), "edit")})) elif daemon.config['zone "%s"' % zone]['type'] in ("forward", "hint"): MAP["bind"].update(checkbox(_("Zone %(zone)s") % {"zone": zone}, {"_%s_" % zone: checkbox(_("can add new records"), "add", _("can delete records"), "delete", _("can change type"), "type")})) else: # type = "slave", "hint" MAP["bind"].update(checkbox(_("Zone %(zone)s") % {"zone": zone}, "_%s_" % zone)) # Example 77# # user_perm = {"bind": {"ro77.control.ru": ["edit"], "77.10.in-addr.arpa": ["edit"], "daemon": ""}}
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) """
def clean(self): cleaned_data = self.cleaned_data for i in ('type', 'resolve', 'name'): if not cleaned_data.get(i, None): self._errors[i] = self.error_class([_("Required field")]) if self._errors: raise forms.ValidationError(u"") # All field are clean now action = cleaned_data.get('action', None) zone_name = self.cleaned_data["zone_name"] file = ZONE_INCLUDE_FILE % zone_name type = cleaned_data['type'] bind_daemon = Bind() config = bind_daemon.zone_config(zone_name) ### Name ### name = cleaned_data['name'] resolve = cleaned_data['resolve'] if type == "PTR": # name # should be an ip address # resolve # should be a full domain name name = form_check_ip_address(self, zone_name, name) resolve = form_check_domain_name(self, zone_name, resolve, type="name") else: # name # everywhere should be the same name = form_check_domain_name(self, zone_name, name) # resolve # if type in ("CNAME", "MX"): # resolve should be a domain name that already exists resolve = form_check_domain_name(self, zone_name, resolve, "resolve") if not resolve in config.keys(): if "$INCLUDE" in config.keys() and file in config['$INCLUDE'] \ and resolve in config['$INCLUDE'][file].keys(): pass else: self._errors['resolve'] = self.error_class([_("RR %(rslv)s doesn't exist") % {"rslv": resolve}]) raise forms.ValidationError(u"") if type == "MX": priority = cleaned_data.get('priority', None) if not priority: self._errors['priority'] = self.error_class([_("Required field")]) raise forms.ValidationError(u"") else: resolve = "%s\t%s" % (priority, resolve) else: resolve = form_check_ip_address(self, zone_name, resolve) if action == "add": # check for uniqueness if type == "PTR": name = re.sub("\.$", "", InAddrArpa(name).dehumanize()) if name in config.keys() and type in config[name].keys(): self._errors['name'] = self.error_class([_("Access denied")]) raise forms.ValidationError(u"") elif "$INCLUDE" in config.keys() and file in config["$INCLUDE"] \ and name in config["$INCLUDE"][file].keys() and \ type in config["$INCLUDE"][file][name] and \ resolve in config["$INCLUDE"][file][name][type]: self._errors['resolve'] = self.error_class([_("RR $(rslv)s already exists") % {"rslv": resolve}]) raise forms.ValidationError(u"") else: if name in config.keys() and type in config[name].keys(): self._errors['name'] = self.error_class([_("Access denied")]) raise forms.ValidationError(u"") elif "$INCLUDE" in config.keys() and file in config["$INCLUDE"] \ and name in config["$INCLUDE"][file].keys() and type in \ config["$INCLUDE"][file][name]: if type == "MX": if filter(lambda x: x["resolve"]==resolve_short, config["$INCLUDE"][file][name][type]): self._errors['resolve'] = self.error_class([_("RR $(rslv)s already exists") % {"rslv": "***"}]) # !? raise forms.ValidationError(u"") elif resolve in config["$INCLUDE"][file][name][type]: self._errors['resolve'] = self.error_class([_("RR $(rslv)s already exists") % {"rslv": resolve}]) raise forms.ValidationError(u"") a = {"type": type, "resolve": resolve, "name": name} if a["type"] == "A": a["create_reversed"] = cleaned_data.get('create_reversed', None) # return a