diff --git a/tuskar_sat_ui/nodes/panel.py b/tuskar_sat_ui/nodes/panel.py index f45f37f..0a1c02e 100644 --- a/tuskar_sat_ui/nodes/panel.py +++ b/tuskar_sat_ui/nodes/panel.py @@ -18,6 +18,7 @@ import horizon from tuskar_ui.infrastructure import dashboard from tuskar_ui.infrastructure.nodes.panel import Nodes as TuskarNodes + class Nodes(horizon.Panel): name = _("Nodes") slug = "nodes" diff --git a/tuskar_sat_ui/nodes/tables.py b/tuskar_sat_ui/nodes/tables.py new file mode 100644 index 0000000..23d8c9a --- /dev/null +++ b/tuskar_sat_ui/nodes/tables.py @@ -0,0 +1,36 @@ +# -*- coding: utf8 -*- +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from django.utils.translation import ugettext_lazy as _ +from horizon import tables + + +def get_errata_link(errata): + return "http://www.google.com" + + +class ErrataTable(tables.DataTable): + title = tables.Column('title', + link=get_errata_link, + verbose_name=_("Title")) + type = tables.Column('type', + verbose_name=_("Type")) + id = tables.Column('id', + verbose_name=_("Errata ID")) + issued = tables.Column('issued', + verbose_name=_("Date Issued")) + + class Meta: + name = "erratatable" + verbose_name = _("Errata") + template = "horizon/common/_enhanced_data_table.html" diff --git a/tuskar_sat_ui/nodes/tabs.py b/tuskar_sat_ui/nodes/tabs.py new file mode 100644 index 0000000..81ef263 --- /dev/null +++ b/tuskar_sat_ui/nodes/tabs.py @@ -0,0 +1,76 @@ +# -*- coding: utf8 -*- +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import requests +import urllib + +from collections import namedtuple +from horizon import tabs +from tuskar_ui.infrastructure.nodes import tabs as nodes_tabs +from .tables import ErrataTable + + +ErrataItem = namedtuple('ErrataItem', ['title', 'type', 'id', 'issued']) + + +class DetailOverviewTab(nodes_tabs.DetailOverviewTab): + template_name = 'infrastructure/nodes/_detail_overview_sat.html' + + def get_context_data(self, request): + result = super(DetailOverviewTab, self).get_context_data(request) + if result['node'].uuid is None: + return result + + # Some currently hardcoded values: + mac = '"52:54:00:4F:D8:65"' # Hardcode for now + host = 'http://sat-perf-04.idm.lab.bos.redhat.com' # Hardcode for now + auth = ('admin', 'changeme') + + # Get the errata here + host = host.strip('/') # Get rid of any trailing slash in the host url + + # Pick up the UUID from the MAC address This makes no sense, as we + # need both MAC address and the interface, and we don't have the + # interface, so we need to make multiple slow searches. If the + # Satellite UUID isn't the same as this one, and it probably isn't we + # need to store a mapping somewhere. + url = '{host}/katello/api/v2/systems'.format(host=host) + for interface in ['eth0', 'eth1', 'en0', 'en1']: + + q = 'facts.net.interface.{iface}.mac_address:{mac}'.format( + iface=interface, mac=mac) + r = requests.get(url, params={'search': q}, auth=auth) + results = r.json()['results'] + if results: + break + else: + # No node found + result['errata'] = None + return result + + uuid = results[0]['uuid'] + errata_url = '{host}/katello/api/v2/systems/{id}/errata' + r = requests.get(errata_url.format(host=host, id=uuid), auth=auth) + errata = r.json()['results'] + if not errata: + result['errata'] = None + else: + data = [ErrataItem(x['title'], x['type'], x['id'], x['issued']) + for x in errata] + result['errata'] = ErrataTable(request, data=data) + return result + + +class NodeDetailTabs(tabs.TabGroup): + slug = "node_details" + tabs = (DetailOverviewTab,) diff --git a/tuskar_sat_ui/nodes/views.py b/tuskar_sat_ui/nodes/views.py index de9a45b..df975a2 100644 --- a/tuskar_sat_ui/nodes/views.py +++ b/tuskar_sat_ui/nodes/views.py @@ -13,7 +13,8 @@ # under the License. from tuskar_ui.infrastructure.nodes import views +from tuskar_sat_ui.nodes import tabs class DetailView(views.DetailView): - template_name = 'infrastructure/nodes/sat_detail.html' + tab_group_class = tabs.NodeDetailTabs diff --git a/tuskar_sat_ui/static/infrastructure/js/angular/horizon.base64.js b/tuskar_sat_ui/static/infrastructure/js/angular/horizon.base64.js deleted file mode 100644 index 75036e0..0000000 --- a/tuskar_sat_ui/static/infrastructure/js/angular/horizon.base64.js +++ /dev/null @@ -1,84 +0,0 @@ -angular.module('hz').factory('Base64', function() { - var keyStr = 'ABCDEFGHIJKLMNOP' + - 'QRSTUVWXYZabcdef' + - 'ghijklmnopqrstuv' + - 'wxyz0123456789+/' + - '='; - return { - encode: function (input) { - var output = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + - keyStr.charAt(enc1) + - keyStr.charAt(enc2) + - keyStr.charAt(enc3) + - keyStr.charAt(enc4); - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - } while (i < input.length); - - return output; - }, - - decode: function (input) { - var output = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - // remove all characters that are not A-Z, a-z, 0-9, +, /, or = - var base64test = /[^A-Za-z0-9\+\/\=]/g; - if (base64test.exec(input)) { - alert("There were invalid base64 characters in the input text.\n" + - "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + - "Expect errors in decoding."); - } - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - do { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - - } while (i < input.length); - - return output; - } - }; - }); diff --git a/tuskar_sat_ui/static/infrastructure/js/angular/horizon.node_errata.js b/tuskar_sat_ui/static/infrastructure/js/angular/horizon.node_errata.js deleted file mode 100644 index bcd2ad0..0000000 --- a/tuskar_sat_ui/static/infrastructure/js/angular/horizon.node_errata.js +++ /dev/null @@ -1,96 +0,0 @@ -angular.module('hz').factory - ('SatelliteErrata', ['$resource', 'Base64', - function ($resource, Base64) { - - var getAuthToken = function(username, password) { - var tokenize = username + ':' + password; - tokenize = Base64.encode(tokenize); - return "Basic " + tokenize; - }; - - var SatelliteErrata = $resource('https://sat-perf-05.idm.lab.bos.redhat.com/katello/api/v2/systems/:id/errata', {id: '@uuid'}, { - get: { - method: 'GET', - isArray: false, - headers: { 'Authorization': getAuthToken('admin', 'changeme') } - } - } - ); - - return SatelliteErrata; - - }]); - -angular.module('hz').directive({ - satelliteErrata: [ function () { - - return { - restrict: 'A', - // require: '^file', - transclude: true, - scope: { - uuid: '=' - }, - controller: ['$scope', 'SatelliteErrata', '$http', 'Base64', 'ngTableParams', '$filter', - function ($scope, SatelliteErrata, $http, Base64, ngTableParams, $filter) { - - var baseUrl = 'https://sat-perf-05.idm.lab.bos.redhat.com'; - - var defaultParams = function (data) { - var params = new ngTableParams({ - page: 1, // show first page - count: 10 // count per page - - }, { - total: data.length, // length of data - getData: function($defer, params) { - var filteredData = params.filter() ? - $filter('filter')(data, params.filter()) : - data; - var orderedData = params.sorting() ? - $filter('orderBy')(filteredData, params.orderBy()) : - data; - $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); - } - }); - - return params; - }; - - $scope.errataLink = function (errata) { - return baseUrl + '/content_hosts/' + $scope.uuid + '/errata/' + errata.errata_id; - }; - - var payload = SatelliteErrata.get({id: $scope.uuid}); - payload.$promise.then( - function() { - $scope.errata = payload.results - $scope.errataParams = defaultParams($scope.errata); - }); - - - }], - template: - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n'+ - '
\n' + - '{{e.title}}\n' + - '{{ e.type }}{{ e.errata_id }}{{ e.issued }}
\n', - link: function (scope, element, attrs, modelCtrl, transclude) { - scope.modelCtrl = modelCtrl; - scope.$transcludeFn = transclude; - } - }; - }] -}); - -angular.module('hz').controller({ - ErrataController: ['$scope', - function ($scope ) { - - }]}); diff --git a/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html b/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html new file mode 100644 index 0000000..e51042f --- /dev/null +++ b/tuskar_sat_ui/templates/infrastructure/nodes/_detail_overview_sat.html @@ -0,0 +1,17 @@ +{% extends "infrastructure/nodes/_detail_overview.html" %} +{% load i18n %} + +{% block additional_data %} + +{% if node.uuid %} +
+

