def save(self, node, user): """ Completes node data update. """ self.requires_firmware_update = False ip = self.cleaned_data.get('ip') oldName = node.name oldProject = node.project # Update node metadata node.name = self.cleaned_data.get('name').lower() node.owner = self.cleaned_data.get('owner') node.location = self.cleaned_data.get('location') node.geo_lat = self.cleaned_data.get('geo_lat') node.geo_long = self.cleaned_data.get('geo_long') node.ant_external = self.cleaned_data.get('ant_external') node.ant_polarization = self.cleaned_data.get('ant_polarization') node.ant_type = self.cleaned_data.get('ant_type') node.project = self.cleaned_data.get('project') node.node_type = self.cleaned_data.get('node_type') node.notes = self.cleaned_data.get('notes') node.url = self.cleaned_data.get('url') node.redundancy_req = self.cleaned_data.get('redundancy_req') if user.is_staff: node.system_node = self.cleaned_data.get('system_node') node.vpn_server = self.cleaned_data.get('vpn_server') if user.is_staff or getattr(settings, 'NONSTAFF_BORDER_ROUTERS', False): node.border_router = self.cleaned_data.get('border_router') node.save() # Update node traffic control policy tc_ingress = self.cleaned_data.get('tc_ingress') if tc_ingress: Policy.set_policy(node, node.vpn_mac_conf, PolicyAction.Shape, tc_ingress, PolicyFamily.Ethernet) else: try: node.gw_policy.get(addr = node.vpn_mac_conf, family = PolicyFamily.Ethernet).delete() except Policy.DoesNotExist: pass # Update DNS records on name changes if oldName != node.name or oldProject != node.project: Record.update_for_node(node, old_name = oldName, old_project = oldProject) # Generate node renamed event if oldName != node.name: Event.create_event(node, EventCode.NodeRenamed, '', EventSource.NodeDatabase, data = 'Old name: %s\n New name: %s' % (oldName, node.name)) # Update node profile for image generator try: profile = node.profile except Profile.DoesNotExist: profile = None if self.cleaned_data.get('template'): if not profile: profile = Profile(node = node, template = self.cleaned_data.get('template')) # Handle potential hardware changes new_template = self.cleaned_data.get('template') if profile.template != new_template: # Rename traffic graphs to preserve history node.rename_graphs(GraphType.Traffic, profile.template.iface_wifi, new_template.iface_wifi) def set_and_check(**kwargs): for key, value in kwargs.iteritems(): field = getattr(profile, key) meta = profile._meta.get_field(key) prep = meta.get_db_prep_value(value) if isinstance(meta, models.ManyToManyField): if set([m.pk for m in field.all()]) != set([m.pk for m in value]): self.requires_firmware_update = True elif field != prep: self.requires_firmware_update = True setattr(profile, key, value) if not self.cleaned_data.get('channel'): set_and_check(channel = node.project.channel) else: set_and_check(channel = self.cleaned_data.get('channel')) set_and_check( template = self.cleaned_data.get('template'), root_pass = self.cleaned_data.get('root_pass'), use_vpn = self.cleaned_data.get('use_vpn'), antenna = self.cleaned_data.get('ant_conn') or 0, lan_bridge = self.cleaned_data.get('lan_bridge') or False, wan_dhcp = self.cleaned_data.get('wan_dhcp'), wan_ip = self.cleaned_data.get('wan_ip'), wan_cidr = self.cleaned_data.get('wan_cidr'), wan_gw = self.cleaned_data.get('wan_gw') ) if self.cleaned_data.get('tc_egress'): set_and_check(vpn_egress_limit = self.cleaned_data.get('tc_egress').bandwidth) else: set_and_check(vpn_egress_limit = None) profile.save() set_and_check(optional_packages = self.cleaned_data.get('optional_packages')) profile.save() elif profile and (settings.IMAGE_GENERATOR_ENABLED or settings.DEBUG): profile.delete() # Registers node name NodeNames(name = node.name, node = node).save() return node