Skip to content

Commit

Permalink
Merge 2980539 into af5ad60
Browse files Browse the repository at this point in the history
  • Loading branch information
atb00ker committed Jun 25, 2020
2 parents af5ad60 + 2980539 commit 188701a
Show file tree
Hide file tree
Showing 19 changed files with 306 additions and 91 deletions.
46 changes: 46 additions & 0 deletions .jslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"predef": [
"document",
"navigator",
"console",
"alert",
"django",
"gettext"
],
"adsafe": false,
"safe": false,
"bitwise": false,
"cap": false,
"confusion": true,
"continue": true,
"css": true,
"debug": false,
"eqeq": false,
"es5": true,
"evil": false,
"forin": false,
"fragment": true,
"newcap": false,
"nomen": false,
"on": false,
"plusplus": false,
"regexp": true,
"sloppy": false,
"sub": false,
"undef": false,
"unparam": true,
"vars": true,
"white": false,
"validthis": true,
"strict_mode": true,
"browser": false,
"devel": false,
"node": false,
"rhino": false,
"widget": false,
"windows": false,
"indent": 4,
"maxerr": 50,
"maxlen": 120,
"passfail": false
}
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ before_install:
install:
- pip install $DJANGO
- python setup.py -q develop
- npm install -g jslint

