示例#1
0
def nodes(request):
  """
  Display a list of all current nodes and their status.
  """
  return render_to_response('nodes/list.html',
    { 'nodes' : queryset_by_ip(Node.objects.all(), 'ip', 'node_type') },
    context_instance = RequestContext(request)
  )
示例#2
0
def nodes(request):
    """
  Display a list of all current nodes and their status.
  """
    return render_to_response(
        'nodes/list.html',
        {'nodes': queryset_by_ip(Node.objects.all(), 'ip', 'node_type')},
        context_instance=RequestContext(request))
示例#3
0
def pools(request):
  """
  Displays IP allocation pools.
  """
  return render_to_response('nodes/pools.html',
    { 'pools' : queryset_by_ip(Pool.objects.filter(parent = None), 'ip_subnet') },
    context_instance = RequestContext(request)
  )
示例#4
0
def my_nodes(request):
  """
  Display a list of current user's nodes.
  """
  return render_to_response('nodes/my.html',
    { 'nodes' : queryset_by_ip(request.user.node_set.all(), 'ip', 'node_type') },
    context_instance = RequestContext(request)
  )
示例#5
0
def pools(request):
    """
  Displays IP allocation pools.
  """
    return render_to_response('nodes/pools.html', {
        'pools':
        queryset_by_ip(Pool.objects.filter(parent=None), 'ip_subnet')
    },
                              context_instance=RequestContext(request))
示例#6
0
def my_nodes(request):
    """
  Display a list of current user's nodes.
  """
    return render_to_response('nodes/my.html', {
        'nodes':
        queryset_by_ip(request.user.node_set.all(), 'ip', 'node_type')
    },
                              context_instance=RequestContext(request))
示例#7
0
 def get_subnet_fields(self):
   """
   A helper method that returns all subnet fields in order.
   """
   for subnet in queryset_by_ip(self.__node.subnet_set.filter(allocated = True), 'ip_subnet'):
     field = self['subnet_%s' % subnet.pk]
     field.model = subnet
     field.prefix = 'prefix_%s' % subnet.pk
     field.manual_ip = self['manual_%s' % subnet.pk]
     yield field
示例#8
0
 def __init__(self, user, node, *args, **kwargs):
   """
   Class constructor.
   """
   super(RenumberForm, self).__init__(*args, **kwargs)
   self.__node = node
   
   # Setup dynamic form fields, depending on how may subnets a node has
   primary = node.subnet_set.ip_filter(ip_subnet__contains = "%s/32" % node.ip).filter(allocated = True).exclude(cidr = 0)
   
   for subnet in queryset_by_ip(node.subnet_set.filter(allocated = True), 'ip_subnet'):
     pools = []
     for pool in queryset_by_ip(node.project.pools.exclude(status = PoolStatus.Full), 'ip_subnet', 'description'):
       pools.append((pool.pk, _("Renumber to %(description)s [%(network)s/%(cidr)s]") % {
         'description': pool.description,
         'network': pool.network,
         'cidr': pool.cidr,
       }))
     
     choices = [
       (RenumberAction.Keep, _("Keep")),
       (RenumberAction.Remove, _("Remove"))
     ]
     
     # Primary subnets should not be removed
     if primary and primary[0] == subnet:
       del choices[1]
     
     self.fields['subnet_%s' % subnet.pk] = forms.ChoiceField(
       choices = choices + pools,
       initial = RenumberAction.Keep,
       widget = forms.Select(attrs = { 'class' : 'subnet' })
     )
     
     # Field for choosing new subnet prefix size
     self.fields['prefix_%s' % subnet.pk] = forms.IntegerField(required = False, initial = 27)
     
     # Field for manual subnet specification
     self.fields['manual_%s' % subnet.pk] = forms.CharField(required = False)
示例#9
0
 def clean(self):
   """
   Additional validation handler.
   """
   for subnet in queryset_by_ip(self.__node.subnet_set.filter(allocated = True), 'ip_subnet'):
     manual_ip = self.cleaned_data.get('manual_%s' % subnet.pk)
     if not manual_ip:
       continue
     
     action = int(self.cleaned_data.get('subnet_%s' % subnet.pk))
     prefix_len = int(self.cleaned_data.get('prefix_%s' % subnet.pk) or 27)
     
     # Validate IP address format
     if not IPV4_ADDR_RE.match(manual_ip):
       raise forms.ValidationError(_("Enter a valid IP address or leave the subnet field empty!"))
     
     # Validate pool status
     pool = Pool.objects.get(pk = action)
     if not pool.reserve_subnet(manual_ip, prefix_len, check_only = True):
       raise forms.ValidationError(_("Subnet %(subnet)s/%(prefix_len)d cannot be allocated from %(pool)s!") % { 'subnet' : manual_ip, 'prefix_len' : prefix_len, 'pool' : unicode(pool) })
   
   return self.cleaned_data
