def clean_new_hostname(self): old_ip = self.cleaned_data.get('address') new_hostname = self.cleaned_data['new_hostname'] if not is_valid_hostname(new_hostname): raise forms.ValidationError("Invalid hostname") try: get_domain(new_hostname) except Domain.DoesNotExist: raise forms.ValidationError("Invalid domain") try: ipaddress = IPAddress.objects.get(hostname=new_hostname) except IPAddress.DoesNotExist: if find_addresses_for_hostname(new_hostname): raise forms.ValidationError("Hostname already in DNS.") else: if ipaddress.device and not ipaddress.device.deleted: if not old_ip: raise forms.ValidationError("Hostname in use.") device = Device.objects.get(ipaddress__address=old_ip) if ipaddress.device.id != device.id: raise forms.ValidationError( "Hostname used by %s" % device, ) elif Record.objects.filter(name=new_hostname).exists(): raise forms.ValidationError("Hostname already in DNS.") return new_hostname
def clean_new_hostname(self): old_ip = self.cleaned_data.get('address') new_hostname = self.cleaned_data['new_hostname'] if not is_valid_hostname(new_hostname): raise forms.ValidationError("Invalid hostname") try: get_domain(new_hostname) except Domain.DoesNotExist: raise forms.ValidationError("Invalid domain") try: ipaddress = IPAddress.objects.get(hostname=new_hostname) except IPAddress.DoesNotExist: if find_addresses_for_hostname(new_hostname): raise forms.ValidationError("Hostname already in DNS.") else: if ipaddress.device and not ipaddress.device.deleted: if not old_ip: raise forms.ValidationError("Hostname in use.") device = Device.objects.get(ipaddress__address=old_ip) if ipaddress.device.id != device.id: raise forms.ValidationError("Hostname used by %s" % device, ) elif Record.objects.filter(name=new_hostname).exists(): raise forms.ValidationError("Hostname already in DNS.") return new_hostname
def validate_domain_name(name): if not name: return if '*' not in name and not is_valid_hostname(name): raise forms.ValidationError("Invalid hostname") if not get_domain(name): raise forms.ValidationError("No such domain") return name.lower()
def _dns_fill_record(form, prefix, record, request): for label in ('name', 'type', 'content', 'type'): setattr(record, label, form.cleaned_data[prefix + label] or None) record.domain = get_domain(record.name) if (record.type in ('A', 'AAAA') and form.cleaned_data[prefix + 'ptr']): try: created = set_revdns_record(record.content, record.name) except DNSError as e: messages.error(request, unicode(e)) else: if created: messages.warning( request, "Created a PTR DNS record for %s." % record.content)
def _dns_fill_record(form, prefix, record, request): for label in ('name', 'type', 'content', 'type'): setattr(record, label, form.cleaned_data[prefix + label] or None) record.domain = get_domain(record.name) if (record.type in ('A', 'AAAA') and form.cleaned_data[prefix + 'ptr']): try: created = set_revdns_record(record.content, record.name) except DNSError as e: messages.error(request, unicode(e)) else: if created: messages.warning( request, "Created a PTR DNS record for %s." % record.content )
def handle_single(self, filename, **options): if options['create_ptr']: create_ptr = True else: create_ptr = False print('Importing DNS records from {}...'.format(filename)) with open(filename, 'rb') as f: for i, value in enumerate(UnicodeReader(f), 1): if len(value) != 3: raise IncorrectLengthRowError( 'CSV row {} has {} elements, should be 3'.format( i, len(value), )) name, type, content = value if not all((name, type, content)): raise EmptyRecordValueError( 'Record fields can not be empty', ) if type not in RECORD_TYPES: raise DisallowedRecordTypeError( 'Record type {} is not allowed. Use:\n {}'.format( type, RECORD_TYPES, ), ) if type == 'A': try: ipaddr.IPv4Address(content) except ValueError: raise InvalidAddressError( 'Record {} has invalid IP address ({}).'.format( name, content, )) domain = get_domain(name) if not domain: raise DomainDoesNotExistError( 'Domain for {} does not exist in Ralph.'.format(name)) self.create_record(domain, name, type, content) if create_ptr: if type != 'A': raise DisallowedRecordTypeError( 'PTR record can only be created for record type A.' ) revname = '.'.join(reversed( content.split('.'))) + '.in-addr.arpa' # we need to create SOA domain/record first today = datetime.date.today().strftime('%Y%m%d') soa_name = '.'.join(revname.split('.')[1:]) soa_domain, created = Domain.objects.get_or_create( name=soa_name, ) if created: # last 2 digits == version for a given day soa_domain.notified_serial = today + '01' soa_domain.type = 'MASTER' soa_domain.save() print('Domain {} of type {} created (sn: {}).'.format( soa_domain.name, soa_domain.type, soa_domain.notified_serial, )) type = 'SOA' if options['soa_content']: content = options['soa_content'] else: content = settings.DEFAULT_SOA_RECORD_CONTENT self.create_record(soa_domain, soa_name, type, content) type = 'PTR' content = name self.create_record(soa_domain, revname, type, content)
def handle_single(self, filename, **options): if options['create_ptr']: create_ptr = True else: create_ptr = False print('Importing DNS records from {}...'.format(filename)) with open(filename, 'rb') as f: for i, value in enumerate(UnicodeReader(f), 1): if len(value) != 3: raise IncorrectLengthRowError( 'CSV row {} has {} elements, should be 3'.format( i, len(value), ) ) name, type, content = value if not all((name, type, content)): raise EmptyRecordValueError( 'Record fields can not be empty', ) if type not in RECORD_TYPES: raise DisallowedRecordTypeError( 'Record type {} is not allowed. Use:\n {}'.format( type, RECORD_TYPES, ), ) if type == 'A': try: ipaddr.IPv4Address(content) except ValueError: raise InvalidAddressError( 'Record {} has invalid IP address ({}).'.format( name, content, ) ) domain = get_domain(name) if not domain: raise DomainDoesNotExistError( 'Domain for {} does not exist in Ralph.'.format(name) ) self.create_record(domain, name, type, content) if create_ptr: if type != 'A': raise DisallowedRecordTypeError( 'PTR record can only be created for record type A.' ) revname = '.'.join( reversed(content.split('.')) ) + '.in-addr.arpa' # we need to create SOA domain/record first today = datetime.date.today().strftime('%Y%m%d') soa_name = '.'.join(revname.split('.')[1:]) soa_domain, created = Domain.objects.get_or_create( name=soa_name, ) if created: # last 2 digits == version for a given day soa_domain.notified_serial = today + '01' soa_domain.type = 'MASTER' soa_domain.save() print('Domain {} of type {} created (sn: {}).'.format( soa_domain.name, soa_domain.type, soa_domain.notified_serial, ) ) type = 'SOA' if options['soa_content']: content = options['soa_content'] else: content = settings.DEFAULT_SOA_RECORD_CONTENT self.create_record(soa_domain, soa_name, type, content) type = 'PTR' content = name self.create_record(soa_domain, revname, type, content)
def post(self, *args, **kwargs): self.object = self.get_object() profile = self.request.user.get_profile() if not profile.has_perm(self.edit_perm, self.object.venture): return HttpResponseForbidden( "You don't have permission to edit this." ) if 'dns' in self.request.POST: dns_records = self.get_dns(self.limit_types) ips = {ip.address for ip in self.object.ipaddress_set.all()} self.dns_formset = DNSFormSet( self.request.POST, queryset=dns_records, prefix='dns', hostnames=self.get_hostnames(), limit_types=self.limit_types, ips=ips, ) if self.dns_formset.is_valid(): for form in self.dns_formset.extra_forms: # Bind the newly created records to domains. if form.has_changed(): form.instance.domain = get_domain(form.instance.name) # Save the user for newly added records form.instance.saving_user = self.request.user for form in self.dns_formset.initial_forms: if form.has_changed(): # Save the user for modified records form.instance.saving_user = self.request.user # Make sure the PTR record is updated on field change if form.instance.ptr and ( 'name' in form.changed_data or 'content' in form.changed_data ): r = Record.objects.get(id=form.instance.id) for ptr in get_revdns_records( r.content).filter(content=r.name): ptr.saving_user = self.request.user ptr.delete() messages.warning( self.request, "PTR record for %s and %s deleted." % ( r.name, r.content, ), ) form.changed_data.append('ptr') self.dns_formset.save() for r, data in self.dns_formset.changed_objects: # Handle PTR creation/deletion if 'ptr' in data: if r.ptr: try: set_revdns_record(r.content, r.name) except DNSError as e: messages.error(self.request, unicode(e)) else: messages.warning( self.request, "PTR record for %s and %s created." % ( r.name, r.content, ), ) else: for ptr in get_revdns_records( r.content).filter(content=r.name): ptr.saving_user = self.request.user ptr.delete() messages.warning( self.request, "PTR record for %s and %s deleted." % ( r.name, r.content, ), ) for r in self.dns_formset.new_objects: # Handle PTR creation if r.ptr: try: set_revdns_record(r.content, r.name) except DNSError as e: messages.error(self.request, unicode(e)) else: messages.warning( self.request, "PTR record for %s created." % r.content ) for r in self.dns_formset.deleted_objects: # Handle PTR deletion for ptr in get_revdns_records( r.content).filter(content=r.name): messages.warning( self.request, "PTR record for %s deleted." % r.name ) ptr.saving_user = self.request.user ptr.delete() messages.success(self.request, "DNS records updated.") return HttpResponseRedirect(self.request.path) else: messages.error(self.request, "Errors in the DNS form.") elif 'dhcp' in self.request.POST: dhcp_records = self.get_dhcp() macs = {e.mac for e in self.object.ethernet_set.all()} ips = {ip.address for ip in self.object.ipaddress_set.all()} self.dhcp_formset = DHCPFormSet( dhcp_records, macs, ips, self.request.POST, prefix='dhcp', ) if self.dhcp_formset.is_valid(): self.dhcp_formset.save() messages.success(self.request, "DHCP records updated.") return HttpResponseRedirect(self.request.path) else: messages.error(self.request, "Errors in the DHCP form.") elif 'ip' in self.request.POST: self.ip_formset = IPAddressFormSet( self.request.POST, queryset=self.object.ipaddress_set.order_by('address'), prefix='ip', ) if self.ip_formset.is_valid(): for form in self.ip_formset.extra_forms: # Bind the newly created addresses to this device. if form.has_changed(): form.instance.device = self.object self.ip_formset.save() messages.success(self.request, "IP addresses updated.") return HttpResponseRedirect(self.request.path) else: messages.error(self.request, "Errors in the addresses form.") return self.get(*args, **kwargs)