def get_context_data(self, **kwargs): ret = super(Addresses, self).get_context_data(**kwargs) if self.dns_formset is None: dns_records = self.get_dns(self.limit_types) ips = {ip.address for ip in self.object.ipaddress_set.all()} self.dns_formset = DNSFormSet( hostnames=self.get_hostnames(), queryset=dns_records, prefix='dns', limit_types=self.limit_types, ips=ips, ) if self.dhcp_formset is None: 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, prefix='dhcp', ) if self.ip_formset is None: self.ip_formset = IPAddressFormSet( queryset=self.object.ipaddress_set.order_by('address'), prefix='ip' ) profile = self.request.user.get_profile() can_edit = profile.has_perm(self.edit_perm, self.object.venture) next_hostname = None first_free_ip_addresses = [] rack = self.object.find_rack() if rack: networks = rack.network_set.order_by('name') for network in networks: next_hostname = get_next_free_hostname(network.data_center) if next_hostname: break for network in networks: first_free_ip = get_first_free_ip(network.name) if first_free_ip: first_free_ip_addresses.append({ 'network_name': network.name, 'first_free_ip': first_free_ip, }) balancers = list(_get_balancers(self.object)) ret.update({ 'canedit': can_edit, 'balancers': balancers, 'dnsformset': self.dns_formset, 'dhcpformset': self.dhcp_formset, 'ipformset': self.ip_formset, 'next_hostname': next_hostname, 'first_free_ip_addresses': first_free_ip_addresses, }) return ret
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)
class Addresses(DeviceDetailView): template_name = 'ui/device_addresses.html' read_perm = Perm.read_device_info_generic edit_perm = Perm.edit_domain_name limit_types = {'A', 'CNAME', 'MX', 'TXT'} def __init__(self, *args, **kwargs): super(Addresses, self).__init__(*args, **kwargs) self.dns_formset = None self.dhcp_formset = None self.ip_formset = None def get_dns(self, limit_types=None): ips = set(ip.address for ip in self.object.ipaddress_set.all()) names = set(ip.hostname for ip in self.object.ipaddress_set.all() if ip.hostname) dotnames = set(name+'.' for name in names) revnames = set('.'.join(reversed(ip.split('.'))) + '.in-addr.arpa' for ip in ips) starrevnames = set() for name in revnames: parts = name.split('.') while parts: parts.pop(0) starrevnames.add('.'.join(['*'] + parts)) for entry in Record.objects.filter( db.Q(content__in=ips) | db.Q(name__in=names) | db.Q(content__in=names | dotnames) ).distinct(): names.add(entry.name) if entry.type == 'A': ips.add(entry.content) elif entry.type == 'CNAME': names.add(entry.content) starnames = set() for name in names: parts = name.split('.') while parts: parts.pop(0) starnames.add('.'.join(['*'] + parts)) query = Record.objects.filter( db.Q(content__in=ips | names) | db.Q(name__in=names | revnames | starnames | starrevnames) ).distinct().order_by('type', 'name', 'content') if limit_types is not None: query = query.filter(type__in=limit_types) return query def get_hostnames(self): ipaddresses = self.object.ipaddress_set.all() ips = set(ip.address for ip in ipaddresses) names = set(ip.hostname for ip in ipaddresses if ip.hostname) revnames = set('.'.join(reversed(ip.split('.'))) + '.in-addr.arpa' for ip in ips) hostnames = set(names) for record in Record.objects.filter( type='A', content__in=ips, ): hostnames.add(record.name) for record in Record.objects.filter( type='PTR', name__in=revnames, ): hostnames.add(record.content.strip('.')) return hostnames 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) def get_dhcp(self): macs = set(eth.mac for eth in self.object.ethernet_set.all()) return DHCPEntry.objects.filter(mac__in=macs) def get_context_data(self, **kwargs): ret = super(Addresses, self).get_context_data(**kwargs) if self.dns_formset is None: dns_records = self.get_dns(self.limit_types) ips = {ip.address for ip in self.object.ipaddress_set.all()} self.dns_formset = DNSFormSet( hostnames=self.get_hostnames(), queryset=dns_records, prefix='dns', limit_types=self.limit_types, ips=ips, ) if self.dhcp_formset is None: 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, prefix='dhcp', ) if self.ip_formset is None: self.ip_formset = IPAddressFormSet( queryset=self.object.ipaddress_set.order_by('address'), prefix='ip' ) profile = self.request.user.get_profile() can_edit = profile.has_perm(self.edit_perm, self.object.venture) next_hostname = None first_free_ip_addresses = [] rack = self.object.find_rack() if rack: networks = rack.network_set.order_by('name') for network in networks: next_hostname = get_next_free_hostname(network.data_center) if next_hostname: break for network in networks: first_free_ip = get_first_free_ip(network.name) if first_free_ip: first_free_ip_addresses.append({ 'network_name': network.name, 'first_free_ip': first_free_ip, }) ret.update({ 'canedit': can_edit, 'balancers': list(_get_balancers(self.object)), 'dnsformset': self.dns_formset, 'dhcpformset': self.dhcp_formset, 'ipformset': self.ip_formset, 'next_hostname': next_hostname, 'first_free_ip_addresses': first_free_ip_addresses, }) return ret