示例#10
0
 def get_pools(self):
   """
   A helper method that returns the IP pools.
   """
   return queryset_by_ip(self.__node.project.pools.exclude(status = PoolStatus.Full).filter(parent = None), 'ip_subnet', 'description')
示例#11
0
 def save(self):
   """
   Performs the actual renumbering.
   """
   # We must ensure exclusive access during node updates as otherwise this might happen
   # in the middle of a monitor update and this would cause unwanted consequences
   self.__node.ensure_exclusive_access()
   
   # Determine what subnet primary IP belonged to
   primary = self.__node.get_primary_subnet()
   renumber_primary = False
   old_router_id = self.__node.ip
   
   # Renumber subnets first
   for subnet in queryset_by_ip(self.__node.subnet_set.filter(allocated = True), 'ip_subnet')[:]:
     action = int(self.cleaned_data.get('subnet_%s' % subnet.pk))
     prefix_len = int(self.cleaned_data.get('prefix_%s' % subnet.pk) or 27)
     manual_ip = self.cleaned_data.get('manual_%s' % subnet.pk)
     
     if action == RenumberAction.Keep:
       pass
     elif action == RenumberAction.Remove:
       subnet.delete()
     else:
       # This means we should renumber to some other pool
       pool = Pool.objects.get(pk = action)
       if manual_ip:
         new_subnet = pool.reserve_subnet(manual_ip, prefix_len)
       else:
         new_subnet = pool.allocate_subnet(prefix_len)
       
       # If the old subnet has been the source of node's primary IP remember that
       save_primary = (not renumber_primary and primary and primary[0] == subnet)
       
       # Remove old subnet and create a new one; it is deleted here so the old allocation
       # is returned to the pool and all status info is reset
       subnet.delete()
       
       s = Subnet(node = self.__node, subnet = new_subnet.network, cidr = new_subnet.cidr)
       s.allocated = True
       s.allocated_at = datetime.now()
       s.status = SubnetStatus.NotAnnounced
       s.description = subnet.description
       s.gen_iface_type = subnet.gen_iface_type
       s.gen_dhcp = subnet.gen_dhcp
       s.save()
       
       if save_primary:
         primary = s
         renumber_primary = True
   
   # The subnet have now been renumbered, check if we need to renumber the primary IP
   router_id_changed = False
   if renumber_primary:
     net = ipcalc.Network(primary.subnet, primary.cidr)
     self.__node.ip = str(net.host_first())
     router_id_changed = True
   
   # Remove conflicting invalid nodes (another node with the IP we just renumbered to)
   existing_nodes = Node.objects.filter(ip = self.__node.ip, status = NodeStatus.Invalid)
   if existing_nodes.count() > 0:
     self.warning_or_continue(_("There is an existing but unregistered node with the same primary IP address you are currently renumbering to! If you continue with this operation, this invalid node will be replaced."))
   existing_nodes.delete()
   
   # Node has been renumbered, reset monitoring status as this node is obviously not
   # visible right after renumbering.
   if router_id_changed:
     # Update node's DNS record
     Record.update_for_node(self.__node)
     
     if not self.__node.is_pending():
       self.__node.status = NodeStatus.Down
       self.__node.peers = 0
       Link.objects.filter(src = self.__node).delete()
       Link.objects.filter(dst = self.__node).delete()
       self.__node.subnet_set.filter(allocated = False).delete()
       self.__node.subnet_set.all().update(status = SubnetStatus.NotAnnounced)
       
       # Setup a node renumbered notice (if one doesn't exist yet)
       try:
         notice = RenumberNotice.objects.get(node = self.__node)
         
         if notice.original_ip == self.__node.ip:
           notice.delete()
           self.__node.awaiting_renumber = False
         else:
           self.__node.awaiting_renumber = True
       except RenumberNotice.DoesNotExist:
         notice = RenumberNotice(node = self.__node)
         notice.original_ip = old_router_id
         notice.renumbered_at = datetime.now()
         notice.save()
         self.__node.awaiting_renumber = True
   
   self.__node.save()
   
   # Generate node renumbered event
   Event.create_event(self.__node, EventCode.NodeRenumbered, '', EventSource.NodeDatabase,
                      data = 'Old address: %s' % old_router_id)
示例#12
0
 def get_pools(self):
   """
   A helper method that returns all allocations pools.
   """
   return queryset_by_ip(self.__node.project.pools.exclude(status = PoolStatus.Full), 'ip_subnet', 'description')