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, connection) 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
def save(self, user): """ Completes node registration. """ ip = self.cleaned_data.get('ip') project = self.cleaned_data.get('project') pool = self.cleaned_data.get('pool') prefix_len = self.cleaned_data.get('prefix_len') if prefix_len == 0: prefix_len = None subnet = None if not ip: # Assign a new IP address from the selected pool (if no IP address selected) node = Node() fresh_subnet = pool.allocate_subnet(prefix_len) net = ipcalc.Network(fresh_subnet.network, fresh_subnet.cidr) node.ip = str(net.host_first()) # Create a new subnet for this node or use an existing one if available subnet = Subnet(node = node, subnet = fresh_subnet.network, cidr = fresh_subnet.cidr) subnet.allocated = True subnet.allocated_at = datetime.now() subnet.status = SubnetStatus.NotAnnounced else: # When prefix is not available we should use /32 if prefix_len is None: prefix_len = 32 net = ipcalc.Network(ip, prefix_len) sub_ip = str(net.network()) # Check if this node already exists try: node = Node.objects.get(ip = str(net.host_first())) except Node.DoesNotExist: node = Node(ip = str(net.host_first())) # Reserve existing IP in the pool pool.reserve_subnet(sub_ip, prefix_len) try: subnet = Subnet.objects.get(node = node, subnet = sub_ip, cidr = prefix_len) subnet.status = SubnetStatus.AnnouncedOk except Subnet.DoesNotExist: subnet = Subnet(node = node, subnet = sub_ip, cidr = prefix_len) subnet.status = SubnetStatus.NotAnnounced subnet.allocated = True subnet.allocated_at = datetime.now() # Update node metadata node.name = self.cleaned_data.get('name').lower() node.project = project node.owner = user 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.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') node.warnings = False for i in xrange(10): try: mac = gen_mac_address() Node.objects.get(vpn_mac_conf = mac) except Node.DoesNotExist: node.vpn_mac_conf = mac break else: raise Exception, "unable to generate unique MAC" 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.status = NodeStatus.New node.save() # Create 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) # Create node profile for image generator if self.cleaned_data.get('template'): profile = Profile(node = node, template = self.cleaned_data.get('template')) if self.cleaned_data.get('channel') in ('', "0", None): profile.channel = node.project.channel else: profile.channel = self.cleaned_data.get('channel') profile.root_pass = self.cleaned_data.get('root_pass') profile.use_vpn = self.cleaned_data.get('use_vpn') profile.antenna = self.cleaned_data.get('ant_conn') or 0 profile.lan_bridge = self.cleaned_data.get('lan_bridge') or False profile.wan_dhcp = self.cleaned_data.get('wan_dhcp') profile.wan_ip = self.cleaned_data.get('wan_ip') profile.wan_cidr = self.cleaned_data.get('wan_cidr') profile.wan_gw = self.cleaned_data.get('wan_gw') if self.cleaned_data.get('tc_egress'): profile.vpn_egress_limit = self.cleaned_data.get('tc_egress').bandwidth profile.save() profile.optional_packages = self.cleaned_data.get('optional_packages') profile.save() if subnet: subnet.node = node subnet.save() # Update DNS entries Record.update_for_node(node) # Registers node name NodeNames(name = node.name, node = node).save() # Generate node added event Event.create_event(node, EventCode.NodeAdded, '', EventSource.NodeDatabase, data = 'Maintainer: %s' % node.owner.username) self.node = node return node