#3237 closed enhancement (wontfix)
[patch] CIDR in INTERNAL_IPS
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | normal | Keywords: | CIDR INTERNAL_IPS |
Cc: | Triage Stage: | Design decision needed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
It'd be nice if INTERNAL_IPS could support CIDR expressions:
class CIDR_LIST(list):
def init(self, cidrs):
self.cidrs = []
try:
#http://cheeseshop.python.org/pypi/IPv4_Utils/0.35
import ipv4
for cidr in cidrs:
self.cidrs.append(ipv4.CIDR(cidr))
except ImportError:
pass
def contains(self, ip):
import ipv4
try:
for cidr in self.cidrs:
if ipv4.CIDR(ip) in cidr:
return True
except:
pass
return False
INTERNAL_IPS = CIDR_LIST([
'127.0.0.1',
'10.0.0.0/24'
])
Change History (13)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
Has patch: | set |
---|---|
Keywords: | CIDR INTERNAL_IPS added |
Triage Stage: | Unreviewed → Design decision needed |
comment:3 by , 18 years ago
Summary: | CIDR in INTERNAL_IPS → [patch] CIDR in INTERNAL_IPS |
---|
comment:4 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I don't think this is something that should be added to django proper, but you can bet your butt I'll use this code myself!
comment:5 by , 16 years ago
Has patch: | unset |
---|---|
Resolution: | wontfix |
Status: | closed → reopened |
A simpler version (see http://www.djangosnippets.org/snippets/1380/)
from fnmatch import fnmatch class glob_list(list): def __contains__(self, key): for elt in self: if fnmatch(key, elt): return True return False INTERNAL_IPS = glob_list([ '127.0.0.1', '18.85.*.*' ])
This is simple and useful enough that I'll entertain the thought of putting something like it in Django proper.
comment:6 by , 15 years ago
If the first one didn't belong in Django (which uses standard CIDR syntax accepted by sysadmins everywhere), this one definitely shouldn't be part of Django, with non-standard and very inflexible syntax that only supports a tiny subset of what CIDR is used for. Nominating for closure.
comment:7 by , 15 years ago
gav's right about my solution being very limited. If something is going to go in Django, it should be reasonably general.
Here's an adaptation to use ipaddr-py, which has been added to the Python standard library in 3.1 (so eventually it wouldn't be a separate dependency):
from ipaddr import IP class IpList(object): def __init__(self, addresses): self.addresses = [IP(address) for address in addresses] def __contains__(self, ip): ip = IP(ip) for address in self.addresses: if ip in address: return True return False INTERNAL_IPS = IpList([ '127.0.0.1', '10.0.0.0/24' ])
(I don't subclass list
because we don't intend to support the full list interface.)
btw, "I don't think this is something that should be added to django proper, but you can bet your butt I'll use this code myself!" -- isn't that what "contrib" is usually for?
comment:8 by , 15 years ago
The ipaddr
module was actually yanked out of 3.1 prior to final release, due to some controversy over whether it was really a good API for this. So I'd be somewhat wary of depending on it; whatever ends up in later 3.x Pythons may not resemble it at all.
comment:9 by , 15 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
I made this a snippet:
http://www.djangosnippets.org/snippets/1862/
Closing.
follow-up: 12 comment:10 by , 5 years ago
Easy pickings: | unset |
---|---|
Resolution: | wontfix |
Status: | closed → new |
UI/UX: | unset |
I would like to reopen this issue because it was closed already 10 years ago and I think it should be reevaluated for the following reasons:
- It is much more likely to run into this problem nowadays because when Django is executed using container virtualization (like Docker), the ip address of the container is often selected "randomly" and not known in advance. In this case setting
INTERNAL_IPS
to the the entire network from which Docker chooses from is the preferred solution. - The implementation works with only builtin modules beginning with the introduction of the
ipaddress
module in Python 3.3. So all versions of Python supported by Django >= 2.2 support this feature.
This is the implementation I currently use:
import ipaddress class CIDRList(list): def __init__(self, addresses): """Create a new ip_network object for each address range provided.""" self.networks = [ipaddress.ip_network(address) for address in addresses] def __contains__(self, address): """Check if the given address is contained in any of the networks.""" return any([ipaddress.ip_address(address) in network for network in self.networks])
I can then use for instance:
INTERNAL_IPS = CIDRList([ '127.0.0.1', '172.0.0.0/255.0.0.0' # Docker containers ])
comment:11 by , 5 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
follow-up: 13 comment:12 by , 5 years ago
Replying to Fabian Köster:
Why overcomplicate things? You can do the following without any custom classes:
import ipaddress INTERNAL_IPS = ['127.0.0.1', *map(str, ipaddress.ip_network('172.0.0.0/24'))]
Granted for 172.0.0.0/8
this is a bad idea, but then you should probably constrain your range of addresses!
comment:13 by , 5 years ago
Right, your solution is much easier. Thanks!
Replying to Nick Pope:
Replying to Fabian Köster:
Why overcomplicate things? You can do the following without any custom classes:
import ipaddress INTERNAL_IPS = ['127.0.0.1', *map(str, ipaddress.ip_network('172.0.0.0/24'))]Granted for
172.0.0.0/8
this is a bad idea, but then you should probably constrain your range of addresses!
code, un-hosed: