IPy for settings.INTERNAL_IPS

75 views
Skip to first unread message

Rodrigo Guzman

unread,
Mar 14, 2009, 7:33:08 PM3/14/09
to django-d...@googlegroups.com
A propos of the recent discussion about the possibility of using
IPy[1] to validate IPAddressField [2], I was thinking that ip
addresses can be handled more robustly in the INTERNAL_IPS setting.

The original use-case I had in mind was to allow the debug context
processor to handle a list of addresses in CIDR notation. This seems
easy to do with IPy (or another similar library) since the IPy.IP
class has a __contains__ method that behaves as one would expect,
e.g.:

'192.168.225.5' in IPy.IP('192.168.225.0/24') returns True

So, it seems like it'd be a straight forward change to
django.core.context_processors.debug to implement it. However, it
seems that this functionality would be better placed in the settings
module.

A few questions:

Is there interest in this? I do realize that the burden can be placed
on the user -- it is possible to just use IPy to generate a list for
INTERNAL_IPS. For my purposes that would be good enough.

Supposing that there is interest in django supporting this, am I
missing something in thinking this is relatively simple to implement
using IPy (or similar library)?

My initial approach to implementing this would be to change the
INTERNAL_IPS list from a list of strings to a thin wrapper around list
of IPy.IP objects in the constructor of the Settings class in
django.conf.__init__. The wrapper only so that the __contains__
method of the list of IPy.IP objects behaves correctly. Is this sane?

[1]: http://software.inl.fr/trac/wiki/IPy
[2]: http://groups.google.com/group/django-developers/browse_thread/thread/cc8a053611d0856a

Regards,

rz

Jeremy Dunck

unread,
Mar 15, 2009, 12:02:48 AM3/15/09
to django-d...@googlegroups.com
On Sat, Mar 14, 2009 at 6:33 PM, Rodrigo Guzman <rod...@gmail.com> wrote:
...

> So, it seems like it'd be a straight forward change to
> django.core.context_processors.debug to implement it.  However, it
> seems that this functionality would be better placed in the settings
> module.

Django only uses INTERNAL_IPS using "in", so just __contains__ is needed.

I've been doing something like this in my project settings for some
time; unless I'm missing something, there's no need to change Django:

class CIDR_LIST(list):
def __init__(self, cidrs):
from IPy import IP
self.cidrs = []
try:
for cidr in cidrs:
self.cidrs.append(IP(cidr))
except ImportError:
pass
def __contains__(self, ip):
try:
for cidr in self.cidrs:
if ip in cidr:
return True
except:
pass
return False

INTERNAL_IPS = CIDR_LIST([
'127.0.0.1/32',
'10.0.0.0/24'
])

Alex Gaynor

unread,
Mar 15, 2009, 12:05:13 AM3/15/09
to django-d...@googlegroups.com
Why are you subclassing list if you're going to just add a cidrs attr that's the list :)

Alex

--
"I disapprove of what you say, but I will defend to the death your right to say it." --Voltaire
"The people's good is the highest law."--Cicero

Jeremy Dunck

unread,
Mar 15, 2009, 12:15:35 AM3/15/09
to django-d...@googlegroups.com
On Sat, Mar 14, 2009 at 11:05 PM, Alex Gaynor <alex....@gmail.com> wrote:
...

> Why are you subclassing list if you're going to just add a cidrs attr that's
> the list :)

I'm handling INTERNAL_IPS which are multiple CIDR blocks. I could
have constructed with [IP('...'),IP('...')], but that's tomayto
tomahto. __contains__ loops over the multiple CIDRs-- is there a
better way?

Ludvig Ericson

unread,
Mar 15, 2009, 5:12:53 PM3/15/09
to django-d...@googlegroups.com
On Mar 15, 2009, at 05:02, Jeremy Dunck wrote:

> class CIDR_LIST(list):
> def __init__(self, cidrs):
> from IPy import IP
> self.cidrs = []
> try:
> for cidr in cidrs:
> self.cidrs.append(IP(cidr))
> except ImportError:
> pass
> def __contains__(self, ip):
> try:
> for cidr in self.cidrs:
> if ip in cidr:
> return True
> except:
> pass
> return False


from IPy import IP

class CIDRList(list):
def __init__(self, seq=()):
super(CIDRList, self).__init__(map(IP, seq))

def __contains__(self, other):
return any(other in range for range in self)

Of course, any only exists in recent Pythons, same for generator
expressions.

I also question the `except ImportError` in your __init__. :-)

- Ludvig

Jeremy Dunck

unread,
Mar 15, 2009, 5:23:30 PM3/15/09
to django-d...@googlegroups.com, django-d...@googlegroups.com
Yeah, dumb bug. :)



On Mar 15, 2009, at 4:12 PM, Ludvig Ericson <ludvig....@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages