1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-01 16:51:11 +03:00

Updates models based on PR feedback from matburt et al.

* Moves topology_data to views
* Changes id to cid
* Changes pk to id
* Changes host_id and inventory_id to ForeignKeys
* Resets migrations for network_ui
* Cleans up old files
This commit is contained in:
Ben Thomasson 2018-03-22 19:00:32 -04:00
parent 883545d4cb
commit 38eb2691a8
No known key found for this signature in database
GPG Key ID: 5818EF4CC895D5F5
14 changed files with 152 additions and 209 deletions

View File

@ -1,5 +1,4 @@
# Copyright (c) 2017 Red Hat, Inc
# In consumers.py
from channels import Group, Channel
from channels.sessions import channel_session
from awx.network_ui.models import Topology, Device, Link, Client, Interface
@ -13,7 +12,6 @@ import logging
from awx.network_ui.utils import transform_dict
import json
# Connected to websocket.connect
logger = logging.getLogger("awx.network_ui.consumers")
@ -31,7 +29,14 @@ def parse_inventory_id(data):
class Persistence(object):
'''
Provides database persistence for the topology canvas.
'''
def parse_message_text(self, message_text, client_id):
'''
See the Messages of CONTRIBUTING.md for the message format.
'''
data = json.loads(message_text)
if len(data) == 2:
message_type = data.pop(0)
@ -48,6 +53,10 @@ class Persistence(object):
return None, None
def handle(self, message):
'''
Dispatches a message based on the message type to a handler function
of name onX where X is the message type.
'''
topology_id = message.get('topology')
assert topology_id is not None, "No topology_id"
client_id = message.get('client')
@ -73,83 +82,83 @@ class Persistence(object):
y='y',
name='name',
type='device_type',
id='id',
id='cid',
host_id='host_id'), device)
logger.info("Device %s", device)
d, _ = Device.objects.get_or_create(topology_id=topology_id, id=device['id'], defaults=device)
d, _ = Device.objects.get_or_create(topology_id=topology_id, cid=device['cid'], defaults=device)
d.x = device['x']
d.y = device['y']
d.device_type = device['device_type']
d.host_id = device['host_id']
d.save()
(Topology.objects
.filter(topology_id=topology_id, device_id_seq__lt=device['id'])
.update(device_id_seq=device['id']))
.filter(pk=topology_id, device_id_seq__lt=device['cid'])
.update(device_id_seq=device['cid']))
def onDeviceDestroy(self, device, topology_id, client_id):
Device.objects.filter(topology_id=topology_id, id=device['id']).delete()
Device.objects.filter(topology_id=topology_id, cid=device['id']).delete()
def onDeviceMove(self, device, topology_id, client_id):
Device.objects.filter(topology_id=topology_id, id=device['id']).update(x=device['x'], y=device['y'])
Device.objects.filter(topology_id=topology_id, cid=device['id']).update(x=device['x'], y=device['y'])
def onDeviceInventoryUpdate(self, device, topology_id, client_id):
Device.objects.filter(topology_id=topology_id, id=device['id']).update(host_id=device['host_id'])
Device.objects.filter(topology_id=topology_id, cid=device['id']).update(host_id=device['host_id'])
def onDeviceLabelEdit(self, device, topology_id, client_id):
Device.objects.filter(topology_id=topology_id, id=device['id']).update(name=device['name'])
Device.objects.filter(topology_id=topology_id, cid=device['id']).update(name=device['name'])
def onInterfaceLabelEdit(self, interface, topology_id, client_id):
(Interface.objects
.filter(device__topology_id=topology_id,
id=interface['id'],
device__id=interface['device_id'])
cid=interface['id'],
device__cid=interface['device_id'])
.update(name=interface['name']))
def onLinkLabelEdit(self, link, topology_id, client_id):
Link.objects.filter(from_device__topology_id=topology_id, id=link['id']).update(name=link['name'])
Link.objects.filter(from_device__topology_id=topology_id, cid=link['id']).update(name=link['name'])
def onInterfaceCreate(self, interface, topology_id, client_id):
Interface.objects.get_or_create(device_id=Device.objects.get(id=interface['device_id'],
Interface.objects.get_or_create(device_id=Device.objects.get(cid=interface['device_id'],
topology_id=topology_id).pk,
id=interface['id'],
cid=interface['id'],
defaults=dict(name=interface['name']))
(Device.objects
.filter(id=interface['device_id'],
.filter(cid=interface['device_id'],
topology_id=topology_id,
interface_id_seq__lt=interface['id'])
.update(interface_id_seq=interface['id']))
def onLinkCreate(self, link, topology_id, client_id):
device_map = dict(Device.objects
.filter(topology_id=topology_id, id__in=[link['from_device_id'], link['to_device_id']])
.values_list('id', 'pk'))
Link.objects.get_or_create(id=link['id'],
.filter(topology_id=topology_id, cid__in=[link['from_device_id'], link['to_device_id']])
.values_list('cid', 'pk'))
Link.objects.get_or_create(cid=link['id'],
name=link['name'],
from_device_id=device_map[link['from_device_id']],
to_device_id=device_map[link['to_device_id']],
from_interface_id=Interface.objects.get(device_id=device_map[link['from_device_id']],
id=link['from_interface_id']).pk,
cid=link['from_interface_id']).pk,
to_interface_id=Interface.objects.get(device_id=device_map[link['to_device_id']],
id=link['to_interface_id']).pk)
cid=link['to_interface_id']).pk)
(Topology.objects
.filter(topology_id=topology_id, link_id_seq__lt=link['id'])
.filter(pk=topology_id, link_id_seq__lt=link['id'])
.update(link_id_seq=link['id']))
def onLinkDestroy(self, link, topology_id, client_id):
device_map = dict(Device.objects
.filter(topology_id=topology_id, id__in=[link['from_device_id'], link['to_device_id']])
.values_list('id', 'pk'))
.filter(topology_id=topology_id, cid__in=[link['from_device_id'], link['to_device_id']])
.values_list('cid', 'pk'))
if link['from_device_id'] not in device_map:
return
if link['to_device_id'] not in device_map:
return
Link.objects.filter(id=link['id'],
Link.objects.filter(cid=link['id'],
from_device_id=device_map[link['from_device_id']],
to_device_id=device_map[link['to_device_id']],
from_interface_id=Interface.objects.get(device_id=device_map[link['from_device_id']],
id=link['from_interface_id']).pk,
cid=link['from_interface_id']).pk,
to_interface_id=Interface.objects.get(device_id=device_map[link['to_device_id']],
id=link['to_interface_id']).pk).delete()
cid=link['to_interface_id']).pk).delete()
def onDeviceSelected(self, message_value, topology_id, client_id):
'Ignore DeviceSelected messages'
@ -178,20 +187,19 @@ class Persistence(object):
@channel_session
def ws_connect(message):
# Accept connection
data = urlparse.parse_qs(message.content['query_string'])
inventory_id = parse_inventory_id(data)
topology_ids = list(TopologyInventory.objects.filter(inventory_id=inventory_id).values_list('topology_id', flat=True))
topology_ids = list(TopologyInventory.objects.filter(inventory_id=inventory_id).values_list('pk', flat=True))
topology_id = None
if len(topology_ids) > 0:
topology_id = topology_ids[0]
if topology_id is not None:
topology = Topology.objects.get(topology_id=topology_id)
topology = Topology.objects.get(pk=topology_id)
else:
topology = Topology(name="topology", scale=1.0, panX=0, panY=0)
topology.save()
TopologyInventory(inventory_id=inventory_id, topology_id=topology.topology_id).save()
topology_id = topology.topology_id
TopologyInventory(inventory_id=inventory_id, topology_id=topology.pk).save()
topology_id = topology.pk
message.channel_session['topology_id'] = topology_id
Group("topology-%s" % topology_id).add(message.reply_channel)
client = Client()
@ -200,7 +208,7 @@ def ws_connect(message):
Group("client-%s" % client.pk).add(message.reply_channel)
message.reply_channel.send({"text": json.dumps(["id", client.pk])})
message.reply_channel.send({"text": json.dumps(["topology_id", topology_id])})
topology_data = transform_dict(dict(topology_id='topology_id',
topology_data = transform_dict(dict(id='topology_id',
name='name',
panX='panX',
panY='panY',
@ -218,26 +226,38 @@ def send_snapshot(channel, topology_id):
for i in (Interface.objects
.filter(device__topology_id=topology_id)
.values()):
i = transform_dict(dict(cid='id',
device_id='device_id',
id='interface_id',
name='name'), i)
interfaces[i['device_id']].append(i)
devices = list(Device.objects.filter(topology_id=topology_id).values())
devices = [transform_dict(dict(cid='id',
id='device_id',
device_type='device_type',
host_id='host_id',
name='name',
x='x',
y='y',
interface_id_seq='interface_id_seq'), x) for x in devices]
for device in devices:
device['interfaces'] = interfaces[device['device_id']]
links = [dict(id=x['id'],
links = [dict(id=x['cid'],
name=x['name'],
from_device_id=x['from_device__id'],
to_device_id=x['to_device__id'],
from_interface_id=x['from_interface__id'],
to_interface_id=x['to_interface__id'])
from_device_id=x['from_device__cid'],
to_device_id=x['to_device__cid'],
from_interface_id=x['from_interface__cid'],
to_interface_id=x['to_interface__cid'])
for x in list(Link.objects
.filter(Q(from_device__topology_id=topology_id) |
Q(to_device__topology_id=topology_id))
.values('id',
.values('cid',
'name',
'from_device__id',
'to_device__id',
'from_interface__id',
'to_interface__id'))]
'from_device__cid',
'to_device__cid',
'from_interface__cid',
'to_interface__cid'))]
snapshot = dict(sender=0,
devices=devices,
links=links)

View File

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 207 KiB

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2018-03-12 18:34
# Generated by Django 1.11.11 on 2018-03-23 20:43
from __future__ import unicode_literals
from django.db import migrations, models
@ -11,42 +11,43 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('main', '0026_v330_emitted_events'),
]
operations = [
migrations.CreateModel(
name='Client',
fields=[
('client_id', models.AutoField(primary_key=True, serialize=False)),
('id', models.AutoField(primary_key=True, serialize=False)),
],
),
migrations.CreateModel(
name='Device',
fields=[
('device_id', models.AutoField(primary_key=True, serialize=False)),
('id', models.AutoField(primary_key=True, serialize=False)),
('name', models.CharField(blank=True, max_length=200)),
('x', models.IntegerField()),
('y', models.IntegerField()),
('id', models.IntegerField()),
('cid', models.IntegerField()),
('device_type', models.CharField(blank=True, max_length=200)),
('interface_id_seq', models.IntegerField(default=0)),
('host_id', models.IntegerField(default=0)),
('host', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.Host')),
],
),
migrations.CreateModel(
name='Interface',
fields=[
('interface_id', models.AutoField(primary_key=True, serialize=False)),
('id', models.AutoField(primary_key=True, serialize=False)),
('name', models.CharField(blank=True, max_length=200)),
('id', models.IntegerField()),
('cid', models.IntegerField()),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Device')),
],
),
migrations.CreateModel(
name='Link',
fields=[
('link_id', models.AutoField(primary_key=True, serialize=False)),
('id', models.IntegerField()),
('id', models.AutoField(primary_key=True, serialize=False)),
('cid', models.IntegerField()),
('name', models.CharField(blank=True, max_length=200)),
('from_device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='from_link', to='network_ui.Device')),
('from_interface', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='from_link', to='network_ui.Interface')),
@ -57,7 +58,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Topology',
fields=[
('topology_id', models.AutoField(primary_key=True, serialize=False)),
('id', models.AutoField(primary_key=True, serialize=False)),
('name', models.CharField(blank=True, max_length=200)),
('scale', models.FloatField()),
('panX', models.FloatField()),
@ -69,8 +70,8 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='TopologyInventory',
fields=[
('topology_inventory_id', models.AutoField(primary_key=True, serialize=False)),
('inventory_id', models.IntegerField()),
('id', models.AutoField(primary_key=True, serialize=False)),
('inventory', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Inventory')),
('topology', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Topology')),
],
),

View File

@ -3,15 +3,15 @@ from django.db import models
class Device(models.Model):
device_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
topology = models.ForeignKey('Topology',)
name = models.CharField(max_length=200, blank=True)
x = models.IntegerField()
y = models.IntegerField()
id = models.IntegerField()
cid = models.IntegerField()
device_type = models.CharField(max_length=200, blank=True)
interface_id_seq = models.IntegerField(default=0,)
host_id = models.IntegerField(default=0,)
host = models.ForeignKey('main.Host', default=None, null=True, on_delete=models.SET_NULL)
def __unicode__(self):
return self.name
@ -19,18 +19,18 @@ class Device(models.Model):
class Link(models.Model):
link_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
from_device = models.ForeignKey('Device', related_name='from_link',)
to_device = models.ForeignKey('Device', related_name='to_link',)
from_interface = models.ForeignKey('Interface', related_name='from_link',)
to_interface = models.ForeignKey('Interface', related_name='to_link',)
id = models.IntegerField()
cid = models.IntegerField()
name = models.CharField(max_length=200, blank=True)
class Topology(models.Model):
topology_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
name = models.CharField(max_length=200, blank=True)
scale = models.FloatField()
panX = models.FloatField()
@ -44,15 +44,15 @@ class Topology(models.Model):
class Client(models.Model):
client_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
class Interface(models.Model):
interface_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
device = models.ForeignKey('Device',)
name = models.CharField(max_length=200, blank=True)
id = models.IntegerField()
cid = models.IntegerField()
def __unicode__(self):
return self.name
@ -60,6 +60,6 @@ class Interface(models.Model):
class TopologyInventory(models.Model):
topology_inventory_id = models.AutoField(primary_key=True,)
id = models.AutoField(primary_key=True,)
topology = models.ForeignKey('Topology',)
inventory_id = models.IntegerField()
inventory = models.ForeignKey('main.Inventory')

View File

@ -1,69 +0,0 @@
# Copyright (c) 2017 Red Hat, Inc
from awx.network_ui.models import Topology, Device, Link, Interface
from django.db.models import Q
import yaml
import json
NetworkAnnotatedInterface = Interface.objects.values('name',
'id',
'from_link__pk',
'to_link__pk',
'from_link__to_device__name',
'to_link__from_device__name',
'from_link__to_interface__name',
'to_link__from_interface__name')
def topology_data(topology_id):
data = dict(devices=[],
links=[])
topology = Topology.objects.get(pk=topology_id)
data['name'] = topology.name
data['topology_id'] = topology_id
links = list(Link.objects
.filter(Q(from_device__topology_id=topology_id) |
Q(to_device__topology_id=topology_id)))
interfaces = Interface.objects.filter(device__topology_id=topology_id)
for device in Device.objects.filter(topology_id=topology_id).order_by('name'):
interfaces = list(NetworkAnnotatedInterface.filter(device_id=device.pk).order_by('name'))
interfaces = [dict(name=x['name'],
network=x['from_link__pk'] or x['to_link__pk'],
remote_device_name=x['from_link__to_device__name'] or x['to_link__from_device__name'],
remote_interface_name=x['from_link__to_interface__name'] or x['to_link__from_interface__name'],
id=x['id'],
) for x in interfaces]
data['devices'].append(dict(name=device.name,
type=device.device_type,
x=device.x,
y=device.y,
id=device.id,
interfaces=interfaces))
for link in links:
data['links'].append(dict(from_device=link.from_device.name,
to_device=link.to_device.name,
from_interface=link.from_interface.name,
to_interface=link.to_interface.name,
from_device_id=link.from_device.id,
to_device_id=link.to_device.id,
from_interface_id=link.from_interface.id,
to_interface_id=link.to_interface.id,
name=link.name,
network=link.pk))
return data
def yaml_serialize_topology(topology_id):
return yaml.safe_dump(topology_data(topology_id), default_flow_style=False)
def json_serialize_topology(topology_id):
return json.dumps(topology_data(topology_id))

View File

@ -1,8 +0,0 @@
/bundle.js
/node_modules
/style.css
/css
/js
/src-instrumented
/index-instrumented.html
/extracted

View File

@ -1,47 +0,0 @@
{
"browser": true,
"node": true,
"jquery": true,
"esnext": true,
"globalstrict": true,
"curly": true,
"immed": true,
"latedef": "nofunc",
"noarg": true,
"nonew": true,
"maxerr": 10000,
"notypeof": true,
"globals": {
"$ENV": true,
"require": true,
"global": true,
"beforeEach": false,
"inject": false,
"module": false,
"angular":false,
"alert":false,
"$AnsibleConfig":true,
"$basePath":true,
"jsyaml":false,
"_":false,
"d3":false,
"Donut3D":false,
"nv":false,
"it": false,
"xit": false,
"expect": false,
"context": false,
"describe": false,
"moment": false,
"spyOn": false,
"jasmine": false
},
"strict": false,
"quotmark": false,
"trailing": true,
"undef": true,
"unused": true,
"eqeqeq": true,
"indent": 4,
"newcap": false
}

View File

@ -1,13 +0,0 @@
SERVER = "https://meganuke:8043"
PORT = "9000"
.PHONY: clean coverage
clean:
git clean -fdX .
git clean -fd .
coverage:
./coverage_report.py ${SERVER}
python -m SimpleHTTPServer ${PORT}

View File

@ -1,2 +0,0 @@
requests
docopt

View File

@ -6,5 +6,5 @@ from awx.network_ui import views
app_name = 'network_ui'
urlpatterns = [
url(r'^topology.json$', views.json_topology_data, name='json_topology_data'),
url(r'^topology.yaml$', views.yaml_topology_data, name='json_topology_data'),
url(r'^topology.yaml$', views.yaml_topology_data, name='yaml_topology_data'),
]

View File

@ -2,12 +2,73 @@
from django.shortcuts import render
from django import forms
from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse
from awx.network_ui.models import Topology
from awx.network_ui.models import Topology, Device, Link, Interface
from django.db.models import Q
import yaml
import json
NetworkAnnotatedInterface = Interface.objects.values('name',
'cid',
'from_link__pk',
'to_link__pk',
'from_link__to_device__name',
'to_link__from_device__name',
'from_link__to_interface__name',
'to_link__from_interface__name')
# Create your views here.
from .serializers import topology_data
def topology_data(topology_id):
data = dict(devices=[],
links=[])
topology = Topology.objects.get(pk=topology_id)
data['name'] = topology.name
data['topology_id'] = topology_id
links = list(Link.objects
.filter(Q(from_device__topology_id=topology_id) |
Q(to_device__topology_id=topology_id)))
interfaces = Interface.objects.filter(device__topology_id=topology_id)
for device in Device.objects.filter(topology_id=topology_id).order_by('name'):
interfaces = list(NetworkAnnotatedInterface.filter(device_id=device.pk).order_by('name'))
interfaces = [dict(name=x['name'],
network=x['from_link__pk'] or x['to_link__pk'],
remote_device_name=x['from_link__to_device__name'] or x['to_link__from_device__name'],
remote_interface_name=x['from_link__to_interface__name'] or x['to_link__from_interface__name'],
id=x['cid'],
) for x in interfaces]
data['devices'].append(dict(name=device.name,
type=device.device_type,
x=device.x,
y=device.y,
id=device.cid,
interfaces=interfaces))
for link in links:
data['links'].append(dict(from_device=link.from_device.name,
to_device=link.to_device.name,
from_interface=link.from_interface.name,
to_interface=link.to_interface.name,
from_device_id=link.from_device.cid,
to_device_id=link.to_device.cid,
from_interface_id=link.from_interface.cid,
to_interface_id=link.to_interface.cid,
name=link.name,
network=link.pk))
return data
def yaml_serialize_topology(topology_id):
return yaml.safe_dump(topology_data(topology_id), default_flow_style=False)
def json_serialize_topology(topology_id):
return json.dumps(topology_data(topology_id))
def index(request):