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