Skip to content
This repository has been archived by the owner on Jun 27, 2020. It is now read-only.

Commit

Permalink
Merge e35d990 into a4bd9c6
Browse files Browse the repository at this point in the history
  • Loading branch information
Weirdo914 authored Dec 30, 2019
2 parents a4bd9c6 + e35d990 commit 3a65cf3
Show file tree
Hide file tree
Showing 21 changed files with 178 additions and 113 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ __pycache__/

# Distribution / packaging
.Python
venv/
env/
build/
develop-eggs/
Expand Down Expand Up @@ -54,6 +55,7 @@ target/
# editors
*.komodoproject
*.komodotools
.vscode/

# other
*.DS_Store*
Expand Down
2 changes: 1 addition & 1 deletion django_netjsongraph/base/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def visualize_view(self, request, pk):


class AbstractNodeAdmin(BaseAdmin):
list_display = ['name', 'topology', 'addresses']
list_display = ['name', 'topology', 'view_addresses']
list_filter = ['topology']
search_fields = ['addresses', 'label', 'properties']

Expand Down
10 changes: 4 additions & 6 deletions django_netjsongraph/base/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,10 @@ def get_from_nodes(cls, source, target, topology):
:param topology: Topology instance
:returns: Link object or None
"""
source = ';{0};'.format(source)
target = ';{0};'.format(target)
q = (Q(source__addresses__contains=source,
target__addresses__contains=target) |
Q(source__addresses__contains=target,
target__addresses__contains=source))
q = (Q(source__addresses__address=source,
target__addresses__address=target) |
Q(source__addresses__address=target,
target__addresses__address=source))
return cls.objects.filter(q).filter(topology=topology).first()

@classmethod
Expand Down
59 changes: 21 additions & 38 deletions django_netjsongraph/base/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@
from django.utils.timezone import now
from jsonfield import JSONField
from rest_framework.utils.encoders import JSONEncoder
from sortedm2m.fields import SortedManyToManyField

from .. import settings
from ..utils import print_info
from .base import TimeStampedEditableModel


class Address(models.Model):
address = models.GenericIPAddressField(primary_key=True)


@python_2_unicode_compatible
class AbstractNode(TimeStampedEditableModel):
"""
Expand All @@ -23,7 +28,7 @@ class AbstractNode(TimeStampedEditableModel):
on_delete=models.CASCADE)
label = models.CharField(max_length=64, blank=True)
# netjson ID and local_addresses
addresses = models.CharField(max_length=510, db_index=True)
addresses = SortedManyToManyField(Address)
properties = JSONField(default=dict,
blank=True,
load_kwargs={'object_pairs_hook': OrderedDict},
Expand All @@ -40,50 +45,30 @@ def clean(self):
self.properties = {}

def save(self, *args, **kwargs):
self._format_addresses()
super(AbstractNode, self).save(*args, **kwargs)

def _format_addresses(self):
"""
Ensure address format is correct: ";addr1;addr2;addr3;"
"""
self.addresses = self.addresses.replace(',', ';')\
.replace(' ', '')\
.replace(';', ';')
if not self.addresses.startswith(';'):
self.addresses = ';' + self.addresses
if not self.addresses.endswith(';'):
self.addresses += ';'

def truncate_addresses(self):
"""
ensures "addresses" field is not too long
"""
max_length = self._meta.get_field('addresses').max_length
if len(self.addresses) <= max_length:
return
addresses = self.address_list
# +1 stands for the character added in self._format_address()
while len(';'.join(addresses)) + 2 > max_length:
addresses.pop()
self.addresses = ';'.join(addresses)
def view_addresses(self):
return "\n".join(self.address_list)

@cached_property
def address_list(self):
addresses = self.addresses.replace(' ', '')
if addresses.startswith(';'):
addresses = addresses[1:]
return addresses[0:-1].split(';')
addresses_array = []
for address in list(self.addresses.all()):
addresses_array.append(address.address)
return addresses_array

@property
def netjson_id(self):
if self.addresses:
return self.address_list[0]
if self.addresses.count():
return self.addresses.first().address

@cached_property
def local_addresses(self):
if self.addresses and len(self.address_list) > 1:
return self.address_list[1:]
if self.addresses.count() > 1:
local_addresses_array = []
for address in (list(self.addresses.all())[1:]):
local_addresses_array.append(address.address)
return local_addresses_array

@property
def name(self):
Expand Down Expand Up @@ -114,9 +99,8 @@ def get_from_address(cls, address, topology):
:param topology: Topology instance
:returns: Node object or None
"""
address = ';{0};'.format(address)
return cls.objects.filter(topology=topology,
addresses__contains=address).first()
addresses__address=address).first()

@classmethod
def count_address(cls, address, topology):
Expand All @@ -126,9 +110,8 @@ def count_address(cls, address, topology):
:param topology: Topology instance
:returns: int
"""
address = ';{0};'.format(address)
return cls.objects.filter(topology=topology,
addresses__contains=address).count()
addresses__address=address).count()

@classmethod
def delete_expired_nodes(cls):
Expand Down
20 changes: 17 additions & 3 deletions django_netjsongraph/base/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from ..settings import PARSERS, TIMEOUT
from ..utils import get_random_key, print_info
from .base import TimeStampedEditableModel
from .node import Address

STRATEGIES = (
('fetch', _('FETCH')),
Expand Down Expand Up @@ -169,7 +170,21 @@ def json(self, dict=False, omit_down=False, **kwargs):
def _create_node(self, **kwargs):
options = dict(topology=self)
options.update(kwargs)
addresses = options.get('addresses', None)
if addresses is not None:
options.__delitem__('addresses')
node = self.node_model(**options)
node.full_clean()
node.save()
if isinstance(addresses, list):
for address in addresses:
address_obj = Address(address)
address_obj.save()
node.addresses.add(address_obj)
elif isinstance(addresses, str):
address = Address(addresses)
address.save()
node.addresses.add(address)
return node

def _create_link(self, **kwargs):
Expand Down Expand Up @@ -208,14 +223,13 @@ def update(self, data=None):
if node: # pragma no cover
continue
# if node doesn't exist create new
addresses = '{0};'.format(node_dict['id'])
addresses += ';'.join(node_dict.get('local_addresses', []))
addresses = [node_dict['id']]
addresses += node_dict.get('local_addresses', [])
properties = node_dict.get('properties', {})
node = self._create_node(addresses=addresses,
properties=properties)
if 'label' in node_dict:
node.label = node_dict.get('label')
node.truncate_addresses()
node.full_clean()
node.save()

Expand Down
4 changes: 2 additions & 2 deletions django_netjsongraph/fixtures/test_nodes.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"fields":{
"label":"node1",
"topology":"a083b494-8e16-4054-9537-fb9eba914861",
"addresses": "192.168.0.1;",
"addresses": "192.168.0.1",
"created":"2015-05-16T20:02:52.483Z",
"modified":"2015-05-16T19:33:41.621Z",
"properties": {}
Expand All @@ -17,7 +17,7 @@
"fields":{
"label":"node2",
"topology":"a083b494-8e16-4054-9537-fb9eba914861",
"addresses": "192.168.0.2;",
"addresses": "192.168.0.2",
"created":"2015-05-16T20:02:52.483Z",
"modified":"2015-05-16T19:33:41.621Z",
"properties": {}
Expand Down
30 changes: 30 additions & 0 deletions django_netjsongraph/migrations/0008_node_address_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 2.2.9 on 2019-12-21 18:51

from django.db import migrations, models
import sortedm2m.fields


class Migration(migrations.Migration):

dependencies = [
('django_netjsongraph', '0007_link_status_changed'),
]

operations = [
migrations.CreateModel(
name='Address',
fields=[
('address', models.GenericIPAddressField(primary_key=True, serialize=False)),
],
),
migrations.RenameField(
model_name='node',
old_name='addresses',
new_name='addresses_old',
),
migrations.AddField(
model_name='node',
name='addresses',
field=sortedm2m.fields.SortedManyToManyField(help_text=None, to='django_netjsongraph.Address'),
),
]
27 changes: 27 additions & 0 deletions django_netjsongraph/migrations/0009_transfer_addresses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 2.2.9 on 2019-12-30 07:29

from django.db import migrations

def link_nodes(apps, schema_editor):
Node = apps.get_model('django_netjsongraph', 'Node')
Address = apps.get_model('django_netjsongraph', 'Address')
for node in Node.objects.all():
addresses = node.addresses_old.replace(' ', '')
if addresses.startswith(';'):
addresses = addresses[1:]
addresses = addresses[0:-1].split(';')
for address in addresses:
address, created = Address.objects.get_or_create(address=address)
node.addresses.add(address)
node.save()


class Migration(migrations.Migration):

dependencies = [
('django_netjsongraph', '0008_node_address_link'),
]

operations = [
migrations.RunPython(link_nodes)
]
18 changes: 18 additions & 0 deletions django_netjsongraph/migrations/0010_rename_node_addresses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.9 on 2019-12-30 07:45

from django.db import migrations
import sortedm2m.fields


class Migration(migrations.Migration):

dependencies = [
('django_netjsongraph', '0009_transfer_addresses'),
]

operations = [
migrations.RemoveField(
model_name='node',
name='addresses_old',
),
]
17 changes: 16 additions & 1 deletion django_netjsongraph/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from ..base.node import Address


class CreateGraphObjectsMixin(object):
def _create_topology(self, **kwargs):
options = dict(label='TestNetwork',
Expand All @@ -17,14 +20,26 @@ def _create_topology(self, **kwargs):

def _create_node(self, **kwargs):
options = dict(label='TestNode',
addresses='192.168.0.1;',
addresses='192.168.0.1',
created='2017-07-10T20:02:52.483Z',
modified='2017-07-14T20:02:52.483Z',
properties={})
options.update(kwargs)
addresses = options.get('addresses', None)
if addresses is not None:
options.__delitem__('addresses')
n = self.node_model(**options)
n.full_clean()
n.save()
if isinstance(addresses, list):
for address in addresses:
address_obj = Address(address)
address_obj.save()
n.addresses.add(address_obj)
elif isinstance(addresses, str):
address = Address(addresses)
address.save()
n.addresses.add(address)
return n

def _create_link(self, **kwargs):
Expand Down
Loading

0 comments on commit 3a65cf3

Please sign in to comment.