From b3d13d2f7084358db7da6d1609bfccb639ee4c4c Mon Sep 17 00:00:00 2001 From: Georgy Okrokvertskhov Date: Tue, 1 Jul 2014 17:20:52 -0700 Subject: [PATCH] Fix topology page issue with deps and images Topology page now shows dependencies between apps or networks Add app images to topology page Show real app images instead of dummy app icon. Change-Id: Ia8c1588239a4d6ea185866f0dd536f2c18178761 Closes-Bug: #1336587 Closes-Bug: #1336587 --- muranodashboard/environments/api.py | 2 +- muranodashboard/environments/topology.py | 66 +++++++++++++----- .../static/muranodashboard/images/ext-net.png | Bin 0 -> 45095 bytes .../js/horizon.muranotopology.js | 12 +++- .../templates/services/_network_info.html | 3 + 5 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 muranodashboard/static/muranodashboard/images/ext-net.png create mode 100644 muranodashboard/templates/services/_network_info.html diff --git a/muranodashboard/environments/api.py b/muranodashboard/environments/api.py index 1e4b529b3..12dd10334 100644 --- a/muranodashboard/environments/api.py +++ b/muranodashboard/environments/api.py @@ -314,4 +314,4 @@ def get_deployment_descr(request, environment_id, deployment_id): def load_environment_data(request, environment_id): environment = environment_get(request, environment_id) - return topology.render_d3_data(environment) + return topology.render_d3_data(request, environment) diff --git a/muranodashboard/environments/topology.py b/muranodashboard/environments/topology.py index 22bb7ad2c..768b1fba0 100644 --- a/muranodashboard/environments/topology.py +++ b/muranodashboard/environments/topology.py @@ -16,8 +16,20 @@ import json import types from django.contrib.staticfiles.templatetags.staticfiles import static +from django.core.urlresolvers import reverse from django.template import loader +from muranodashboard.api import packages as pkg_cli + + +def get_app_image(request, app_fqdn): + package = pkg_cli.app_by_fqn(request, app_fqdn) + url = static('dashboard/img/stack-green.svg') + if package: + app_id = package.id + url = reverse("horizon:murano:catalog:images", args=(app_id,)) + return url + def _get_environment_status_message(entity): if hasattr(entity, 'status'): @@ -62,6 +74,13 @@ def _application_info(application, app_image, status): context) +def _network_info(name, image): + context = {'name': name, + 'image': image} + return loader.render_to_string('services/_network_info.html', + context) + + def _unit_info(unit, unit_image): data = dict(unit) data['type'] = _truncate_type(data['type'], 45) @@ -98,9 +117,12 @@ def _create_empty_node(): def _create_ext_network_node(name): node = _create_empty_node() - node.update({'name': name, - 'image': static('dashboard/img/lb-green.svg'), - 'link_type': 'relation'}) + node.update({'id': name, + 'image': static('muranodashboard/images/ext-net.png'), + 'link_type': 'relation', + 'info_box': _network_info(name, static( + 'dashboard/img/lb-green.svg'))} + ) return node @@ -119,7 +141,16 @@ def _is_atomic(elt): return not isinstance(value, (types.DictType, types.ListType)) -def render_d3_data(environment): +def check_service_references(node, node_data, srv_list): + node_id = node_data['?']['id'] + for service in srv_list: + for k, v in service.iteritems(): + if v == node_id: + node['required_by'].append(service['?']['id']) + node['link_type'] = 'relation' + + +def render_d3_data(request, environment): if not environment: return None @@ -138,34 +169,36 @@ def render_d3_data(environment): }) d3_data['environment'] = environment_node - service_image = static('dashboard/img/stack-green.svg') unit_image = static('dashboard/img/server-green.svg') for service in environment.services: in_progress, status_message = _get_environment_status_message(service) required_by = None - if hasattr(service, 'assignFloatingIP'): - if ext_net_name: - required_by = ext_net_name - else: - ext_net_name = 'External_Network' - ext_network_node = _create_ext_network_node(ext_net_name) - d3_data['nodes'].append(ext_network_node) - required_by = ext_net_name + if 'instance' in service: + if service['instance'].get('assignFloatingIp', False): + if ext_net_name: + required_by = ext_net_name + else: + ext_net_name = 'External_Network' + ext_network_node = _create_ext_network_node(ext_net_name) + d3_data['nodes'].append(ext_network_node) + required_by = ext_net_name service_node = _create_empty_node() + service_image = get_app_image(request, service['?']['type']) service_node.update({ 'name': service.get('name', ''), 'status': status_message, 'image': service_image, 'id': service['?']['id'], - 'link_type': 'unit', + 'link_type': 'relation', 'in_progress': in_progress, 'info_box': _application_info( service, service_image, status_message) }) if required_by: - service_node['required_by'] = [required_by] + service_node['required_by'].append(required_by) + check_service_references(service_node, service, environment.services) d3_data['nodes'].append(service_node) def rec(node_data, node_key, parent_node=None): @@ -180,7 +213,8 @@ def render_d3_data(environment): ('type', node_type), ('name', node_data.get('name', node_key))]) if parent_node is not None: - node['required_by'] = [parent_node['?']['id']] + node['required_by'].append(parent_node['?']['id']) + node.update({ 'id': node_data['?']['id'], 'info_box': _unit_info(atomics, unit_image), diff --git a/muranodashboard/static/muranodashboard/images/ext-net.png b/muranodashboard/static/muranodashboard/images/ext-net.png new file mode 100644 index 0000000000000000000000000000000000000000..d9583ee3531cfee0bc81fba822be35de8e6374db GIT binary patch literal 45095 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
OfnUb@G?FZ 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 z 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 literal 0 HcmV?d00001 diff --git a/muranodashboard/static/muranodashboard/js/horizon.muranotopology.js b/muranodashboard/static/muranodashboard/js/horizon.muranotopology.js index 764d5fe0c..ffa990ec7 100644 --- a/muranodashboard/static/muranodashboard/js/horizon.muranotopology.js +++ b/muranodashboard/static/muranodashboard/js/horizon.muranotopology.js @@ -36,13 +36,16 @@ function update(){ .attr("node_id", function(d) { return d.id; }) .call(force.drag); + + nodeEnter.append("image") .attr("xlink:href", function(d) { return d.image; }) .attr("id", function(d){ return "image_"+ d.id; }) .attr("x", function(d) { return d.image_x; }) .attr("y", function(d) { return d.image_y; }) .attr("width", function(d) { return d.image_size; }) - .attr("height", function(d) { return d.image_size; }); + .attr("height", function(d) { return d.image_size; }) + .attr("clip-path","url(#clipCircle)"); node.exit().remove(); link.enter().insert("path", "g.node") @@ -175,7 +178,7 @@ function build_reverse_links(node){ 'source':findNodeIndex(nodes[i].id), 'target':findNodeIndex(node.id), 'value':1, - 'link_type': node.link_type + 'link_type': nodes[i].link_type }); } } @@ -273,6 +276,11 @@ if ($(murano_container).length){ needs_update = false, nodes = force.nodes(), links = force.links(); + svg.append("svg:clipPath") + .attr("id","clipCircle") + .append("svg:circle") + .attr("cursor","pointer") + .attr("r", "28px"); build_links(); update(); diff --git a/muranodashboard/templates/services/_network_info.html b/muranodashboard/templates/services/_network_info.html new file mode 100644 index 000000000..52715d1c4 --- /dev/null +++ b/muranodashboard/templates/services/_network_info.html @@ -0,0 +1,3 @@ + + +

Name: {{ name }}