{% trans "Errata" %}

+ {% if errata %} + {{ errata.render }} + {% else %} +

{% trans "No errata found" %}

+ {% endif %} +
+{% endif %} + +{% endblock %} diff --git a/tuskar_sat_ui/templates/infrastructure/nodes/sat_detail.html b/tuskar_sat_ui/templates/infrastructure/nodes/sat_detail.html deleted file mode 100644 index 71cfc53..0000000 --- a/tuskar_sat_ui/templates/infrastructure/nodes/sat_detail.html +++ /dev/null @@ -1,183 +0,0 @@ -{% extends 'infrastructure/base.html' %} -{% load i18n %} -{% block title %}{{ title }}{% endblock %} - -{% block page_header %} - {% include 'horizon/common/_page_header.html' with title=title %} -{% endblock page_header %} - -{% block js %} -{{ block.super }} - - -{% endblock %} - -{% block main %} -
-
-
- {% trans "Powered" %} {{ node.power_state|default:"—" }} -
-
- -
-

{% trans "Deployment" %}

-
-
{% trans "Deployment Role" %}
- {% if stack and role %} -
{{ role.name }}
- {% else %} -
- {% endif %} -
{% trans "Provisioning" %}
-
- {{ node.provisioning_status|default:"—" }} - {% if node.instance_uuid %} -
{{ node.instance.created }} - {% endif %} -
-
{% trans "Image" %}
-
{{ node.image_name|default:"—" }}
-
{% trans "Instance UUID" %}
-
{{ node.instance_uuid|default:"—" }}
-
-
- -
-

{% trans "Inventory" %}

-
-
{% trans "Node UUID" %}
-
{{ node.uuid|default:"—" }}
-
{% trans "Driver" %}
- -
{% trans "Network Cards" %}
- -
{% trans "Registered HW" %}
-
- {{ node.cpus|default:"—" }} {% trans "CPU" %}
- {{ node.memory_mb|default:"—" }} {% trans "RAM (MB)" %}
- {{ node.local_gb|default:"—" }} {% trans "HDD (GB)" %} -
-
-
- -
-

{% trans "Performance and Capacity" %}

- -{% if meter_conf %} -
-{% url 'horizon:infrastructure:nodes:performance' node.uuid as node_perf_url %} - -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- - - -
- {% for meter_label, url_part, y_max in meter_conf %} -
- {% include "infrastructure/_performance_chart.html" with label=meter_label y_max=y_max url=node_perf_url|add:"?"|add:url_part only %} -
- {% endfor %} - - {% else %} - {% trans 'Metering service is not enabled.' %} - {% endif %} -
-
- -{% if node.uuid %} -
-
-
-

{% trans "Errata" %}

-
-
-
-
-{% endif %} - -{% endblock %}