script:
- ./run-qa-checks
Expand Down
8 changes: 4 additions & 4 deletions openwisp_ipam/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ def response_add(self, request, *args, **kwargs):
if request.POST.get('_popup'):
return HttpResponse(
f"""
<script type='text/javascript'>
opener.dismissAddAnotherPopup(window, '{request.POST.get('ip_address')}');
</script>
"""
<script type='text/javascript'>
opener.dismissAddAnotherPopup(window, '{request.POST.get('ip_address')}');
</script>
"""
)
return response

Expand Down
13 changes: 10 additions & 3 deletions openwisp_ipam/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
from rest_framework import pagination, serializers, status
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.generics import (
CreateAPIView, ListAPIView, ListCreateAPIView, RetrieveAPIView, RetrieveUpdateDestroyAPIView,
CreateAPIView,
ListAPIView,
ListCreateAPIView,
RetrieveAPIView,
RetrieveUpdateDestroyAPIView,
get_object_or_404,
)
from rest_framework.permissions import DjangoModelPermissions
Expand All @@ -17,7 +21,10 @@
from ..base.models import AbstractSubnet, CsvImportException
from .responses import HostsResponse
from .serializers import (
HostsResponseSerializer, ImportSubnetSerializer, IpAddressSerializer, IpRequestSerializer,
HostsResponseSerializer,
ImportSubnetSerializer,
IpAddressSerializer,
IpRequestSerializer,
SubnetSerializer,
)

Expand All @@ -40,7 +47,7 @@ def paginate_queryset(self, queryset, request, view=None):
self.queryset = queryset
self.request = request
self.offset = self.get_offset(request)
return list(queryset[self.offset: self.offset + self.limit])
return list(queryset[self.offset : self.offset + self.limit])

def get_paginated_response(self, data):
return Response(
Expand Down
11 changes: 8 additions & 3 deletions openwisp_ipam/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ def patch_ipaddress_lib():
On python < 3.7, the ipaddress library does not have
the method ``subnet_of``, so we add it via monkey patching
"""

def _is_subnet_of(a, b):
try:
# Always false if one is v4 and the other is v6
if a._version != b._version:
raise TypeError("%s and %s are not of the same version" % (a, b))
return (b.network_address <= a.network_address and b.broadcast_address >= a.broadcast_address)
return (
b.network_address <= a.network_address
and b.broadcast_address >= a.broadcast_address
)
except AttributeError:
raise TypeError("Unable to test subnet containment "
"between %s and %s" % (a, b))
raise TypeError(
"Unable to test subnet containment " "between %s and %s" % (a, b)
)

def subnet_of(self, other):
""" Return True if this network is a subnet of other """
Expand Down
4 changes: 3 additions & 1 deletion openwisp_ipam/management/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ def handle(self, *args, **options):
except self.subnet_model.DoesNotExist:
raise CommandError(_('Subnet "%s" does not exist' % subnet))
except ValueError:
raise CommandError(_("'%s' does not appear to be an IPv4 or IPv6 network" % subnet))
raise CommandError(
_("'%s' does not appear to be an IPv4 or IPv6 network" % subnet)
)
with open('data_{0}.csv'.format(instance.id), 'w+') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
instance.export_csv(instance.id, writer)
Expand Down
109 changes: 90 additions & 19 deletions openwisp_ipam/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,112 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='IpAddress',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
(
'id',
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
'created',
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now,
editable=False,
verbose_name='created',
),
),
(
'modified',
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now,
editable=False,
verbose_name='modified',
),
),
('ip_address', models.GenericIPAddressField()),
('description', models.CharField(blank=True, max_length=100)),
('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='openwisp_users.Organization', verbose_name='organization')),
(
'organization',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
verbose_name='organization',
),
),
],
options={
'abstract': False,
'swappable': 'OPENWISP_IPAM_IPADDRESS_MODEL',
},
options={'abstract': False, 'swappable': 'OPENWISP_IPAM_IPADDRESS_MODEL',},
bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model),
),
migrations.CreateModel(
name='Subnet',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
(
'id',
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
'created',
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now,
editable=False,
verbose_name='created',
),
),
(
'modified',
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now,
editable=False,
verbose_name='modified',
),
),
('name', models.CharField(blank=True, db_index=True, max_length=100)),
('subnet', openwisp_ipam.base.fields.NetworkField(db_index=True, help_text='Subnet in CIDR notation, eg: "10.0.0.0/24" for IPv4 and "fdb6:21b:a477::9f7/64" for IPv6', max_length=43)),
(
'subnet',
openwisp_ipam.base.fields.NetworkField(
db_index=True,
help_text='Subnet in CIDR notation, eg: "10.0.0.0/24" for IPv4 and "fdb6:21b:a477::9f7/64" for IPv6',
max_length=43,
),
),
('description', models.CharField(blank=True, max_length=100)),
('master_subnet', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_subnet_set', to=settings.OPENWISP_IPAM_SUBNET_MODEL)),
('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='openwisp_users.Organization', verbose_name='organization')),
(
'master_subnet',
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name='child_subnet_set',
to=settings.OPENWISP_IPAM_SUBNET_MODEL,
),
),
(
'organization',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
verbose_name='organization',
),
),
],
options={
'abstract': False,
'swappable': 'OPENWISP_IPAM_SUBNET_MODEL',
},
options={'abstract': False, 'swappable': 'OPENWISP_IPAM_SUBNET_MODEL',},
bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model),
),
migrations.AddField(
model_name='ipaddress',
name='subnet',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.OPENWISP_IPAM_SUBNET_MODEL),
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.OPENWISP_IPAM_SUBNET_MODEL,
),
),
migrations.AddIndex(
model_name='subnet',
Expand Down
27 changes: 8 additions & 19 deletions openwisp_ipam/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,10 @@ def test_subnet_popup_response(self):
subnet='fdb6:21b:a477::9f7/64', description='Sample Subnet'
)
self._create_ipaddress(ip_address='fdb6:21b:a477::9f7', subnet=subnet)
change_path = reverse('admin:{0}_subnet_change'.format(self.app_label), args=[subnet.id])
response = self.client.get(
f'{change_path}?_popup=1',
follow=True,
change_path = reverse(
'admin:{0}_subnet_change'.format(self.app_label), args=[subnet.id]
)
response = self.client.get(f'{change_path}?_popup=1', follow=True,)
self.assertContains(response, 'ok')

def test_add_ipaddress_response(self):
Expand Down Expand Up @@ -187,9 +186,7 @@ def test_csv_upload(self):
10.27.1.254,Nano Beam 5 19AC"""
csvfile = SimpleUploadedFile('data.csv', bytes(csv_data, 'utf-8'))
response = self.client.post(
reverse('admin:ipam_import_subnet'.format(self.app_label)),
{'csvfile': csvfile},
follow=True,
reverse('admin:ipam_import_subnet'), {'csvfile': csvfile}, follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(str(Subnet.objects.first().subnet), '10.27.1.0/24')
Expand All @@ -213,9 +210,7 @@ def test_existing_csv_data(self):
10.27.1.254,Nano Beam 5 19AC"""
csvfile = SimpleUploadedFile('data.csv', bytes(csv_data, 'utf-8'))
response = self.client.post(
reverse('admin:ipam_import_subnet'.format(self.app_label)),
{'csvfile': csvfile},
follow=True,
reverse('admin:ipam_import_subnet'), {'csvfile': csvfile}, follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(str(IpAddress.objects.all()[1].ip_address), '10.27.1.252')
Expand All @@ -233,9 +228,7 @@ def test_invalid_file_type(self):
10.27.1.254,Nano Beam 5 19AC"""
csvfile = SimpleUploadedFile('data.txt', bytes(csv_data, 'utf-8'))
response = self.client.post(
reverse('admin:ipam_import_subnet'.format(self.app_label)),
{'csvfile': csvfile},
follow=True,
reverse('admin:ipam_import_subnet'), {'csvfile': csvfile}, follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'File type not supported.')
Expand All @@ -251,9 +244,7 @@ def test_invalid_subnet_csv_data(self):
10.27.1.254,Nano Beam 5 19AC"""
csvfile = SimpleUploadedFile('data.csv', bytes(csv_data, 'utf-8'))
response = self.client.post(
reverse('admin:ipam_import_subnet'.format(self.app_label)),
{'csvfile': csvfile},
follow=True,
reverse('admin:ipam_import_subnet'), {'csvfile': csvfile}, follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'does not appear to be an IPv4 or IPv6 network')
Expand All @@ -270,9 +261,7 @@ def test_invalid_ipaddress_csv_data(self):
10.27.1.254,Nano Beam 5 19AC"""
csvfile = SimpleUploadedFile('data.csv', bytes(csv_data, 'utf-8'))
response = self.client.post(
reverse('admin:ipam_import_subnet'.format(self.app_label)),
{'csvfile': csvfile},
follow=True,
reverse('admin:ipam_import_subnet'), {'csvfile': csvfile}, follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'does not appear to be an IPv4 or IPv6 address')
Expand Down
5 changes: 4 additions & 1 deletion openwisp_ipam/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ def test_invalid_ipaddress_subnet(self):
try:
self._create_ipaddress(ip_address='10.0.0.2', subnet=Subnet.objects.first())
except ValidationError as e:
self.assertTrue(e.message_dict['ip_address'] == ['IP address does not belong to the subnet'])
self.assertTrue(
e.message_dict['ip_address']
== ['IP address does not belong to the subnet']
)
else:
self.fail('ValidationError not raised')

Expand Down
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
coveralls
django-extensions>=2.0.7
openwisp-utils[qa]>=0.4.1
openwisp-utils[qa]~=0.5.0
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
openwisp-users~=0.2.0
openwisp-utils~=0.4.0
openwisp-utils~=0.5.0
django>=2.2,<3.1
djangorestframework>=3.7,<3.12
swapper~=1.1
Expand Down
10 changes: 8 additions & 2 deletions run-qa-checks
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

set -e

openwisp-utils-qa-checks \
echo ''
echo 'Check JavaScript Linting'
jslint ./openwisp_ipam/static/openwisp-ipam/js/*.js

echo ''
echo 'Running checks for openwisp_ipam'
openwisp-qa-check \
--migration-path ./openwisp_ipam/migrations/ \
--migration-module openwisp_ipam

echo ''
echo 'Running checks for SAMPLE_APP'

SAMPLE_APP=1 openwisp-utils-qa-checks \
SAMPLE_APP=1 openwisp-qa-check \
--skip-isort \
--skip-flake8 \
--skip-checkmigrations \
Expand Down
1 change: 1 addition & 0 deletions runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

if __name__ == "__main__":
from django.core.management import execute_from_command_line

args = sys.argv
args.insert(1, "test")
if not os.environ.get('SAMPLE_APP', False):
Expand Down

0 comments on commit 188701a

Please sign in to comment.